diff options
Diffstat (limited to 'api/direct_bt')
-rw-r--r-- | api/direct_bt/BTAdapter.hpp | 18 | ||||
-rw-r--r-- | api/direct_bt/BTAddress.hpp | 32 | ||||
-rw-r--r-- | api/direct_bt/BTDevice.hpp | 35 | ||||
-rw-r--r-- | api/direct_bt/HCIHandler.hpp | 27 | ||||
-rw-r--r-- | api/direct_bt/SMPKeyBin.hpp | 16 |
5 files changed, 102 insertions, 26 deletions
diff --git a/api/direct_bt/BTAdapter.hpp b/api/direct_bt/BTAdapter.hpp index 9fcfaa32..7570953d 100644 --- a/api/direct_bt/BTAdapter.hpp +++ b/api/direct_bt/BTAdapter.hpp @@ -349,7 +349,7 @@ namespace direct_bt { */ BDAddressAndType visibleAddressAndType; HCILEOwnAddressType visibleMACType; - MgmtIdentityResolvingKeyInfo privacyIRK; + MgmtIdentityResolvingKey privacyIRK; public: typedef jau::nsize_t size_type; @@ -434,7 +434,7 @@ namespace direct_bt { bool initialSetup() noexcept; bool enableListening(const bool enable) noexcept; - static BTDeviceRef findDevice(device_list_t & devices, const EUI48 & address, const BDAddressType addressType) noexcept; + static BTDeviceRef findDevice(HCIHandler& hci, device_list_t & devices, const EUI48 & address, const BDAddressType addressType) noexcept; static BTDeviceRef findDevice(device_list_t & devices, BTDevice const & device) noexcept; static BTDeviceRef findWeakDevice(weak_device_list_t & devices, const EUI48 & address, const BDAddressType addressType) noexcept; static BTDeviceRef findWeakDevice(weak_device_list_t & devices, BTDevice const & device) noexcept; @@ -474,6 +474,7 @@ namespace direct_bt { uint16_t latency, uint16_t supervision_timeout) noexcept; friend HCIStatusCode BTDevice::connectBREDR(const uint16_t pkt_type, const uint16_t clock_offset, const uint8_t role_switch) noexcept; friend void BTDevice::processL2CAPSetup(BTDeviceRef sthis); + friend bool BTDevice::updateIdentityAddress(BDAddressAndType const & identityAddress, bool sendEvent) noexcept; friend bool BTDevice::updatePairingState(const BTDeviceRef& sthis, const MgmtEvent& evt, const HCIStatusCode evtStatus, SMPPairingState claimed_state) noexcept; friend void BTDevice::hciSMPMsgCallback(const BTDeviceRef& sthis, const SMPPDUMsg& msg, const HCIACLData::l2cap_frame& source) noexcept; friend void BTDevice::processDeviceReady(BTDeviceRef sthis, const uint64_t timestamp); @@ -525,14 +526,17 @@ namespace direct_bt { void mgmtEvDeviceDiscoveringMgmt(const MgmtEvent& e) noexcept; void mgmtEvLocalNameChangedMgmt(const MgmtEvent& e) noexcept; void mgmtEvDeviceFoundHCI(const MgmtEvent& e) noexcept; + void mgmtEvPairDeviceCompleteMgmt(const MgmtEvent& e) noexcept; void mgmtEvNewLongTermKeyMgmt(const MgmtEvent& e) noexcept; void mgmtEvNewLinkKeyMgmt(const MgmtEvent& e) noexcept; void mgmtEvNewIdentityResolvingKeyMgmt(const MgmtEvent& e) noexcept; void mgmtEvHCIAnyHCI(const MgmtEvent& e) noexcept; + void mgmtEvMgmtAnyMgmt(const MgmtEvent& e) noexcept; void mgmtEvDeviceDiscoveringHCI(const MgmtEvent& e) noexcept; void mgmtEvDeviceConnectedHCI(const MgmtEvent& e) noexcept; + void mgmtEvDeviceConnectedMgmt(const MgmtEvent& e) noexcept; void mgmtEvConnectFailedHCI(const MgmtEvent& e) noexcept; void mgmtEvHCILERemoteUserFeaturesHCI(const MgmtEvent& e) noexcept; @@ -677,7 +681,7 @@ namespace direct_bt { BTMode getBTMode() const noexcept { return adapterInfo.getCurrentBTMode(); } /** - * Returns the adapter's public BDAddressAndType. + * Returns the adapter's public BDAddressAndType, i.e. BDAddressType::BDADDR_LE_PUBLIC. * <p> * The adapter's address as initially reported by the system is always its public address, i.e. BDAddressType::BDADDR_LE_PUBLIC. * </p> @@ -687,15 +691,16 @@ namespace direct_bt { BDAddressAndType const & getAddressAndType() const noexcept { return adapterInfo.addressAndType; } /** - * Returns the adapter's currently visible BDAddressAndType. + * Returns the adapter's currently visible BDAddressAndType, i.e. BDAddressType::BDADDR_LE_RANDOM or BDAddressType::BDADDR_LE_PUBLIC. * <p> * The adapter's address as initially reported by the system is always its public address, i.e. BDAddressType::BDADDR_LE_PUBLIC. * </p> * <p> - * The adapter's visible BDAddressAndType might be set to BDAddressType::BDADDR_LE_RANDOM before scanning / discovery mode (TODO). + * The adapter's visible BDAddressAndType might be set to BDAddressType::BDADDR_LE_RANDOM before scanning / discovery mode via setPrivacy(). * </p> - * @since 2.2.8 + * @since 3.2.8 * @see #getAddressAndType() + * @see #setPrivacy() */ BDAddressAndType const & getVisibleAddressAndType() const noexcept { return visibleAddressAndType; } @@ -753,6 +758,7 @@ namespace direct_bt { * @param enable toggle to enable or disable (default) * @return HCIStatusCode::SUCCESS or an error state on failure * @since 3.2.0 + * @see #getVisibleAddressAndType() */ HCIStatusCode setPrivacy(const bool enable) noexcept; diff --git a/api/direct_bt/BTAddress.hpp b/api/direct_bt/BTAddress.hpp index 493f8d6d..1e0a2466 100644 --- a/api/direct_bt/BTAddress.hpp +++ b/api/direct_bt/BTAddress.hpp @@ -218,6 +218,38 @@ namespace direct_bt { } /** + * Returns true if this address and type refers to a static public LE identity address, + * which does not require address resolution via an Identity Resolving Key (IRK).<br> + * Either ::BDAddressType::BDADDR_LE_PUBLIC or ::BDAddressType::BDADDR_LE_RANDOM of sub-type ::BLERandomAddressType::STATIC_PUBLIC. + */ + constexpr bool isIdentityLEAddress() const noexcept { + if( BDAddressType::BDADDR_LE_RANDOM == type ) { + return BLERandomAddressType::STATIC_PUBLIC == getBLERandomAddressType(); + } else { + return BDAddressType::BDADDR_LE_PUBLIC == type; + } + } + + /** + * Returns true if this address and type refers to a public static identity address, + * which does not require address resolution via an Identity Resolving Key (IRK).<br> + * This includes ::BDAddressType::BDADDR_LE_RANDOM of sub-type ::BLERandomAddressType::STATIC_PUBLIC + * <p> + * Returns false if this address is of type ::BDAddressType::BDADDR_LE_RANDOM, + * excluding sub-type ::BLERandomAddressType::STATIC_PUBLIC + * and not of type ::BDAddressType::BDADDR_LE_PUBLIC or ::BDAddressType::BDADDR_BREDR. + * </p> + */ + constexpr bool isIdentityAddress() const noexcept { + if( BDAddressType::BDADDR_LE_RANDOM == type ) { + return BLERandomAddressType::STATIC_PUBLIC == getBLERandomAddressType(); + } else { + return BDAddressType::BDADDR_LE_PUBLIC == type || + BDAddressType::BDADDR_BREDR == type; + } + } + + /** * Returns true if the BDAddressType is a BREDR address type. */ constexpr bool isBREDRAddress() const noexcept { return BDAddressType::BDADDR_BREDR == type; } diff --git a/api/direct_bt/BTDevice.hpp b/api/direct_bt/BTDevice.hpp index 6b0e814f..1437370f 100644 --- a/api/direct_bt/BTDevice.hpp +++ b/api/direct_bt/BTDevice.hpp @@ -168,6 +168,8 @@ namespace direct_bt { void clearData() noexcept; + bool updateIdentityAddress(BDAddressAndType const & identityAddress, bool sendEvent) noexcept; + bool updateVisibleAddress(BDAddressAndType const & randomPrivateAddress) noexcept; EIRDataType update(EInfoReport const & data) noexcept; EIRDataType update(GattGenericAccessSvc const &data, const uint64_t timestamp) noexcept; @@ -255,8 +257,10 @@ namespace direct_bt { typedef jau::snsize_t ssize_type; const uint64_t ts_creation; - /** Device's unique mac address and type tuple. */ - const BDAddressAndType addressAndType; // FIXME: Mutable for resolvable -> identity during pairing? + /** Either the remote devices' initially reported (resolvable) random address or its (static) public identity address. */ + BDAddressAndType visibleAddressAndType; + /** Device's unique mac address and type tuple, might be its initially reported (resolvable) random address until pairing. */ + BDAddressAndType addressAndType; /** Private ctor for private BTDevice::make_shared() intended for friends. */ BTDevice(const BTDevice::ctor_cookie& cc, BTAdapter & adapter, EInfoReport const & r); @@ -325,11 +329,27 @@ namespace direct_bt { uint64_t getLastUpdateAge(const uint64_t ts_now) const noexcept { return ts_now - ts_last_update; } /** - * Returns the unique device EUI48 address and BDAddressType type. - * @since 2.2.0 + * Returns the devices' unique EUI48 address and type tuple, might be its initially reported (resolvable) random address until pairing, + * i.e. BDAddressType::BDADDR_LE_RANDOM instead of BDAddressType::BDADDR_LE_PUBLIC. + * <p> + * After pairing or if the remote device uses a (static) public address, + * it is considered unique and BDAddressType::BDADDR_LE_PUBLIC. + * </p> + * @since 3.2.0 */ constexpr BDAddressAndType const & getAddressAndType() const noexcept { return addressAndType; } + /** + * Returns the devices' visible BDAddressAndType, i.e. BDAddressType::BDADDR_LE_RANDOM or BDAddressType::BDADDR_LE_PUBLIC + * <p> + * The devices' address as initially reported by the system might be a (resolvable) random address, + * i.e. BDAddressType::BDADDR_LE_RANDOM instead of BDAddressType::BDADDR_LE_PUBLIC. + * </p> + * @since 3.2.8 + * @see #getAddressAndType() + */ + BDAddressAndType const & getVisibleAddressAndType() const noexcept { return visibleAddressAndType; } + /** Return RSSI of device as recognized at discovery and connect. */ int8_t getRSSI() const noexcept { return rssi; } @@ -1241,8 +1261,11 @@ namespace direct_bt { size_type removeAllCharListener() noexcept; }; - inline bool operator==(const BTDevice& lhs, const BTDevice& rhs) noexcept - { return lhs.getAddressAndType() == rhs.getAddressAndType(); } + inline bool operator==(const BTDevice& lhs, const BTDevice& rhs) noexcept { + return lhs.getAddressAndType() == rhs.getAddressAndType() || + lhs.getVisibleAddressAndType() == rhs.getVisibleAddressAndType() // FIXME: Evaluate if OK w/o collisions + ; + } inline bool operator!=(const BTDevice& lhs, const BTDevice& rhs) noexcept { return !(lhs == rhs); } diff --git a/api/direct_bt/HCIHandler.hpp b/api/direct_bt/HCIHandler.hpp index 3ece4bca..8f329d52 100644 --- a/api/direct_bt/HCIHandler.hpp +++ b/api/direct_bt/HCIHandler.hpp @@ -189,31 +189,35 @@ namespace direct_bt { private: class HCIConnection { private: - BDAddressAndType addressAndType; // immutable + BDAddressAndType visibleAddressAndType; // immutable + BDAddressAndType addressAndType; // mutable uint16_t handle; // mutable public: - HCIConnection(BDAddressAndType addressAndType_, const uint16_t handle_) - : addressAndType(std::move(addressAndType_)), handle(handle_) {} + HCIConnection(const BDAddressAndType& addressAndType_, const uint16_t handle_) + : visibleAddressAndType(addressAndType_), addressAndType(addressAndType_), handle(handle_) {} HCIConnection(const HCIConnection &o) = default; HCIConnection(HCIConnection &&o) = default; HCIConnection& operator=(const HCIConnection &o) = default; HCIConnection& operator=(HCIConnection &&o) = default; + const BDAddressAndType & getVisibleAddressAndType() const { return visibleAddressAndType; } const BDAddressAndType & getAddressAndType() const { return addressAndType; } + void setResolvAddrAndType(const BDAddressAndType& val) { addressAndType = val; } + uint16_t getHandle() const { return handle; } void setHandle(uint16_t newHandle) { handle = newHandle; } bool equals(const BDAddressAndType & other) const - { return addressAndType == other; } + { return addressAndType == other || visibleAddressAndType == other; } bool operator==(const HCIConnection& rhs) const { if( this == &rhs ) { return true; } - return addressAndType == rhs.addressAndType; + return addressAndType == rhs.addressAndType || visibleAddressAndType == rhs.visibleAddressAndType; } bool operator!=(const HCIConnection& rhs) const @@ -224,8 +228,9 @@ namespace direct_bt { } std::string toString() const { + std::string resaddr_s = visibleAddressAndType != addressAndType ? ", visible "+visibleAddressAndType.toString() : ""; return "HCIConnection[handle "+jau::to_hexstring(handle)+ - ", address "+addressAndType.toString()+"]"; + ", address "+addressAndType.toString()+resaddr_s+"]"; } }; public: @@ -286,6 +291,16 @@ namespace direct_bt { /** Exclusive [le] connection command (status + pending completed) one at a time */ std::mutex mtx_connect_cmd; + HCIConnectionRef setResolvHCIConnectionAddr(jau::darray<HCIConnectionRef> &list, + const BDAddressAndType& visibleAddressAndType, const BDAddressAndType& addressAndType) noexcept; + + public: + void setResolvHCIConnectionAddr(const BDAddressAndType& visibleAddressAndType, const BDAddressAndType& addressAndType) noexcept { + setResolvHCIConnectionAddr(connectionList, visibleAddressAndType, addressAndType); + setResolvHCIConnectionAddr(disconnectCmdList, visibleAddressAndType, addressAndType); + } + + private: /** * Returns a newly added HCIConnectionRef tracker connection with given parameters, if not existing yet. * <p> diff --git a/api/direct_bt/SMPKeyBin.hpp b/api/direct_bt/SMPKeyBin.hpp index acf7d476..48ad8a47 100644 --- a/api/direct_bt/SMPKeyBin.hpp +++ b/api/direct_bt/SMPKeyBin.hpp @@ -290,10 +290,10 @@ class SMPKeyBin { constexpr BTSecurityLevel getSecLevel() const noexcept { return sec_level; } constexpr SMPIOCapability getIOCap() const noexcept { return io_cap; } - constexpr bool hasLTKInit() const noexcept { return ( SMPKeyType::ENC_KEY & keys_init ) != SMPKeyType::NONE; } - constexpr bool hasIRKInit() const noexcept { return ( SMPKeyType::ID_KEY & keys_init ) != SMPKeyType::NONE; } - constexpr bool hasCSRKInit() const noexcept { return ( SMPKeyType::SIGN_KEY & keys_init ) != SMPKeyType::NONE; } - constexpr bool hasLKInit() const noexcept { return ( SMPKeyType::LINK_KEY & keys_init ) != SMPKeyType::NONE; } + constexpr bool hasLTKInit() const noexcept { return is_set(keys_init, SMPKeyType::ENC_KEY); } + constexpr bool hasIRKInit() const noexcept { return is_set(keys_init, SMPKeyType::ID_KEY); } + constexpr bool hasCSRKInit() const noexcept { return is_set(keys_init, SMPKeyType::SIGN_KEY); } + constexpr bool hasLKInit() const noexcept { return is_set(keys_init, SMPKeyType::LINK_KEY); } constexpr const SMPLongTermKey& getLTKInit() const noexcept { return ltk_init; } constexpr const SMPIdentityResolvingKey& getIRKInit() const noexcept { return irk_init; } constexpr const SMPSignatureResolvingKey& getCSRKInit() const noexcept { return csrk_init; } @@ -319,10 +319,10 @@ class SMPKeyBin { size = calcSize(); } - constexpr bool hasLTKResp() const noexcept { return ( SMPKeyType::ENC_KEY & keys_resp ) != SMPKeyType::NONE; } - constexpr bool hasIRKResp() const noexcept { return ( SMPKeyType::ID_KEY & keys_resp ) != SMPKeyType::NONE; } - constexpr bool hasCSRKResp() const noexcept { return ( SMPKeyType::SIGN_KEY & keys_resp ) != SMPKeyType::NONE; } - constexpr bool hasLKResp() const noexcept { return ( SMPKeyType::LINK_KEY & keys_resp ) != SMPKeyType::NONE; } + constexpr bool hasLTKResp() const noexcept { return is_set(keys_resp, SMPKeyType::ENC_KEY); } + constexpr bool hasIRKResp() const noexcept { return is_set(keys_resp, SMPKeyType::ID_KEY); } + constexpr bool hasCSRKResp() const noexcept { return is_set(keys_resp, SMPKeyType::SIGN_KEY); } + constexpr bool hasLKResp() const noexcept { return is_set(keys_resp, SMPKeyType::LINK_KEY); } constexpr const SMPLongTermKey& getLTKResp() const noexcept { return ltk_resp; } constexpr const SMPIdentityResolvingKey& getIRKResp() const noexcept { return irk_resp; } constexpr const SMPSignatureResolvingKey& getCSRKResp() const noexcept { return csrk_resp; } |