diff options
author | Sven Gothel <[email protected]> | 2021-09-24 12:59:13 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2021-09-24 12:59:13 +0200 |
commit | 61bfb0757a1c337eaf86f9df8b0524bec1b7bc0f (patch) | |
tree | 55e81117467e342ba7c6ef7d7b6beb3a43b01655 /api | |
parent | 61108682ad95d12f66cc5ee6cca89a5bbf99c5fa (diff) |
HCIHandler/BTAdapter/BTDevice: Add le_set[_default]_phy(..) / set[Connected|Default]LE_PHY(..)
Note that the HCIHandler methods validate if LE_Features if host do support LE_2M.
le_set*_phy(): Missing LE_2M support causes command to fail early w/o issuing it.
le_read_phy(): Missing LE_2M support causes command to return LE_1M here.
+++
Also remove 'TODO' re scanning PHY, since we shall simply stick with LE_1M band for compatibility.
Connection itself may use the fast LE_2M or long range LE_CODED band.
Diffstat (limited to 'api')
-rw-r--r-- | api/direct_bt/BTAdapter.hpp | 20 | ||||
-rw-r--r-- | api/direct_bt/BTDevice.hpp | 53 | ||||
-rw-r--r-- | api/direct_bt/HCIHandler.hpp | 39 | ||||
-rw-r--r-- | api/direct_bt/HCITypes.hpp | 16 | ||||
-rw-r--r-- | api/direct_bt/MgmtTypes.hpp | 42 |
5 files changed, 162 insertions, 8 deletions
diff --git a/api/direct_bt/BTAdapter.hpp b/api/direct_bt/BTAdapter.hpp index aedf3b8e..4d4f951d 100644 --- a/api/direct_bt/BTAdapter.hpp +++ b/api/direct_bt/BTAdapter.hpp @@ -391,6 +391,7 @@ namespace direct_bt { bool mgmtEvHCIEncryptionChangedHCI(const MgmtEvent& e) noexcept; bool mgmtEvHCIEncryptionKeyRefreshCompleteHCI(const MgmtEvent& e) noexcept; bool mgmtEvHCILERemoteUserFeaturesHCI(const MgmtEvent& e) noexcept; + bool mgmtEvHCILEPhyUpdateCompleteHCI(const MgmtEvent& e) noexcept; bool mgmtEvDeviceDisconnectedHCI(const MgmtEvent& e) noexcept; @@ -643,6 +644,25 @@ namespace direct_bt { HCIStatusCode reset() noexcept; /** + * Sets default preference of LE_PHYs. + * + * BT Core Spec v5.2: Vol 4, Part E, 7.8.49 LE Set PHY command + * + * @param tryTx if true, host has preference for given Tx LE_PHYs + * @param tryRx if true, host has preference for given Rx LE_PHYs + * @param Tx transmitter LE_PHYs of preference if tryTx is true, otherwise ignored + * @param Rx receiver LE_PHYs of preference if tryRx is true, otherwise ignored + * @return + * @see BTDevice::getTxPhys() + * @see BTDevice::getRxPhys() + * @see BTDevice::getConnectedLE_PHY() + * @see BTDevice::setConnectedLE_PHY() + * @since 2.4.0 + */ + HCIStatusCode setDefaultLE_PHY(const bool tryTx, const bool tryRx, + const LE_PHYs Tx, const LE_PHYs Rx) noexcept; + + /** * Returns a reference to the used singleton BTManager instance, used to create this adapter. */ BTManager& getManager() const noexcept { return mgmt; } diff --git a/api/direct_bt/BTDevice.hpp b/api/direct_bt/BTDevice.hpp index a2d2c877..066ce5be 100644 --- a/api/direct_bt/BTDevice.hpp +++ b/api/direct_bt/BTDevice.hpp @@ -87,6 +87,8 @@ namespace direct_bt { AppearanceCat appearance = AppearanceCat::UNKNOWN; jau::relaxed_atomic_uint16 hciConnHandle; jau::ordered_atomic<LE_Features, std::memory_order_relaxed> le_features; + jau::ordered_atomic<LE_PHYs, std::memory_order_relaxed> le_phy_tx; + jau::ordered_atomic<LE_PHYs, std::memory_order_relaxed> le_phy_rx; std::shared_ptr<ManufactureSpecificData> advMSD = nullptr; jau::darray<std::shared_ptr<const jau::uuid_t>> advServices; #if SMP_SUPPORTED_BY_OS @@ -159,6 +161,7 @@ namespace direct_bt { void notifyDisconnected() noexcept; void notifyConnected(std::shared_ptr<BTDevice> sthis, const uint16_t handle, const SMPIOCapability io_cap) noexcept; void notifyLEFeatures(std::shared_ptr<BTDevice> sthis, const LE_Features features) noexcept; + void notifyLEPhyUpdateComplete(const LE_PHYs Tx, const LE_PHYs Rx) noexcept; /** * Setup L2CAP channel connection to device incl. optional security encryption level off-thread. @@ -496,11 +499,61 @@ namespace direct_bt { * @param resTx reference for the resulting transmitter LE_PHYs bit * @param resRx reference for the resulting receiver LE_PHYs bit * @return HCIStatusCode + * @see getTxPhys() + * @see getRxPhys() + * @see getConnectedLE_PHY() + * @see setConnectedLE_PHY() + * @see BTAdapter::setDefaultLE_PHY() * @since 2.4.0 */ HCIStatusCode getConnectedLE_PHY(LE_PHYs& resTx, LE_PHYs& resRx) noexcept; /** + * Return the Tx LE_PHYs as notified via HCIMetaEventType::LE_PHY_UPDATE_COMPLETE + * or retrieved via getConnectedLE_PHY() + * @see getTxPhys() + * @see getRxPhys() + * @see getConnectedLE_PHY() + * @see setConnectedLE_PHY() + * @see BTAdapter::setDefaultLE_PHY() + * @since 2.4.0 + */ + LE_PHYs getTxPhys() const noexcept { return le_phy_tx; } + + /** + * Return the Rx LE_PHYs as notified via HCIMetaEventType::LE_PHY_UPDATE_COMPLETE + * or retrieved via getConnectedLE_PHY() + * @see getTxPhys() + * @see getRxPhys() + * @see getConnectedLE_PHY() + * @see setConnectedLE_PHY() + * @see BTAdapter::setDefaultLE_PHY() + * @since 2.4.0 + */ + LE_PHYs getRxPhys() const noexcept { return le_phy_rx; } + + /** + * Sets preference of used LE_PHYs for the given connection. + * + * - BT Core Spec v5.2: Vol 4, Part E, 7.8.49 LE Set PHY command + * - BT Core Spec v5.2: Vol 4, Part E, 7.7.65.12 LE PHY Update Complete event + * + * @param tryTx if true, host has preference for given Tx LE_PHYs + * @param tryRx if true, host has preference for given Rx LE_PHYs + * @param Tx transmitter LE_PHYs of preference if tryTx is true, otherwise ignored + * @param Rx receiver LE_PHYs of preference if tryRx is true, otherwise ignored + * @return + * @see getTxPhys() + * @see getRxPhys() + * @see getConnectedLE_PHY() + * @see setConnectedLE_PHY() + * @see BTAdapter::setDefaultLE_PHY() + * @since 2.4.0 + */ + HCIStatusCode setConnectedLE_PHY(const bool tryTx, const bool tryRx, + const LE_PHYs Tx, const LE_PHYs Rx) noexcept; + + /** * Disconnect the LE or BREDR peer's GATT and HCI connection. * <p> * BT Core Spec v5.2: Vol 4, Part E HCI: 7.1.6 Disconnect command diff --git a/api/direct_bt/HCIHandler.hpp b/api/direct_bt/HCIHandler.hpp index daec62e5..9341270a 100644 --- a/api/direct_bt/HCIHandler.hpp +++ b/api/direct_bt/HCIHandler.hpp @@ -682,6 +682,10 @@ namespace direct_bt { * <pre> * BT Core Spec v5.2: Vol 4, Part E, 7.8.47 LE Read PHY command * </pre> + * + * Controller shall send a pending HCIMetaEventType::LE_PHY_UPDATE_COMPLETE event with SUCCESS + * after issuing this command in all cases (change or unchanged PHYs). + * * @param conn_handle * @param addressAndType * @param resTx reference for the resulting transmitter LE_PHYs bit @@ -692,6 +696,41 @@ namespace direct_bt { HCIStatusCode le_read_phy(const uint16_t conn_handle, const BDAddressAndType& peerAddressAndType, LE_PHYs& resTx, LE_PHYs& resRx) noexcept; + + /** + * Sets default preference of used LE_PHYs for all subsequent LE connections. + * + * BT Core Spec v5.2: Vol 4, Part E, 7.8.48 LE Set Default PHY command + * + * @param tryTx if true, host has preference for given Tx LE_PHYs + * @param tryRx if true, host has preference for given Rx LE_PHYs + * @param Tx transmitter LE_PHYs of preference if tryTx is true, otherwise ignored + * @param Rx receiver LE_PHYs of preference if tryRx is true, otherwise ignored + * @return + * @since 2.4.0 + */ + HCIStatusCode le_set_default_phy(const bool tryTx, const bool tryRx, + const LE_PHYs Tx, const LE_PHYs Rx) noexcept; + + /** + * Sets preference of used LE_PHYs for the given connection. + * + * - BT Core Spec v5.2: Vol 4, Part E, 7.8.49 LE Set PHY command + * - BT Core Spec v5.2: Vol 4, Part E, 7.7.65.12 LE PHY Update Complete event + * + * @param conn_handle + * @param peerAddressAndType + * @param tryTx if true, host has preference for given Tx LE_PHYs + * @param tryRx if true, host has preference for given Rx LE_PHYs + * @param Tx transmitter LE_PHYs of preference if tryTx is true, otherwise ignored + * @param Rx receiver LE_PHYs of preference if tryRx is true, otherwise ignored + * @return + * @since 2.4.0 + */ + HCIStatusCode le_set_phy(const uint16_t conn_handle, const BDAddressAndType& peerAddressAndType, + const bool tryTx, const bool tryRx, + const LE_PHYs Tx, const LE_PHYs Rx) noexcept; + private: /** * Sets LE advertising parameters. diff --git a/api/direct_bt/HCITypes.hpp b/api/direct_bt/HCITypes.hpp index 1ff9fdcc..a2beb608 100644 --- a/api/direct_bt/HCITypes.hpp +++ b/api/direct_bt/HCITypes.hpp @@ -421,6 +421,7 @@ namespace direct_bt { LE_ENABLE_ENC = 0x2019, LE_READ_PHY = 0x2030, LE_SET_DEFAULT_PHY = 0x2031, + LE_SET_PHY = 0x2032, LE_SET_EXT_ADV_PARAMS = 0x2036, LE_SET_EXT_ADV_DATA = 0x2037, LE_SET_EXT_SCAN_RSP_DATA = 0x2038, @@ -467,13 +468,14 @@ namespace direct_bt { LE_ENABLE_ENC = 39, LE_READ_PHY = 40, LE_SET_DEFAULT_PHY = 41, - LE_SET_EXT_ADV_PARAMS = 42, - LE_SET_EXT_ADV_DATA = 43, - LE_SET_EXT_SCAN_RSP_DATA = 44, - LE_SET_EXT_ADV_ENABLE = 45, - LE_SET_EXT_SCAN_PARAMS = 46, - LE_SET_EXT_SCAN_ENABLE = 47, - LE_EXT_CREATE_CONN = 48 + LE_SET_PHY = 42, + LE_SET_EXT_ADV_PARAMS = 44, + LE_SET_EXT_ADV_DATA = 45, + LE_SET_EXT_SCAN_RSP_DATA = 46, + LE_SET_EXT_ADV_ENABLE = 47, + LE_SET_EXT_SCAN_PARAMS = 48, + LE_SET_EXT_SCAN_ENABLE = 49, + LE_EXT_CREATE_CONN = 50 // etc etc - incomplete }; constexpr uint8_t number(const HCIOpcodeBit rhs) noexcept { diff --git a/api/direct_bt/MgmtTypes.hpp b/api/direct_bt/MgmtTypes.hpp index 475791d2..e5b18ccf 100644 --- a/api/direct_bt/MgmtTypes.hpp +++ b/api/direct_bt/MgmtTypes.hpp @@ -1130,7 +1130,8 @@ namespace direct_bt { HCI_ENC_CHANGED = 0x002e, // direct_bt extension HCIHandler -> listener HCI_ENC_KEY_REFRESH_COMPLETE = 0x002f, // direct_bt extension HCIHandler -> listener HCI_LE_REMOTE_USR_FEATURES = 0x0030, // direct_bt extension HCIHandler -> listener - MGMT_EVENT_TYPE_COUNT = 0x0031 + HCI_LE_PHY_UPDATE_COMPLETE = 0x0031, // direct_bt extension HCIHandler -> listener + MGMT_EVENT_TYPE_COUNT = 0x0032 }; static constexpr uint16_t number(const Opcode rhs) noexcept { return static_cast<uint16_t>(rhs); @@ -2192,6 +2193,45 @@ namespace direct_bt { const uint8_t* getData() const noexcept override { return nullptr; } }; + /** + * mgmt_addr_info { EUI48, uint8_t type }, + * uint8_t Tx (8 Octets) + * uint8_t Rx (8 Octets) + * <p> + * This is a Direct_BT extension for HCI. + * </p> + */ + class MgmtEvtLEPhyUpdateComplete : public MgmtEvent + { + protected: + std::string baseString() const noexcept override { + return MgmtEvent::baseString()+", address="+getAddress().toString()+ + ", addressType "+to_string(getAddressType())+ + ", Tx="+direct_bt::to_string(getTx())+ + ", Rx="+direct_bt::to_string(getRx()); + } + + public: + MgmtEvtLEPhyUpdateComplete(const uint16_t dev_id, const BDAddressAndType& addressAndType, const LE_PHYs Tx, const LE_PHYs Rx) + : MgmtEvent(Opcode::HCI_LE_PHY_UPDATE_COMPLETE, dev_id, 6+1+2) + { + pdu.put_eui48_nc(MGMT_HEADER_SIZE, addressAndType.address); + pdu.put_uint8_nc(MGMT_HEADER_SIZE+6, direct_bt::number(addressAndType.type)); + pdu.put_uint8_nc(MGMT_HEADER_SIZE+6+1, direct_bt::number(Tx)); + pdu.put_uint8_nc(MGMT_HEADER_SIZE+6+2, direct_bt::number(Rx)); + } + + const EUI48& getAddress() const noexcept { return *reinterpret_cast<const EUI48 *>( pdu.get_ptr_nc(MGMT_HEADER_SIZE + 0) ); } // mgmt_addr_info + BDAddressType getAddressType() const noexcept { return static_cast<BDAddressType>(pdu.get_uint8_nc(MGMT_HEADER_SIZE+6)); } // mgmt_addr_info + + LE_PHYs getTx() const noexcept { return static_cast<LE_PHYs>(pdu.get_uint8_nc(MGMT_HEADER_SIZE+6+1)); } + LE_PHYs getRx() const noexcept { return static_cast<LE_PHYs>(pdu.get_uint8_nc(MGMT_HEADER_SIZE+6+2)); } + + jau::nsize_t getDataOffset() const noexcept override { return MGMT_HEADER_SIZE+6+1+2; } + jau::nsize_t getDataSize() const noexcept override { return 0; } + const uint8_t* getData() const noexcept override { return nullptr; } + }; + class MgmtEvtAdapterInfo : public MgmtEvtCmdComplete { protected: |