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) { return (tBLE_ADDR_TYPE)raw_type; }
from_ble_addr_type(tBLE_ADDR_TYPE type)65 inline uint8_t from_ble_addr_type(tBLE_ADDR_TYPE type) { return (uint8_t)type; }
66
67 /* BLE ADDR type ID bit */
68 #define BLE_ADDR_TYPE_ID_BIT 0x02
is_identity_type(const tBLE_ADDR_TYPE & type)69 inline bool is_identity_type(const tBLE_ADDR_TYPE& type) { return type & BLE_ADDR_TYPE_ID_BIT; }
70
71 #define STREAM_TO_BLE_ADDR_TYPE(type, p) \
72 { \
73 (type) = (tBLE_ADDR_TYPE)(*(p)); \
74 (p) += sizeof(tBLE_ADDR_TYPE); \
75 }
76 #define BLE_ADDR_TYPE_TO_STREAM(p, type) \
77 { *(p)++ = (tBLE_ADDR_TYPE)(type); }
78
79 #ifdef __cplusplus
80 constexpr uint8_t kBleAddressPublicDevice = BLE_ADDR_PUBLIC;
81 constexpr uint8_t kBleAddressRandomDevice = BLE_ADDR_RANDOM;
82 constexpr uint8_t kBleAddressIdentityBit = BLE_ADDR_TYPE_ID_BIT;
83 constexpr uint8_t kBleAddressPublicIdentity = kBleAddressIdentityBit | kBleAddressPublicDevice;
84 constexpr uint8_t kBleAddressRandomIdentity = kBleAddressIdentityBit | kBleAddressRandomDevice;
85
86 constexpr uint8_t kResolvableAddressMask = 0xc0;
87 constexpr uint8_t kResolvableAddressMsb = 0x40;
88
89 struct tBLE_BD_ADDR {
90 tBLE_ADDR_TYPE type;
91 RawAddress bda;
AddressEqualstBLE_BD_ADDR92 bool AddressEquals(const RawAddress& other) const { return other == bda; }
IsPublicDeviceTypetBLE_BD_ADDR93 bool IsPublicDeviceType() const { return type == kBleAddressPublicDevice; }
IsRandomDeviceTypetBLE_BD_ADDR94 bool IsRandomDeviceType() const { return type == kBleAddressRandomDevice; }
IsPublicIdentityTypetBLE_BD_ADDR95 bool IsPublicIdentityType() const { return type == kBleAddressPublicIdentity; }
lsRandomIdentityTypetBLE_BD_ADDR96 bool lsRandomIdentityType() const { return type == kBleAddressRandomIdentity; }
IsAddressResolvabletBLE_BD_ADDR97 bool IsAddressResolvable() const {
98 return ((bda.address)[0] & kResolvableAddressMask) == kResolvableAddressMsb;
99 }
IsPublictBLE_BD_ADDR100 bool IsPublic() const { return !(type & 0x01); }
IsResolvablePrivateAddresstBLE_BD_ADDR101 bool IsResolvablePrivateAddress() const { return IsAddressResolvable() && IsRandomDeviceType(); }
IsIdentityTypetBLE_BD_ADDR102 bool IsIdentityType() const { return IsPublicIdentityType() || lsRandomIdentityType(); }
TypeWithoutIdentityEqualstBLE_BD_ADDR103 bool TypeWithoutIdentityEquals(const tBLE_ADDR_TYPE other) const {
104 return (other & ~kBleAddressIdentityBit) == (type & ~kBleAddressIdentityBit);
105 }
106
ToStringtBLE_BD_ADDR107 std::string ToString() const {
108 return std::string(bda.ToString() + "[" + AddressTypeText(type) + "]");
109 }
110
ToStringForLoggingtBLE_BD_ADDR111 std::string ToStringForLogging() const {
112 return bda.ToStringForLogging() + "[" + AddressTypeText(type) + "]";
113 }
114
ToRedactedStringForLoggingtBLE_BD_ADDR115 std::string ToRedactedStringForLogging() const {
116 return bda.ToRedactedStringForLogging() + "[" + AddressTypeText(type) + "]";
117 }
118
119 bool operator==(const tBLE_BD_ADDR rhs) const { return rhs.type == type && rhs.bda == bda; }
120 bool operator!=(const tBLE_BD_ADDR rhs) const { return !(*this == rhs); }
121 };
122
123 template <>
124 struct std::hash<tBLE_BD_ADDR> {
125 std::size_t operator()(const tBLE_BD_ADDR& val) const {
126 static_assert(sizeof(uint64_t) >= (RawAddress::kLength + sizeof(tBLE_ADDR_TYPE)));
127 uint64_t int_addr = 0;
128 memcpy(reinterpret_cast<uint8_t*>(&int_addr), val.bda.address, RawAddress::kLength);
129 memcpy(reinterpret_cast<uint8_t*>(&int_addr) + RawAddress::kLength, (const void*)&val.type,
130 sizeof(tBLE_ADDR_TYPE));
131 return std::hash<uint64_t>{}(int_addr);
132 }
133 };
134
135 struct tAclLinkSpec {
136 tBLE_BD_ADDR addrt;
137 tBT_TRANSPORT transport;
138
139 bool operator==(const tAclLinkSpec rhs) const {
140 if (rhs.addrt != addrt) {
141 return false;
142 }
143
144 if (rhs.transport == BT_TRANSPORT_AUTO || transport == BT_TRANSPORT_AUTO) {
145 return true;
146 }
147
148 return rhs.transport == transport;
149 }
150
151 bool operator!=(const tAclLinkSpec rhs) const { return !(*this == rhs); }
152
153 bool StrictlyEquals(const tAclLinkSpec rhs) const {
154 return rhs.addrt == addrt && rhs.transport == transport;
155 }
156
157 std::string ToString() const {
158 return std::string(addrt.ToString() + "[" + bt_transport_text(transport) + "]");
159 }
160
161 std::string ToStringForLogging() const {
162 return addrt.ToStringForLogging() + "[" + bt_transport_text(transport) + "]";
163 }
164
165 std::string ToRedactedStringForLogging() const {
166 return addrt.ToRedactedStringForLogging() + "[" + bt_transport_text(transport) + "]";
167 }
168 };
169
170 #if __has_include(<bluetooth/log.h>)
171 #include <bluetooth/log.h>
172
173 namespace std {
174 template <>
175 struct formatter<tBLE_BD_ADDR> : formatter<std::string> {
176 template <class Context>
177 typename Context::iterator format(const tBLE_BD_ADDR& address, Context& ctx) const {
178 std::string repr = address.ToRedactedStringForLogging();
179 return std::formatter<std::string>::format(repr, ctx);
180 }
181 };
182 template <>
183 struct formatter<tAclLinkSpec> : formatter<std::string> {
184 template <class Context>
185 typename Context::iterator format(const tAclLinkSpec& address, Context& ctx) const {
186 std::string repr = address.ToRedactedStringForLogging();
187 return std::formatter<std::string>::format(repr, ctx);
188 }
189 };
190 } // namespace std
191
192 #endif // __has_include(<bluetooth/log.h>
193
194 #endif
195