1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cstdint>
20 #include <string>
21 
22 #include "types/bt_transport.h"
23 #include "types/raw_address.h"
24 
25 #define BLE_ADDR_PUBLIC 0x00
26 #define BLE_ADDR_RANDOM 0x01
27 #define BLE_ADDR_PUBLIC_ID 0x02
28 #define BLE_ADDR_RANDOM_ID 0x03
29 #define BLE_ADDR_ANONYMOUS 0xFF
30 typedef uint8_t tBLE_ADDR_TYPE;
31 #ifdef __cplusplus
AddressTypeText(tBLE_ADDR_TYPE type)32 inline std::string AddressTypeText(tBLE_ADDR_TYPE type) {
33   switch (type) {
34     case BLE_ADDR_PUBLIC:
35       return std::string("public");
36     case BLE_ADDR_RANDOM:
37       return std::string("random");
38     case BLE_ADDR_PUBLIC_ID:
39       return std::string("public identity");
40     case BLE_ADDR_RANDOM_ID:
41       return std::string("random identity");
42     case BLE_ADDR_ANONYMOUS:
43       return std::string("anonymous");
44     default:
45       return std::string("unknown");
46   }
47 }
48 #endif  // __cplusplus
49 
is_ble_addr_type_valid(uint8_t raw_type)50 inline bool is_ble_addr_type_valid(uint8_t raw_type) { return raw_type < 4; }
51 
is_ble_addr_type_known(tBLE_ADDR_TYPE type)52 inline bool is_ble_addr_type_known(tBLE_ADDR_TYPE type) {
53   switch (type) {
54     case BLE_ADDR_PUBLIC:
55     case BLE_ADDR_PUBLIC_ID:
56     case BLE_ADDR_RANDOM:
57     case BLE_ADDR_RANDOM_ID:
58       return true;
59     default:
60       return false;
61   }
62 }
63 
to_ble_addr_type(uint8_t raw_type)64 inline tBLE_ADDR_TYPE to_ble_addr_type(uint8_t raw_type) {
65   return (tBLE_ADDR_TYPE)raw_type;
66 }
from_ble_addr_type(tBLE_ADDR_TYPE type)67 inline uint8_t from_ble_addr_type(tBLE_ADDR_TYPE type) { return (uint8_t)type; }
68 
69 /* BLE ADDR type ID bit */
70 #define BLE_ADDR_TYPE_ID_BIT 0x02
is_identity_type(const tBLE_ADDR_TYPE & type)71 inline bool is_identity_type(const tBLE_ADDR_TYPE& type) {
72   return type & BLE_ADDR_TYPE_ID_BIT;
73 }
74 
75 #define STREAM_TO_BLE_ADDR_TYPE(type, p) \
76   {                                      \
77     (type) = (tBLE_ADDR_TYPE)(*(p));     \
78     (p) += sizeof(tBLE_ADDR_TYPE);       \
79   }
80 #define BLE_ADDR_TYPE_TO_STREAM(p, type) \
81   { *(p)++ = (tBLE_ADDR_TYPE)(type); }
82 
83 #ifdef __cplusplus
84 constexpr uint8_t kBleAddressPublicDevice = BLE_ADDR_PUBLIC;
85 constexpr uint8_t kBleAddressRandomDevice = BLE_ADDR_RANDOM;
86 constexpr uint8_t kBleAddressIdentityBit = BLE_ADDR_TYPE_ID_BIT;
87 constexpr uint8_t kBleAddressPublicIdentity =
88     kBleAddressIdentityBit | kBleAddressPublicDevice;
89 constexpr uint8_t kBleAddressRandomIdentity =
90     kBleAddressIdentityBit | kBleAddressRandomDevice;
91 
92 constexpr uint8_t kResolvableAddressMask = 0xc0;
93 constexpr uint8_t kResolvableAddressMsb = 0x40;
94 
95 struct tBLE_BD_ADDR {
96   tBLE_ADDR_TYPE type;
97   RawAddress bda;
AddressEqualstBLE_BD_ADDR98   bool AddressEquals(const RawAddress& other) const { return other == bda; }
IsPublicDeviceTypetBLE_BD_ADDR99   bool IsPublicDeviceType() const { return type == kBleAddressPublicDevice; }
IsRandomDeviceTypetBLE_BD_ADDR100   bool IsRandomDeviceType() const { return type == kBleAddressRandomDevice; }
IsPublicIdentityTypetBLE_BD_ADDR101   bool IsPublicIdentityType() const {
102     return type == kBleAddressPublicIdentity;
103   }
lsRandomIdentityTypetBLE_BD_ADDR104   bool lsRandomIdentityType() const {
105     return type == kBleAddressRandomIdentity;
106   }
IsAddressResolvabletBLE_BD_ADDR107   bool IsAddressResolvable() const {
108     return ((bda.address)[0] & kResolvableAddressMask) == kResolvableAddressMsb;
109   }
IsPublictBLE_BD_ADDR110   bool IsPublic() const { return !(type & 0x01); }
IsResolvablePrivateAddresstBLE_BD_ADDR111   bool IsResolvablePrivateAddress() const {
112     return IsAddressResolvable() && IsRandomDeviceType();
113   }
IsIdentityTypetBLE_BD_ADDR114   bool IsIdentityType() const {
115     return IsPublicIdentityType() || lsRandomIdentityType();
116   }
TypeWithoutIdentityEqualstBLE_BD_ADDR117   bool TypeWithoutIdentityEquals(const tBLE_ADDR_TYPE other) const {
118     return (other & ~kBleAddressIdentityBit) ==
119            (type & ~kBleAddressIdentityBit);
120   }
121 
ToStringtBLE_BD_ADDR122   std::string ToString() const {
123     return std::string(bda.ToString() + "[" + AddressTypeText(type) + "]");
124   }
125 
ToStringForLoggingtBLE_BD_ADDR126   std::string ToStringForLogging() const {
127     return bda.ToStringForLogging() + "[" + AddressTypeText(type) + "]";
128   }
129 
ToRedactedStringForLoggingtBLE_BD_ADDR130   std::string ToRedactedStringForLogging() const {
131     return bda.ToRedactedStringForLogging() + "[" + AddressTypeText(type) + "]";
132   }
133 
134   bool operator==(const tBLE_BD_ADDR rhs) const {
135     return rhs.type == type && rhs.bda == bda;
136   }
137   bool operator!=(const tBLE_BD_ADDR rhs) const { return !(*this == rhs); }
138 };
139 
140 template <>
141 struct std::hash<tBLE_BD_ADDR> {
142   std::size_t operator()(const tBLE_BD_ADDR& val) const {
143     static_assert(sizeof(uint64_t) >=
144                   (RawAddress::kLength + sizeof(tBLE_ADDR_TYPE)));
145     uint64_t int_addr = 0;
146     memcpy(reinterpret_cast<uint8_t*>(&int_addr), val.bda.address,
147            RawAddress::kLength);
148     memcpy(reinterpret_cast<uint8_t*>(&int_addr) + RawAddress::kLength,
149            (const void*)&val.type, sizeof(tBLE_ADDR_TYPE));
150     return std::hash<uint64_t>{}(int_addr);
151   }
152 };
153 
154 struct tAclLinkSpec {
155   tBLE_BD_ADDR addrt;
156   tBT_TRANSPORT transport;
157 
158   bool operator==(const tAclLinkSpec rhs) const {
159     if (rhs.addrt != addrt) return false;
160 
161     if (rhs.transport == BT_TRANSPORT_AUTO || transport == BT_TRANSPORT_AUTO) {
162       return true;
163     }
164 
165     return rhs.transport == transport;
166   }
167 
168   bool operator!=(const tAclLinkSpec rhs) const { return !(*this == rhs); }
169 
170   bool StrictlyEquals(const tAclLinkSpec rhs) const {
171     return rhs.addrt == addrt && rhs.transport == transport;
172   }
173 
174   std::string ToString() const {
175     return std::string(addrt.ToString() + "[" + bt_transport_text(transport) +
176                        "]");
177   }
178 
179   std::string ToStringForLogging() const {
180     return addrt.ToStringForLogging() + "[" + bt_transport_text(transport) +
181            "]";
182   }
183 
184   std::string ToRedactedStringForLogging() const {
185     return addrt.ToRedactedStringForLogging() + "[" +
186            bt_transport_text(transport) + "]";
187   }
188 };
189 
190 #if __has_include(<bluetooth/log.h>)
191 #include <bluetooth/log.h>
192 
193 namespace bluetooth::os {
194 bool should_log_be_redacted();
195 }  // namespace bluetooth::os
196 
197 namespace fmt {
198 template <>
199 struct formatter<tBLE_BD_ADDR> : formatter<std::string> {
200   template <class Context>
201   typename Context::iterator format(const tBLE_BD_ADDR& address,
202                                     Context& ctx) const {
203     std::string repr = bluetooth::os::should_log_be_redacted()
204                            ? address.ToRedactedStringForLogging()
205                            : address.ToStringForLogging();
206     return fmt::formatter<std::string>::format(repr, ctx);
207   }
208 };
209 template <>
210 struct formatter<tAclLinkSpec> : formatter<std::string> {
211   template <class Context>
212   typename Context::iterator format(const tAclLinkSpec& address,
213                                     Context& ctx) const {
214     std::string repr = bluetooth::os::should_log_be_redacted()
215                            ? address.ToRedactedStringForLogging()
216                            : address.ToStringForLogging();
217     return fmt::formatter<std::string>::format(repr, ctx);
218   }
219 };
220 }  // namespace fmt
221 
222 #endif  // __has_include(<bluetooth/log.h>
223 
224 #endif
225