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