diff --git a/src/NimBLEClient.cpp b/src/NimBLEClient.cpp index 7054f93e..05cc53ec 100644 --- a/src/NimBLEClient.cpp +++ b/src/NimBLEClient.cpp @@ -388,7 +388,49 @@ void NimBLEClient::setConfig(NimBLEClient::Config config) { */ void NimBLEClient::setConnectPhy(uint8_t mask) { m_phyMask = mask; -} +} // setConnectPhy + +/** + * @brief Request a change to the PHY used for this peer connection. + * @param [in] txPhyMask TX PHY. Can be mask of following: + * - BLE_GAP_LE_PHY_1M_MASK + * - BLE_GAP_LE_PHY_2M_MASK + * - BLE_GAP_LE_PHY_CODED_MASK + * - BLE_GAP_LE_PHY_ANY_MASK + * @param [in] rxPhyMask RX PHY. Can be mask of following: + * - BLE_GAP_LE_PHY_1M_MASK + * - BLE_GAP_LE_PHY_2M_MASK + * - BLE_GAP_LE_PHY_CODED_MASK + * - BLE_GAP_LE_PHY_ANY_MASK + * @param phyOptions Additional PHY options. Valid values are: + * - BLE_GAP_LE_PHY_CODED_ANY (default) + * - BLE_GAP_LE_PHY_CODED_S2 + * - BLE_GAP_LE_PHY_CODED_S8 + * @return True if successful. + */ +bool NimBLEClient::updatePhy(uint8_t txPhysMask, uint8_t rxPhysMask, uint16_t phyOptions) { + int rc = ble_gap_set_prefered_le_phy(m_connHandle, txPhysMask, rxPhysMask, phyOptions); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Failed to update phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + + return rc == 0; +} // updatePhy + +/** + * @brief Get the PHY used for this peer connection. + * @param [out] txPhy The TX PHY. + * @param [out] rxPhy The RX PHY. + * @return True if successful. + */ +bool NimBLEClient::getPhy(uint8_t* txPhy, uint8_t* rxPhy) { + int rc = ble_gap_read_le_phy(m_connHandle, txPhy, rxPhy); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Failed to read phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + + return rc == 0; +} // getPhy # endif /** diff --git a/src/NimBLEClient.h b/src/NimBLEClient.h index 430e3c6f..2ab3627f 100644 --- a/src/NimBLEClient.h +++ b/src/NimBLEClient.h @@ -93,7 +93,9 @@ class NimBLEClient { bool response = false); # if CONFIG_BT_NIMBLE_EXT_ADV - void setConnectPhy(uint8_t mask); + void setConnectPhy(uint8_t phyMask); + bool updatePhy(uint8_t txPhysMask, uint8_t rxPhysMask, uint16_t phyOptions = 0); + bool getPhy(uint8_t* txPhy, uint8_t* rxPhy); # endif struct Config { diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index 07c01ac1..c109cfcf 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -711,6 +711,31 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) { /* STACK FUNCTIONS */ /* -------------------------------------------------------------------------- */ +# if CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_) +/** + * @brief Set the preferred default phy to use for connections. + * @param [in] txPhyMask TX PHY. Can be mask of following: + * - BLE_GAP_LE_PHY_1M_MASK + * - BLE_GAP_LE_PHY_2M_MASK + * - BLE_GAP_LE_PHY_CODED_MASK + * - BLE_GAP_LE_PHY_ANY_MASK + * @param [in] rxPhyMask RX PHY. Can be mask of following: + * - BLE_GAP_LE_PHY_1M_MASK + * - BLE_GAP_LE_PHY_2M_MASK + * - BLE_GAP_LE_PHY_CODED_MASK + * - BLE_GAP_LE_PHY_ANY_MASK + * @return True if successful. + */ +bool NimBLEDevice::setDefaultPhy(uint8_t txPhyMask, uint8_t rxPhyMask) { + int rc = ble_gap_set_prefered_default_le_phy(txPhyMask, rxPhyMask); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Failed to set default phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + + return rc == 0; +} +# endif + /** * @brief Host reset, we pass the message so we don't make calls until re-synced. * @param [in] reason The reason code for the reset. diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h index 51d16c5c..96b2c678 100644 --- a/src/NimBLEDevice.h +++ b/src/NimBLEDevice.h @@ -136,6 +136,10 @@ class NimBLEDevice { static void onSync(void); static void host_task(void* param); +# if CONFIG_BT_NIMBLE_EXT_ADV + static bool setDefaultPhy(uint8_t txPhyMask, uint8_t rxPhyMask); +# endif + # if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) static NimBLEScan* getScan(); # endif diff --git a/src/NimBLEServer.cpp b/src/NimBLEServer.cpp index 9e9aab7a..57f74f3b 100644 --- a/src/NimBLEServer.cpp +++ b/src/NimBLEServer.cpp @@ -937,6 +937,50 @@ bool NimBLEServer::startAdvertising(uint8_t inst_id, bool NimBLEServer::stopAdvertising(uint8_t inst_id) { return getAdvertising()->stop(inst_id); } // stopAdvertising + +/** + * @brief Request an update to the PHY used for a peer connection. + * @param [in] connHandle the connection handle to the update the PHY for. + * @param [in] txPhyMask TX PHY. Can be mask of following: + * - BLE_GAP_LE_PHY_1M_MASK + * - BLE_GAP_LE_PHY_2M_MASK + * - BLE_GAP_LE_PHY_CODED_MASK + * - BLE_GAP_LE_PHY_ANY_MASK + * @param [in] rxPhyMask RX PHY. Can be mask of following: + * - BLE_GAP_LE_PHY_1M_MASK + * - BLE_GAP_LE_PHY_2M_MASK + * - BLE_GAP_LE_PHY_CODED_MASK + * - BLE_GAP_LE_PHY_ANY_MASK + * @param phyOptions Additional PHY options. Valid values are: + * - BLE_GAP_LE_PHY_CODED_ANY (default) + * - BLE_GAP_LE_PHY_CODED_S2 + * - BLE_GAP_LE_PHY_CODED_S8 + * @return True if successful. + */ +bool NimBLEServer::updatePhy(uint16_t connHandle, uint8_t txPhysMask, uint8_t rxPhysMask, uint16_t phyOptions) { + int rc = ble_gap_set_prefered_le_phy(connHandle, txPhysMask, rxPhysMask, phyOptions); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Failed to update phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + + return rc == 0; +} // updatePhy + +/** + * @brief Get the PHY used for a peer connection. + * @param [in] connHandle the connection handle to the get the PHY for. + * @param [out] txPhy The TX PHY. + * @param [out] rxPhy The RX PHY. + * @return True if successful. + */ +bool NimBLEServer::getPhy(uint16_t connHandle, uint8_t* txPhy, uint8_t* rxPhy) { + int rc = ble_gap_read_le_phy(connHandle, txPhy, rxPhy); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Failed to read phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + + return rc == 0; +} // getPhy #endif #if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_) diff --git a/src/NimBLEServer.h b/src/NimBLEServer.h index 86700e19..e04d3d13 100644 --- a/src/NimBLEServer.h +++ b/src/NimBLEServer.h @@ -55,6 +55,8 @@ class NimBLEServer { int duration = 0, int max_events = 0); bool stopAdvertising(uint8_t inst_id); + bool updatePhy(uint16_t connHandle, uint8_t txPhysMask, uint8_t rxPhysMask, uint16_t phyOptions); + bool getPhy(uint16_t connHandle, uint8_t* txPhy, uint8_t* rxPhy); #endif # if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_) NimBLEAdvertising* getAdvertising();