Skip to content

Commit c4c9f79

Browse files
committed
Add methods to set/get connection PHY's.
* Added `NimBLEDevice::setDefaultPhy` which will set the default preferred PHY for all connections. * Added `NimBLEClient::updatePhy` to request a PHY change with a peer. * Added `NimBLEClient::getPhy` to read the current connection PHY setting. * Added `NimBLEServer::updatePhy` to request a PHY change with a peer. * Added `NimBLEServer::getPhy` to read the PHY of a peer connection. * Added callbacks: * - `NimBLEClientCallbacks::onPhyUpdate` * - `NimBLEServerCallbacks::onPhyUpdate` Which are called when the PHY update is complete.
1 parent 3cb9adb commit c4c9f79

File tree

6 files changed

+199
-10
lines changed

6 files changed

+199
-10
lines changed

src/NimBLEClient.cpp

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,49 @@ void NimBLEClient::setConfig(NimBLEClient::Config config) {
388388
*/
389389
void NimBLEClient::setConnectPhy(uint8_t mask) {
390390
m_phyMask = mask;
391-
}
391+
} // setConnectPhy
392+
393+
/**
394+
* @brief Request a change to the PHY used for this peer connection.
395+
* @param [in] txPhyMask TX PHY. Can be mask of following:
396+
* - BLE_GAP_LE_PHY_1M_MASK
397+
* - BLE_GAP_LE_PHY_2M_MASK
398+
* - BLE_GAP_LE_PHY_CODED_MASK
399+
* - BLE_GAP_LE_PHY_ANY_MASK
400+
* @param [in] rxPhyMask RX PHY. Can be mask of following:
401+
* - BLE_GAP_LE_PHY_1M_MASK
402+
* - BLE_GAP_LE_PHY_2M_MASK
403+
* - BLE_GAP_LE_PHY_CODED_MASK
404+
* - BLE_GAP_LE_PHY_ANY_MASK
405+
* @param phyOptions Additional PHY options. Valid values are:
406+
* - BLE_GAP_LE_PHY_CODED_ANY (default)
407+
* - BLE_GAP_LE_PHY_CODED_S2
408+
* - BLE_GAP_LE_PHY_CODED_S8
409+
* @return True if successful.
410+
*/
411+
bool NimBLEClient::updatePhy(uint8_t txPhyMask, uint8_t rxPhyMask, uint16_t phyOptions) {
412+
int rc = ble_gap_set_prefered_le_phy(m_connHandle, txPhyMask, rxPhyMask, phyOptions);
413+
if (rc != 0) {
414+
NIMBLE_LOGE(LOG_TAG, "Failed to update phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
415+
}
416+
417+
return rc == 0;
418+
} // updatePhy
419+
420+
/**
421+
* @brief Get the PHY used for this peer connection.
422+
* @param [out] txPhy The TX PHY.
423+
* @param [out] rxPhy The RX PHY.
424+
* @return True if successful.
425+
*/
426+
bool NimBLEClient::getPhy(uint8_t* txPhy, uint8_t* rxPhy) {
427+
int rc = ble_gap_read_le_phy(m_connHandle, txPhy, rxPhy);
428+
if (rc != 0) {
429+
NIMBLE_LOGE(LOG_TAG, "Failed to read phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
430+
}
431+
432+
return rc == 0;
433+
} // getPhy
392434
# endif
393435

394436
/**
@@ -1129,6 +1171,19 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
11291171
break;
11301172
} // BLE_GAP_EVENT_IDENTITY_RESOLVED
11311173

1174+
# if CONFIG_BT_NIMBLE_EXT_ADV
1175+
case BLE_GAP_EVENT_PHY_UPDATE_COMPLETE: {
1176+
NimBLEConnInfo peerInfo;
1177+
rc = ble_gap_conn_find(event->phy_updated.conn_handle, &peerInfo.m_desc);
1178+
if (rc != 0) {
1179+
return BLE_ATT_ERR_INVALID_HANDLE;
1180+
}
1181+
1182+
pClient->m_pClientCallbacks->onPhyUpdate(pClient, event->phy_updated.tx_phy, event->phy_updated.rx_phy);
1183+
return 0;
1184+
} // BLE_GAP_EVENT_PHY_UPDATE_COMPLETE
1185+
# endif
1186+
11321187
case BLE_GAP_EVENT_MTU: {
11331188
if (pClient->m_connHandle != event->mtu.conn_handle) {
11341189
return 0;
@@ -1224,30 +1279,31 @@ std::string NimBLEClient::toString() const {
12241279
} // toString
12251280

12261281
static const char* CB_TAG = "NimBLEClientCallbacks";
1282+
12271283
/**
12281284
* @brief Get the last error code reported by the NimBLE host
12291285
* @return int, the NimBLE error code.
12301286
*/
1231-
int NimBLEClient::getLastError() const {
1287+
int NimBLEClient::getLastError() const {
12321288
return m_lastErr;
12331289
} // getLastError
12341290

12351291
void NimBLEClientCallbacks::onConnect(NimBLEClient* pClient) {
12361292
NIMBLE_LOGD(CB_TAG, "onConnect: default");
1237-
}
1293+
} // onConnect
12381294

12391295
void NimBLEClientCallbacks::onConnectFail(NimBLEClient* pClient, int reason) {
12401296
NIMBLE_LOGD(CB_TAG, "onConnectFail: default, reason: %d", reason);
1241-
}
1297+
} // onConnectFail
12421298

12431299
void NimBLEClientCallbacks::onDisconnect(NimBLEClient* pClient, int reason) {
12441300
NIMBLE_LOGD(CB_TAG, "onDisconnect: default, reason: %d", reason);
1245-
}
1301+
} // onDisconnect
12461302

12471303
bool NimBLEClientCallbacks::onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) {
12481304
NIMBLE_LOGD(CB_TAG, "onConnParamsUpdateRequest: default");
12491305
return true;
1250-
}
1306+
} // onConnParamsUpdateRequest
12511307

12521308
void NimBLEClientCallbacks::onPassKeyEntry(NimBLEConnInfo& connInfo) {
12531309
NIMBLE_LOGD(CB_TAG, "onPassKeyEntry: default: 123456");
@@ -1256,7 +1312,7 @@ void NimBLEClientCallbacks::onPassKeyEntry(NimBLEConnInfo& connInfo) {
12561312

12571313
void NimBLEClientCallbacks::onAuthenticationComplete(NimBLEConnInfo& connInfo) {
12581314
NIMBLE_LOGD(CB_TAG, "onAuthenticationComplete: default");
1259-
}
1315+
} // onAuthenticationComplete
12601316

12611317
void NimBLEClientCallbacks::onIdentity(NimBLEConnInfo& connInfo) {
12621318
NIMBLE_LOGD(CB_TAG, "onIdentity: default");
@@ -1265,10 +1321,16 @@ void NimBLEClientCallbacks::onIdentity(NimBLEConnInfo& connInfo) {
12651321
void NimBLEClientCallbacks::onConfirmPasskey(NimBLEConnInfo& connInfo, uint32_t pin) {
12661322
NIMBLE_LOGD(CB_TAG, "onConfirmPasskey: default: true");
12671323
NimBLEDevice::injectConfirmPasskey(connInfo, true);
1268-
}
1324+
} // onConfirmPasskey
12691325

12701326
void NimBLEClientCallbacks::onMTUChange(NimBLEClient* pClient, uint16_t mtu) {
12711327
NIMBLE_LOGD(CB_TAG, "onMTUChange: default");
1272-
}
1328+
} // onMTUChange
1329+
1330+
# if CONFIG_BT_NIMBLE_EXT_ADV
1331+
void NimBLEClientCallbacks::onPhyUpdate(NimBLEClient* pClient, uint8_t txPhy, uint8_t rxPhy) {
1332+
NIMBLE_LOGD(CB_TAG, "onPhyUpdate: default, txPhy: %d, rxPhy: %d", txPhy, rxPhy);
1333+
} // onPhyUpdate
1334+
# endif
12731335

12741336
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */

src/NimBLEClient.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ class NimBLEClient {
9393
bool response = false);
9494

9595
# if CONFIG_BT_NIMBLE_EXT_ADV
96-
void setConnectPhy(uint8_t mask);
96+
void setConnectPhy(uint8_t phyMask);
97+
bool updatePhy(uint8_t txPhysMask, uint8_t rxPhysMask, uint16_t phyOptions = 0);
98+
bool getPhy(uint8_t* txPhy, uint8_t* rxPhy);
9799
# endif
98100

99101
struct Config {
@@ -207,6 +209,21 @@ class NimBLEClientCallbacks {
207209
* about the peer connection parameters.
208210
*/
209211
virtual void onMTUChange(NimBLEClient* pClient, uint16_t MTU);
212+
213+
# if CONFIG_BT_NIMBLE_EXT_ADV
214+
/**
215+
* @brief Called when the PHY update procedure is complete.
216+
* @param [in] pClient A pointer to the client whose PHY was updated.
217+
* about the peer connection parameters.
218+
* @param [in] txPhy The transmit PHY.
219+
* @param [in] rxPhy The receive PHY.
220+
* Possible values:
221+
* * BLE_GAP_LE_PHY_1M
222+
* * BLE_GAP_LE_PHY_2M
223+
* * BLE_GAP_LE_PHY_CODED
224+
*/
225+
virtual void onPhyUpdate(NimBLEClient* pClient, uint8_t txPhy, uint8_t rxPhy);
226+
# endif
210227
};
211228

212229
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_CENTRAL */

src/NimBLEDevice.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,31 @@ NimBLEAddress NimBLEDevice::getWhiteListAddress(size_t index) {
711711
/* STACK FUNCTIONS */
712712
/* -------------------------------------------------------------------------- */
713713

714+
# if CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_)
715+
/**
716+
* @brief Set the preferred default phy to use for connections.
717+
* @param [in] txPhyMask TX PHY. Can be mask of following:
718+
* - BLE_GAP_LE_PHY_1M_MASK
719+
* - BLE_GAP_LE_PHY_2M_MASK
720+
* - BLE_GAP_LE_PHY_CODED_MASK
721+
* - BLE_GAP_LE_PHY_ANY_MASK
722+
* @param [in] rxPhyMask RX PHY. Can be mask of following:
723+
* - BLE_GAP_LE_PHY_1M_MASK
724+
* - BLE_GAP_LE_PHY_2M_MASK
725+
* - BLE_GAP_LE_PHY_CODED_MASK
726+
* - BLE_GAP_LE_PHY_ANY_MASK
727+
* @return True if successful.
728+
*/
729+
bool NimBLEDevice::setDefaultPhy(uint8_t txPhyMask, uint8_t rxPhyMask) {
730+
int rc = ble_gap_set_prefered_default_le_phy(txPhyMask, rxPhyMask);
731+
if (rc != 0) {
732+
NIMBLE_LOGE(LOG_TAG, "Failed to set default phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
733+
}
734+
735+
return rc == 0;
736+
}
737+
# endif
738+
714739
/**
715740
* @brief Host reset, we pass the message so we don't make calls until re-synced.
716741
* @param [in] reason The reason code for the reset.

src/NimBLEDevice.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ class NimBLEDevice {
136136
static void onSync(void);
137137
static void host_task(void* param);
138138

139+
# if CONFIG_BT_NIMBLE_EXT_ADV
140+
static bool setDefaultPhy(uint8_t txPhyMask, uint8_t rxPhyMask);
141+
# endif
142+
139143
# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
140144
static NimBLEScan* getScan();
141145
# endif

src/NimBLEServer.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,20 @@ int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) {
671671
return 0;
672672
} // BLE_GAP_EVENT_IDENTITY_RESOLVED
673673

674+
# if CONFIG_BT_NIMBLE_EXT_ADV
675+
case BLE_GAP_EVENT_PHY_UPDATE_COMPLETE: {
676+
rc = ble_gap_conn_find(event->phy_updated.conn_handle, &peerInfo.m_desc);
677+
if(rc != 0) {
678+
return BLE_ATT_ERR_INVALID_HANDLE;
679+
}
680+
681+
pServer->m_pServerCallbacks->onPhyUpdate(peerInfo,
682+
event->phy_updated.tx_phy,
683+
event->phy_updated.rx_phy);
684+
return 0;
685+
} //BLE_GAP_EVENT_PHY_UPDATE_COMPLETE
686+
#endif
687+
674688
case BLE_GAP_EVENT_PASSKEY_ACTION: {
675689
struct ble_sm_io pkey = {0,0};
676690

@@ -937,6 +951,50 @@ bool NimBLEServer::startAdvertising(uint8_t inst_id,
937951
bool NimBLEServer::stopAdvertising(uint8_t inst_id) {
938952
return getAdvertising()->stop(inst_id);
939953
} // stopAdvertising
954+
955+
/**
956+
* @brief Request an update to the PHY used for a peer connection.
957+
* @param [in] connHandle the connection handle to the update the PHY for.
958+
* @param [in] txPhyMask TX PHY. Can be mask of following:
959+
* - BLE_GAP_LE_PHY_1M_MASK
960+
* - BLE_GAP_LE_PHY_2M_MASK
961+
* - BLE_GAP_LE_PHY_CODED_MASK
962+
* - BLE_GAP_LE_PHY_ANY_MASK
963+
* @param [in] rxPhyMask RX PHY. Can be mask of following:
964+
* - BLE_GAP_LE_PHY_1M_MASK
965+
* - BLE_GAP_LE_PHY_2M_MASK
966+
* - BLE_GAP_LE_PHY_CODED_MASK
967+
* - BLE_GAP_LE_PHY_ANY_MASK
968+
* @param phyOptions Additional PHY options. Valid values are:
969+
* - BLE_GAP_LE_PHY_CODED_ANY (default)
970+
* - BLE_GAP_LE_PHY_CODED_S2
971+
* - BLE_GAP_LE_PHY_CODED_S8
972+
* @return True if successful.
973+
*/
974+
bool NimBLEServer::updatePhy(uint16_t connHandle, uint8_t txPhyMask, uint8_t rxPhyMask, uint16_t phyOptions) {
975+
int rc = ble_gap_set_prefered_le_phy(connHandle, txPhyMask, rxPhyMask, phyOptions);
976+
if (rc != 0) {
977+
NIMBLE_LOGE(LOG_TAG, "Failed to update phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
978+
}
979+
980+
return rc == 0;
981+
} // updatePhy
982+
983+
/**
984+
* @brief Get the PHY used for a peer connection.
985+
* @param [in] connHandle the connection handle to the get the PHY for.
986+
* @param [out] txPhy The TX PHY.
987+
* @param [out] rxPhy The RX PHY.
988+
* @return True if successful.
989+
*/
990+
bool NimBLEServer::getPhy(uint16_t connHandle, uint8_t* txPhy, uint8_t* rxPhy) {
991+
int rc = ble_gap_read_le_phy(connHandle, txPhy, rxPhy);
992+
if (rc != 0) {
993+
NIMBLE_LOGE(LOG_TAG, "Failed to read phy; rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
994+
}
995+
996+
return rc == 0;
997+
} // getPhy
940998
#endif
941999

9421000
#if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_)
@@ -1089,4 +1147,10 @@ void NimBLEServerCallbacks::onConnParamsUpdate(NimBLEConnInfo& connInfo){
10891147
NIMBLE_LOGD("NimBLEServerCallbacks", "onConnParamsUpdate: default");
10901148
} // onConnParamsUpdate
10911149

1150+
# if CONFIG_BT_NIMBLE_EXT_ADV
1151+
void NimBLEServerCallbacks::onPhyUpdate(NimBLEConnInfo& connInfo, uint8_t txPhy, uint8_t rxPhy) {
1152+
NIMBLE_LOGD("NimBLEServerCallbacks", "onPhyUpdate: default, txPhy: %d, rxPhy: %d", txPhy, rxPhy);
1153+
} // onPhyUpdate
1154+
# endif
1155+
10921156
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */

src/NimBLEServer.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class NimBLEServer {
5555
int duration = 0,
5656
int max_events = 0);
5757
bool stopAdvertising(uint8_t inst_id);
58+
bool updatePhy(uint16_t connHandle, uint8_t txPhysMask, uint8_t rxPhysMask, uint16_t phyOptions);
59+
bool getPhy(uint16_t connHandle, uint8_t* txPhy, uint8_t* rxPhy);
5860
#endif
5961
# if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_)
6062
NimBLEAdvertising* getAdvertising();
@@ -213,6 +215,21 @@ class NimBLEServerCallbacks {
213215
* updated connection parameters.
214216
*/
215217
virtual void onConnParamsUpdate(NimBLEConnInfo& connInfo);
218+
219+
# if CONFIG_BT_NIMBLE_EXT_ADV
220+
/**
221+
* @brief Called when the PHY update procedure is complete.
222+
* @param [in] connInfo A reference to a NimBLEConnInfo instance with information
223+
* about the peer connection parameters.
224+
* @param [in] txPhy The transmit PHY.
225+
* @param [in] rxPhy The receive PHY.
226+
* Possible values:
227+
* * BLE_GAP_LE_PHY_1M
228+
* * BLE_GAP_LE_PHY_2M
229+
* * BLE_GAP_LE_PHY_CODED
230+
*/
231+
virtual void onPhyUpdate(NimBLEConnInfo& connInfo, uint8_t txPhy, uint8_t rxPhy);
232+
# endif
216233
}; // NimBLEServerCallbacks
217234

218235
#endif /* CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL */

0 commit comments

Comments
 (0)