Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
BTAddress.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2021 Gothel Software e.K.
4 * Copyright (c) 2020 ZAFENA AB
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef BT_ADDRESS_HPP_
27#define BT_ADDRESS_HPP_
28
29#include <cstring>
30#include <string>
31#include <cstdint>
32#include <functional>
33
36#include <jau/eui48.hpp>
37
38using jau::EUI48;
39using jau::EUI48Sub;
40
41namespace direct_bt {
42
43 /** \addtogroup DBTUserAPI
44 *
45 * @{
46 */
47
48 /**
49 * BT Core Spec v5.2: Vol 3, Part C Generic Access Profile (GAP): 15.1.1.1 Public Bluetooth address
50 * <pre>
51 * 1) BT public address used as BD_ADDR for BR/EDR physical channel is defined in Vol 2, Part B 1.2
52 * - EUI-48 or MAC (6 octets)
53 *
54 * 2) BT public address used as BD_ADDR for the LE physical channel is defined in Vol 6, Part B 1.3
55 * BT Core Spec v5.2: Vol 3, Part C Generic Access Profile (GAP): 15.1.1.2 Random Bluetooth address
56 *
57 * 3) BT random address used as BD_ADDR on the LE physical channel is defined in Vol 3, Part C 10.8
58 * </pre>
59 */
60 enum class BDAddressType : uint8_t {
61 /** Bluetooth BREDR address */
62 BDADDR_BREDR = 0x00,
63 /** Bluetooth LE public address */
64 BDADDR_LE_PUBLIC = 0x01,
65 /** Bluetooth LE random address, see {@link BLERandomAddressType} */
66 BDADDR_LE_RANDOM = 0x02,
67 /** Undefined */
68 BDADDR_UNDEFINED = 0xff
69 };
70 constexpr BDAddressType to_BDAddressType(const uint8_t v) noexcept {
71 if( v <= 2 ) {
72 return static_cast<BDAddressType>(v);
73 }
75 }
76 constexpr uint8_t number(const BDAddressType rhs) noexcept {
77 return static_cast<uint8_t>(rhs);
78 }
79 std::string to_string(const BDAddressType type) noexcept;
80
81 /**
82 * BT Core Spec v5.2: Vol 6 LE, Part B Link Layer Specification: 1.3 Device Address
83 * <p>
84 * BT Core Spec v5.2: Vol 6 LE, Part B Link Layer Specification: 1.3.2 Random device Address
85 * </p>
86 * <p>
87 * Table 1.2, address bits [47:46]
88 * </p>
89 * <p>
90 * If {@link BDAddressType} is {@link BDAddressType::BDADDR_LE_RANDOM},
91 * its value shall be different than {@link BLERandomAddressType::UNDEFINED}.
92 * </p>
93 * <p>
94 * If {@link BDAddressType} is not {@link BDAddressType::BDADDR_LE_RANDOM},
95 * its value shall be {@link BLERandomAddressType::UNDEFINED}.
96 * </p>
97 */
98 enum class BLERandomAddressType : uint8_t {
99 /** Non-resolvable private random device address 0b00 */
100 UNRESOLVABLE_PRIVAT = 0x00,
101 /**
102 * Resolvable private random device address 0b01.
103 *
104 * Requires Local Identity Resolving Key (IRK) or the Peer Identity Resolving Key (IRK).
105 *
106 * EUI48: 24 bits hash = ag(IRK, prand), 24 bits prand.
107 */
108 RESOLVABLE_PRIVAT = 0x01,
109 /** Reserved for future use 0b10 */
110 RESERVED = 0x02,
111 /** Static public 'random' device address 0b11. Not changing between power-cycles. */
112 STATIC_PUBLIC = 0x03,
113 /** Undefined, e.g. address not of type {@link BDAddressType::BDADDR_LE_RANDOM} */
114 UNDEFINED = 0xff
115 };
116 constexpr uint8_t number(const BLERandomAddressType rhs) noexcept { return static_cast<uint8_t>(rhs); }
117 std::string to_string(const BLERandomAddressType type) noexcept;
118
119 /**
120 * HCI LE Address-Type is PUBLIC: 0x00, RANDOM: 0x01
121 * <p>
122 * BT Core Spec v5.2: Vol 4, Part E Host Controller Interface (HCI) Functionality:
123 * <pre>
124 * > 7.8.5: LE Set Advertising Parameters command
125 * -- Own_Address_Type: public: 0x00 (default), random: 0x01, resolvable-1: 0x02, resolvable-2: 0x03
126 * > 7.8.10: LE Set Scan Parameters command
127 * -- Own_Address_Type: public: 0x00 (default), random: 0x01, resolvable-1: 0x02, resolvable-2: 0x03
128 * > 7.8.12: LE Create Connection command
129 * -- Own_Address_Type: public: 0x00 (default), random: 0x01,
130 * Public Identity Address (resolvable-1, any not supporting LE_Set_Privacy_Mode command): 0x02,
131 * Random (static) Identity Address (resolvable-2, any not supporting LE_Set_Privacy_Mode command): 0x03
132 * </pre>
133 * </p>
134 */
135 enum class HCILEPeerAddressType : uint8_t {
136 /** Public Device Address */
137 PUBLIC = 0x00,
138 /** Random Device Address */
139 RANDOM = 0x01,
140 /** Public Resolved Identity Address */
141 PUBLIC_IDENTITY = 0x02,
142 /** Resolved Random (Static) Identity Address */
144 UNDEFINED = 0xff /**< HCIADDR_UNDEFINED */
145 };
146 constexpr uint8_t number(const HCILEPeerAddressType rhs) noexcept { return static_cast<uint8_t>(rhs); }
147 BDAddressType to_BDAddressType(const HCILEPeerAddressType hciPeerAddrType) noexcept;
148 std::string to_string(const HCILEPeerAddressType type) noexcept;
149
150 enum class HCILEOwnAddressType : uint8_t {
151 /** Public Device Address */
152 PUBLIC = 0x00,
153 /** Random Device Address */
154 RANDOM = 0x01,
155 /** Controller Resolved Private Address or Public Address */
157 /** Controller Resolved Private Address or Random Address */
159 UNDEFINED = 0xff
160 };
161 constexpr uint8_t number(const HCILEOwnAddressType rhs) noexcept { return static_cast<uint8_t>(rhs); }
162 BDAddressType to_BDAddressType(const HCILEOwnAddressType hciOwnAddrType) noexcept;
163 HCILEOwnAddressType to_HCILEOwnAddressType(const BDAddressType addrType, bool resolvable) noexcept;
164 std::string to_string(const HCILEOwnAddressType type) noexcept;
165
166
167 /**
168 * Unique Bluetooth EUI48 address and ::BDAddressType tuple.
169 * <p>
170 * Bluetooth EUI48 address itself is not unique as it requires the ::BDAddressType bits.<br>
171 * E.g. there could be two devices with the same EUI48 address, one using ::BDAddressType::BDADDR_LE_PUBLIC
172 * and one using ::BDAddressType::BDADDR_LE_RANDOM being a ::BLERandomAddressType::RESOLVABLE_PRIVAT.
173 * </p>
174 */
176 public:
177 /** Using EUI48::ANY_DEVICE and ::BDAddressType::BDADDR_BREDR to match any BREDR device. */
179
180 /**
181 * Using EUI48::ANY_DEVICE and ::BDAddressType::BDADDR_UNDEFINED to match any device.<br>
182 * This constant is suitable to {@link #matches(BDAddressAndType) any device.
183 */
185
188
189 private:
190 jau::relaxed_atomic_size_t hash = 0; // default 0, cache
191
192 public:
194 : address(address_), type(type_) {}
195
197 BDAddressAndType(const BDAddressAndType &o) noexcept : address(o.address), type(o.type) { }
199 address = o.address;
200 type = o.type;
201 }
202 constexpr BDAddressAndType& operator=(const BDAddressAndType &o) noexcept {
203 address = o.address;
204 type = o.type;
205 return *this;
206 }
208 address = o.address;
209 type = o.type;
210 return *this;
211 }
212
213 /**
214 * Returns true if the BDAddressType is a LE address type.
215 */
216 constexpr bool isLEAddress() const noexcept {
218 }
219
220 /**
221 * Returns true if this address and type refers to a static public LE identity address,
222 * which does not require address resolution via an Identity Resolving Key (IRK).<br>
223 * Either ::BDAddressType::BDADDR_LE_PUBLIC or ::BDAddressType::BDADDR_LE_RANDOM of sub-type ::BLERandomAddressType::STATIC_PUBLIC.
224 */
225 constexpr bool isIdentityLEAddress() const noexcept {
228 } else {
230 }
231 }
232
233 /**
234 * Returns true if this address and type refers to a public static identity address,
235 * which does not require address resolution via an Identity Resolving Key (IRK).<br>
236 * This includes ::BDAddressType::BDADDR_LE_RANDOM of sub-type ::BLERandomAddressType::STATIC_PUBLIC
237 * <p>
238 * Returns false if this address is of type ::BDAddressType::BDADDR_LE_RANDOM,
239 * excluding sub-type ::BLERandomAddressType::STATIC_PUBLIC
240 * and not of type ::BDAddressType::BDADDR_LE_PUBLIC or ::BDAddressType::BDADDR_BREDR.
241 * </p>
242 */
243 constexpr bool isIdentityAddress() const noexcept {
246 } else {
249 }
250 }
251
252 /**
253 * Returns true if the BDAddressType is a BREDR address type.
254 */
255 constexpr bool isBREDRAddress() const noexcept { return BDAddressType::BDADDR_BREDR == type; }
256
257 /**
258 * Returns the BLERandomAddressType.
259 * <p>
260 * If ::BDAddressType is ::BDAddressType::BDADDR_LE_RANDOM,
261 * method shall return a valid value other than ::BLERandomAddressType::UNDEFINED.
262 * </p>
263 * <p>
264 * If BDAddressType is not ::BDAddressType::BDADDR_LE_RANDOM,
265 * method shall return ::BLERandomAddressType::UNDEFINED.
266 * </p>
267 * @since 2.2.0
268 */
269 static BLERandomAddressType getBLERandomAddressType(const jau::EUI48& address, const BDAddressType addressType) noexcept;
270
271 /**
272 * Returns the BLERandomAddressType std::string representation.
273 * <p>
274 * If ::BDAddressType is ::BDAddressType::BDADDR_LE_RANDOM,
275 * method shall return the given prefix and a valid string value other than ::BLERandomAddressType::UNDEFINED.
276 * </p>
277 * <p>
278 * If BDAddressType is not ::BDAddressType::BDADDR_LE_RANDOM,
279 * method shall return an empty string.
280 * </p>
281 * @since 2.5.3
282 */
283 static std::string getBLERandomAddressTypeString(const jau::EUI48& address, const BDAddressType addressType, const std::string& prefix) noexcept;
284
285 /**
286 * Returns the BLERandomAddressType.
287 * <p>
288 * If type is ::BDAddressType::BDADDR_LE_RANDOM},
289 * method shall return a valid value other than ::BLERandomAddressType::UNDEFINED.
290 * </p>
291 * <p>
292 * If type is not ::BDAddressType::BDADDR_LE_RANDOM,
293 * method shall return ::BLERandomAddressType::UNDEFINED.
294 * </p>
295 * @since 2.0.0
296 */
299 }
300
301
302 /**
303 * Returns true if both devices match, i.e. equal address
304 * and equal type or at least one type is {@link BDAddressType#BDADDR_UNDEFINED}.
305 */
306 bool matches(const BDAddressAndType & o) const noexcept {
307 if(this == &o) {
308 return true;
309 }
310 return address == o.address &&
311 ( type == o.type ||
314 }
315
316 /**
317 * Implementation uses a lock-free volatile cache.
318 */
319 std::size_t hash_code() const noexcept {
320 std::size_t h = hash;
321 if( 0 == h ) {
322 // 31 * x == (x << 5) - x
323 h = 31 + address.hash_code();
324 h = ((h << 5) - h) + number(type);
325 const_cast<BDAddressAndType *>(this)->hash = h;
326 }
327 return h;
328 }
329
330 /**
331 * Method clears the cached hash value.
332 * @see #clear()
333 */
334 void clearHash() { hash = 0; }
335
336 /**
337 * Method clears the underlying byte array {@link #b} and cached hash value.
338 * @see #clearHash()
339 */
340 void clear() {
341 hash = 0;
342 address.clear();
344 }
345
346 std::string toString() const noexcept;
347 };
348 inline bool operator==(const BDAddressAndType& lhs, const BDAddressAndType& rhs) noexcept {
349 if( &lhs == &rhs ) {
350 return true;
351 }
352 return lhs.address == rhs.address &&
353 lhs.type == rhs.type;
354 }
355 inline bool operator!=(const BDAddressAndType& lhs, const BDAddressAndType& rhs) noexcept
356 { return !(lhs == rhs); }
357
358 inline std::string to_string(const BDAddressAndType& a) noexcept { return a.toString(); }
359
360 /**@}*/
361
362} // namespace direct_bt
363
364// injecting specialization of std::hash to namespace std of our types above
365namespace std
366{
367 /** \addtogroup DBTUserAPI
368 *
369 * @{
370 */
371
372 template<> struct hash<direct_bt::BDAddressAndType> {
373 std::size_t operator()(direct_bt::BDAddressAndType const& a) const noexcept {
374 return a.hash_code();
375 }
376 };
377
378 /**@}*/
379
380}
381
382#endif /* BT_ADDRESS_HPP_ */
Unique Bluetooth EUI48 address and BDAddressType tuple.
Definition: BTAddress.hpp:175
bool matches(const BDAddressAndType &o) const noexcept
Returns true if both devices match, i.e.
Definition: BTAddress.hpp:306
constexpr bool isLEAddress() const noexcept
Returns true if the BDAddressType is a LE address type.
Definition: BTAddress.hpp:216
BLERandomAddressType getBLERandomAddressType() const noexcept
Returns the BLERandomAddressType.
Definition: BTAddress.hpp:297
constexpr bool isIdentityAddress() const noexcept
Returns true if this address and type refers to a public static identity address, which does not requ...
Definition: BTAddress.hpp:243
void clear()
Method clears the underlying byte array b and cached hash value.
Definition: BTAddress.hpp:340
constexpr BDAddressAndType() noexcept
Definition: BTAddress.hpp:196
constexpr bool isIdentityLEAddress() const noexcept
Returns true if this address and type refers to a static public LE identity address,...
Definition: BTAddress.hpp:225
constexpr BDAddressAndType & operator=(const BDAddressAndType &o) noexcept
Definition: BTAddress.hpp:202
std::size_t hash_code() const noexcept
Implementation uses a lock-free volatile cache.
Definition: BTAddress.hpp:319
static std::string getBLERandomAddressTypeString(const jau::EUI48 &address, const BDAddressType addressType, const std::string &prefix) noexcept
Returns the BLERandomAddressType std::string representation.
Definition: BTTypes0.cpp:176
static const BDAddressAndType ANY_BREDR_DEVICE
Using EUI48::ANY_DEVICE and BDAddressType::BDADDR_BREDR to match any BREDR device.
Definition: BTAddress.hpp:178
constexpr bool isBREDRAddress() const noexcept
Returns true if the BDAddressType is a BREDR address type.
Definition: BTAddress.hpp:255
BDAddressAndType(const jau::EUI48 &address_, BDAddressType type_)
Definition: BTAddress.hpp:193
void clearHash()
Method clears the cached hash value.
Definition: BTAddress.hpp:334
static const BDAddressAndType ANY_DEVICE
Using EUI48::ANY_DEVICE and BDAddressType::BDADDR_UNDEFINED to match any device.
Definition: BTAddress.hpp:184
BDAddressAndType(const BDAddressAndType &o) noexcept
Definition: BTAddress.hpp:197
BDAddressAndType(BDAddressAndType &&o) noexcept
Definition: BTAddress.hpp:198
BDAddressAndType & operator=(BDAddressAndType &&o) noexcept
Definition: BTAddress.hpp:207
std::string toString() const noexcept
Definition: BTTypes0.cpp:186
BLERandomAddressType
BT Core Spec v5.2: Vol 6 LE, Part B Link Layer Specification: 1.3 Device Address.
Definition: BTAddress.hpp:98
HCILEOwnAddressType to_HCILEOwnAddressType(const BDAddressType addrType, bool resolvable) noexcept
Definition: BTTypes0.cpp:99
std::string to_string(const DiscoveryPolicy v) noexcept
Definition: BTAdapter.cpp:58
HCILEPeerAddressType
HCI LE Address-Type is PUBLIC: 0x00, RANDOM: 0x01.
Definition: BTAddress.hpp:135
BDAddressType
BT Core Spec v5.2: Vol 3, Part C Generic Access Profile (GAP): 15.1.1.1 Public Bluetooth address.
Definition: BTAddress.hpp:60
bool operator!=(const BTAdapter &lhs, const BTAdapter &rhs) noexcept
Definition: BTAdapter.hpp:1351
constexpr BDAddressType to_BDAddressType(const uint8_t v) noexcept
Definition: BTAddress.hpp:70
constexpr uint8_t number(const DiscoveryPolicy rhs) noexcept
Definition: BTAdapter.hpp:100
@ RESOLVABLE_PRIVAT
Resolvable private random device address 0b01.
@ RESERVED
Reserved for future use 0b10.
@ UNRESOLVABLE_PRIVAT
Non-resolvable private random device address 0b00.
@ STATIC_PUBLIC
Static public 'random' device address 0b11.
@ RANDOM
Random Device Address.
@ PUBLIC_IDENTITY
Public Resolved Identity Address.
@ RANDOM_STATIC_IDENTITY
Resolved Random (Static) Identity Address.
@ PUBLIC
Public Device Address.
@ BDADDR_BREDR
Bluetooth BREDR address.
@ BDADDR_LE_RANDOM
Bluetooth LE random address, see BLERandomAddressType.
@ BDADDR_LE_PUBLIC
Bluetooth LE public address.
@ BDADDR_UNDEFINED
Undefined.
@ RESOLVABLE_OR_RANDOM
Controller Resolved Private Address or Random Address.
@ RESOLVABLE_OR_PUBLIC
Controller Resolved Private Address or Public Address.
STL namespace.
A 48 bit EUI-48 sub-identifier, see EUI48.
Definition: eui48.hpp:51
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...
Definition: eui48.hpp:324
constexpr std::size_t hash_code() const noexcept
Definition: eui48.hpp:324
void clear()
Definition: eui48.hpp:324
std::size_t operator()(direct_bt::BDAddressAndType const &a) const noexcept
Definition: BTAddress.hpp:373