aboutsummaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2021-09-24 12:59:13 +0200
committerSven Gothel <[email protected]>2021-09-24 12:59:13 +0200
commit61bfb0757a1c337eaf86f9df8b0524bec1b7bc0f (patch)
tree55e81117467e342ba7c6ef7d7b6beb3a43b01655 /api
parent61108682ad95d12f66cc5ee6cca89a5bbf99c5fa (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.hpp20
-rw-r--r--api/direct_bt/BTDevice.hpp53
-rw-r--r--api/direct_bt/HCIHandler.hpp39
-rw-r--r--api/direct_bt/HCITypes.hpp16
-rw-r--r--api/direct_bt/MgmtTypes.hpp42
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: