Skip to content

Commit 23e9455

Browse files
committed
Add asynchronous client secure
* Adds parameter `rc` to `NimBLEDevice::startSecurity`, default value works as the original method. * * `rc`: 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 a59e8ee commit 23e9455

File tree

6 files changed

+68
-15
lines changed

6 files changed

+68
-15
lines changed

src/NimBLEClient.cpp

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ NimBLEClient::NimBLEClient(const NimBLEAddress& peerAddress)
6666
m_deleteCallbacks{false},
6767
m_connEstablished{false},
6868
m_asyncConnect{false},
69+
m_asyncSecure{false},
6970
m_exchangeMTU{true},
7071
# if CONFIG_BT_NIMBLE_EXT_ADV
7172
m_phyMask{BLE_GAP_LE_PHY_1M_MASK | BLE_GAP_LE_PHY_2M_MASK | BLE_GAP_LE_PHY_CODED_MASK},
@@ -313,16 +314,42 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes,
313314
* @return True on success.
314315
* @details This is a blocking function and should not be used in a callback.
315316
*/
316-
bool NimBLEClient::secureConnection() const {
317+
bool NimBLEClient::secureConnection(bool async) {
317318
NIMBLE_LOGD(LOG_TAG, ">> secureConnection()");
318319

320+
if (!NimBLEDevice::m_synced) {
321+
NIMBLE_LOGE(LOG_TAG, "Host reset, wait for sync.");
322+
return false;
323+
}
324+
325+
if (NimBLEDevice::isSecureInProgress()) {
326+
NIMBLE_LOGE(LOG_TAG, "Secure already in progress");
327+
return false;
328+
}
329+
330+
m_asyncSecure = async;
331+
332+
// Set the secure in progress flag to prevent a scan from starting while securing.
333+
NimBLEDevice::setSecureInProgress(true);
334+
335+
int rc = 0;
336+
if (!NimBLEDevice::startSecurity(m_connHandle, &rc)) {
337+
m_lastErr = rc;
338+
m_asyncSecure = false;
339+
NimBLEDevice::setSecureInProgress(false);
340+
NIMBLE_LOGE(LOG_TAG, "secureConnection: failed to start rc=%d", rc);
341+
return false;
342+
}
343+
344+
if (m_asyncSecure) {
345+
return true;
346+
}
347+
319348
NimBLETaskData taskData(const_cast<NimBLEClient*>(this), BLE_HS_ENOTCONN);
320349
m_pTaskData = &taskData;
321350
int retryCount = 1;
322351
do {
323-
if (NimBLEDevice::startSecurity(m_connHandle)) {
324-
NimBLEUtils::taskWait(taskData, BLE_NPL_TIME_FOREVER);
325-
}
352+
NimBLEUtils::taskWait(taskData, BLE_NPL_TIME_FOREVER);
326353
} while (taskData.m_flags == (BLE_HS_ERR_HCI_BASE + BLE_ERR_PINKEY_MISSING) && retryCount--);
327354

328355
m_pTaskData = nullptr;
@@ -1087,6 +1114,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
10871114
return 0;
10881115
}
10891116

1117+
NimBLEDevice::setSecureInProgress(false);
10901118
if (event->enc_change.status == 0 ||
10911119
event->enc_change.status == (BLE_HS_ERR_HCI_BASE + BLE_ERR_PINKEY_MISSING)) {
10921120
NimBLEConnInfo peerInfo;

src/NimBLEClient.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class NimBLEClient {
6464
bool setConnection(uint16_t connHandle);
6565
uint16_t getMTU() const;
6666
bool exchangeMTU();
67-
bool secureConnection() const;
67+
bool secureConnection(bool async = false);
6868
void setConnectTimeout(uint32_t timeout);
6969
bool setDataLen(uint16_t txOctets);
7070
bool discoverAttributes();
@@ -120,6 +120,7 @@ class NimBLEClient {
120120
bool m_deleteCallbacks;
121121
bool m_connEstablished;
122122
bool m_asyncConnect;
123+
bool m_asyncSecure;
123124
bool m_exchangeMTU;
124125
# if CONFIG_BT_NIMBLE_EXT_ADV
125126
uint8_t m_phyMask;

src/NimBLEDevice.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ uint8_t NimBLEDevice::m_ownAddrType{BLE_OWN_ADDR_PUBLIC};
103103

104104
# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
105105
bool NimBLEDevice::m_connectionInProgress{false};
106+
bool NimBLEDevice::m_secureInProgress{false};
106107
# endif
107108

108109
# ifdef ESP_PLATFORM
@@ -1140,13 +1141,16 @@ uint32_t NimBLEDevice::getSecurityPasskey() {
11401141
* @param connHandle The connection handle of the peer device.
11411142
* @returns NimBLE stack return code, 0 = success.
11421143
*/
1143-
bool NimBLEDevice::startSecurity(uint16_t connHandle) {
1144-
int rc = ble_gap_security_initiate(connHandle);
1145-
if (rc != 0) {
1146-
NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
1144+
bool NimBLEDevice::startSecurity(uint16_t connHandle, int *rc) {
1145+
int _rc = 0;
1146+
if (rc == nullptr)
1147+
rc = &_rc;
1148+
*rc = ble_gap_security_initiate(connHandle);
1149+
if (*rc != 0) {
1150+
NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", *rc, NimBLEUtils::returnCodeToString(*rc));
11471151
}
11481152

1149-
return rc == 0 || rc == BLE_HS_EALREADY;
1153+
return *rc == 0 || *rc == BLE_HS_EALREADY;
11501154
} // startSecurity
11511155

11521156
/**
@@ -1268,6 +1272,23 @@ bool NimBLEDevice::isConnectionInProgress() {
12681272
return m_connectionInProgress;
12691273
} // isConnectionInProgress
12701274

1275+
/**
1276+
* @brief Set the secure in progress flag.
1277+
* @param [in] inProgress The secure in progress flag.
1278+
* @details This is used to prevent a scan from starting while a secure is in progress.
1279+
*/
1280+
void NimBLEDevice::setSecureInProgress(bool inProgress) {
1281+
m_secureInProgress = inProgress;
1282+
} // setSecureInProgress
1283+
1284+
/**
1285+
* @brief Check if a secure is in progress.
1286+
* @return True if a secure is in progress.
1287+
*/
1288+
bool NimBLEDevice::isSecureInProgress() {
1289+
return m_secureInProgress;
1290+
} // isSecureInProgress
1291+
12711292
/**
12721293
* @brief Return a string representation of the address of this device.
12731294
* @return A string representation of this device address.

src/NimBLEDevice.h

Lines changed: 4 additions & 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 *rc = nullptr);
133133
static bool setMTU(uint16_t mtu);
134134
static uint16_t getMTU();
135135
static bool isIgnored(const NimBLEAddress& address);
@@ -186,6 +186,8 @@ class NimBLEDevice {
186186
static NimBLEAddress getBondedAddress(int index);
187187
static void setConnectionInProgress(bool inProgress);
188188
static bool isConnectionInProgress();
189+
static void setSecureInProgress(bool inProgress);
190+
static bool isSecureInProgress();
189191
# endif
190192

191193
private:
@@ -199,6 +201,7 @@ class NimBLEDevice {
199201

200202
# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
201203
static bool m_connectionInProgress;
204+
static bool m_secureInProgress;
202205
# endif
203206

204207
# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)

src/NimBLERemoteValueAttribute.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const char* LOG_TAG = "NimBLERemoteValueAttribute";
1919
bool NimBLERemoteValueAttribute::writeValue(const uint8_t* data, size_t length, bool response) const {
2020
NIMBLE_LOGD(LOG_TAG, ">> writeValue()");
2121

22-
const NimBLEClient* pClient = getClient();
22+
NimBLEClient* pClient = getClient();
2323
int retryCount = 1;
2424
int rc = 0;
2525
uint16_t mtu = pClient->getMTU() - 3;
@@ -109,7 +109,7 @@ NimBLEAttValue NimBLERemoteValueAttribute::readValue(time_t* timestamp) const {
109109
NIMBLE_LOGD(LOG_TAG, ">> readValue()");
110110

111111
NimBLEAttValue value{};
112-
const NimBLEClient* pClient = getClient();
112+
NimBLEClient* pClient = getClient();
113113
int rc = 0;
114114
int retryCount = 1;
115115
NimBLETaskData taskData(const_cast<NimBLERemoteValueAttribute*>(this), 0, &value);

src/NimBLEScan.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,8 @@ bool NimBLEScan::isScanning() {
291291
bool NimBLEScan::start(uint32_t duration, bool is_continue) {
292292
NIMBLE_LOGD(LOG_TAG, ">> start: duration=%" PRIu32, duration);
293293

294-
if (NimBLEDevice::isConnectionInProgress()) {
295-
NIMBLE_LOGE(LOG_TAG, "Connection in progress, cannot start scan");
294+
if (NimBLEDevice::isConnectionInProgress() || NimBLEDevice::isSecureInProgress()) {
295+
NIMBLE_LOGE(LOG_TAG, "Connection/Secure in progress, cannot start scan");
296296
return false;
297297
}
298298

0 commit comments

Comments
 (0)