Skip to content

Commit 15392bf

Browse files
thekurtovich2zero
authored andcommitted
Add asynchronous client connection secure
* Adds parameter `rcPtr` to `NimBLEDevice::startSecurity`, default value works as the original method. * * `rcPtr`: if not nullptr, will allow caller to obtain the internal return code. * Adds parameter `async` to `NimBLEClient::secureConnection`, default value works as the original method. * * `async`; if true, will send the secure command and return immediately with a true value for successfully sending the command, else false.
1 parent e0fe166 commit 15392bf

File tree

4 files changed

+33
-7
lines changed

4 files changed

+33
-7
lines changed

src/NimBLEClient.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ NimBLEClient::NimBLEClient(const NimBLEAddress& peerAddress)
6363
m_pClientCallbacks{&defaultCallbacks},
6464
m_connHandle{BLE_HS_CONN_HANDLE_NONE},
6565
m_terminateFailCount{0},
66+
m_asyncSecureAttempt{0},
6667
m_config{},
6768
# if CONFIG_BT_NIMBLE_EXT_ADV
6869
m_phyMask{BLE_GAP_LE_PHY_1M_MASK | BLE_GAP_LE_PHY_2M_MASK | BLE_GAP_LE_PHY_CODED_MASK},
@@ -293,12 +294,26 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes,
293294
/**
294295
* @brief Initiate a secure connection (pair/bond) with the server.\n
295296
* Called automatically when a characteristic or descriptor requires encryption or authentication to access it.
297+
* @param [in] async If true, the connection will be secured asynchronously and this function will return immediately.\n
298+
* If false, this function will block until the connection is secured or the client disconnects.
296299
* @return True on success.
297-
* @details This is a blocking function and should not be used in a callback.
300+
* @details If async=false, this function will block and should not be used in a callback.
298301
*/
299-
bool NimBLEClient::secureConnection() const {
302+
bool NimBLEClient::secureConnection(bool async) const {
300303
NIMBLE_LOGD(LOG_TAG, ">> secureConnection()");
301304

305+
int rc = 0;
306+
if (async && !NimBLEDevice::startSecurity(m_connHandle, &rc)) {
307+
m_lastErr = rc;
308+
m_asyncSecureAttempt = 0;
309+
return false;
310+
}
311+
312+
if (async) {
313+
m_asyncSecureAttempt++;
314+
return true;
315+
}
316+
302317
NimBLETaskData taskData(const_cast<NimBLEClient*>(this), BLE_HS_ENOTCONN);
303318
m_pTaskData = &taskData;
304319
int retryCount = 1;
@@ -988,6 +1003,8 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
9881003
NIMBLE_LOGD(LOG_TAG, "disconnect; reason=%d, %s", rc, NimBLEUtils::returnCodeToString(rc));
9891004

9901005
pClient->m_terminateFailCount = 0;
1006+
pClient->m_asyncSecureAttempt = 0;
1007+
9911008
// Don't call the disconnect callback if we are waiting for a connection to complete and it fails
9921009
if (rc != (BLE_HS_ERR_HCI_BASE + BLE_ERR_CONN_ESTABLISHMENT) || pClient->m_config.asyncConnect) {
9931010
pClient->m_pClientCallbacks->onDisconnect(pClient, rc);
@@ -1150,7 +1167,12 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
11501167
if (event->enc_change.status == (BLE_HS_ERR_HCI_BASE + BLE_ERR_PINKEY_MISSING)) {
11511168
// Key is missing, try deleting.
11521169
ble_store_util_delete_peer(&peerInfo.m_desc.peer_id_addr);
1170+
// Attempt a retry if async secure failed.
1171+
if (pClient->m_asyncSecureAttempt == 1) {
1172+
pClient->secureConnection(true);
1173+
}
11531174
} else {
1175+
pClient->m_asyncSecureAttempt = 0;
11541176
pClient->m_pClientCallbacks->onAuthenticationComplete(peerInfo);
11551177
}
11561178
}

src/NimBLEClient.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class NimBLEClient {
6565
bool setConnection(uint16_t connHandle);
6666
uint16_t getMTU() const;
6767
bool exchangeMTU();
68-
bool secureConnection() const;
68+
bool secureConnection(bool async = false) const;
6969
void setConnectTimeout(uint32_t timeout);
7070
bool setDataLen(uint16_t txOctets);
7171
bool discoverAttributes();
@@ -131,6 +131,7 @@ class NimBLEClient {
131131
NimBLEClientCallbacks* m_pClientCallbacks;
132132
uint16_t m_connHandle;
133133
uint8_t m_terminateFailCount;
134+
mutable uint8_t m_asyncSecureAttempt;
134135
Config m_config;
135136

136137
# if CONFIG_BT_NIMBLE_EXT_ADV

src/NimBLEDevice.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,14 +1136,17 @@ uint32_t NimBLEDevice::getSecurityPasskey() {
11361136
/**
11371137
* @brief Start the connection securing and authorization for this connection.
11381138
* @param connHandle The connection handle of the peer device.
1139-
* @returns NimBLE stack return code, 0 = success.
1139+
* @param rcPtr Optional pointer to pass the return code to the caller.
1140+
* @returns True if successfully started, success = 0 or BLE_HS_EALREADY.
11401141
*/
1141-
bool NimBLEDevice::startSecurity(uint16_t connHandle) {
1142+
bool NimBLEDevice::startSecurity(uint16_t connHandle, int* rcPtr) {
11421143
int rc = ble_gap_security_initiate(connHandle);
11431144
if (rc != 0) {
11441145
NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
11451146
}
1146-
1147+
if (rcPtr) {
1148+
*rcPtr = rc;
1149+
}
11471150
return rc == 0 || rc == BLE_HS_EALREADY;
11481151
} // startSecurity
11491152

src/NimBLEDevice.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class NimBLEDevice {
129129
static void setSecurityRespKey(uint8_t respKey);
130130
static void setSecurityPasskey(uint32_t passKey);
131131
static uint32_t getSecurityPasskey();
132-
static bool startSecurity(uint16_t connHandle);
132+
static bool startSecurity(uint16_t connHandle, int* rcPtr = nullptr);
133133
static bool setMTU(uint16_t mtu);
134134
static uint16_t getMTU();
135135
static void onReset(int reason);

0 commit comments

Comments
 (0)