Skip to content

Commit 6ae7cc7

Browse files
committed
Fix endless loop when calling scan start from scan end callback.
When attempting to connect and the scanner is running `NimBLEScan::stop` is called to stop it which then calls the `onScanEnded` callback. If the app then starts the scan again in this callback an endless loop will be created. This change prevents the endless loop by setting a flag in the `NimBLEScan` that prevents the scan from starting while a client is trying to connect.
1 parent 98a2d35 commit 6ae7cc7

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

src/NimBLEClient.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes)
182182
m_pTaskData = &taskData;
183183
int rc = 0;
184184

185+
// Set the connection in progress flag to prevent a scan from starting while connecting.
186+
NimBLEDevice::getScan()->setConnectionInProgress(true);
187+
185188
do {
186189
# if CONFIG_BT_NIMBLE_EXT_ADV
187190
rc = ble_gap_ext_connect(NimBLEDevice::m_ownAddrType,
@@ -207,7 +210,7 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes)
207210
break;
208211

209212
case BLE_HS_EBUSY:
210-
// Scan was still running, stop it and try again
213+
// Scan was active, stop it through the NimBLEScan API to release any tasks and call the callback.
211214
if (!NimBLEDevice::getScan()->stop()) {
212215
rc = BLE_HS_EUNKNOWN;
213216
}
@@ -236,8 +239,8 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes)
236239

237240
} while (rc == BLE_HS_EBUSY);
238241

242+
NimBLEDevice::getScan()->setConnectionInProgress(false);
239243
m_lastErr = rc;
240-
241244
if (rc != 0) {
242245
m_pTaskData = nullptr;
243246
return false;

src/NimBLEScan.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ NimBLEScan::NimBLEScan() {
4040
m_pTaskData = nullptr;
4141
m_duration = BLE_HS_FOREVER; // make sure this is non-zero in the event of a host reset
4242
m_maxResults = 0xFF;
43+
m_connectionInProgress = false;
4344
}
4445

4546

@@ -292,6 +293,11 @@ bool NimBLEScan::isScanning() {
292293
bool NimBLEScan::start(uint32_t duration, bool is_continue) {
293294
NIMBLE_LOGD(LOG_TAG, ">> start: duration=%" PRIu32, duration);
294295

296+
if (isConnectionInProgress()) {
297+
NIMBLE_LOGE(LOG_TAG, "Connection in progress, cannot start scan");
298+
return false;
299+
}
300+
295301
// Save the duration in the case that the host is reset so we can reuse it.
296302
m_duration = duration;
297303

@@ -444,6 +450,22 @@ void NimBLEScan::onHostSync() {
444450
}
445451
}
446452

453+
/**
454+
* @brief Set the connection in progress flag.
455+
* @param [in] inProgress The connection in progress flag.
456+
* @details This is used to prevent a scan from starting while a connection is in progress.
457+
*/
458+
void NimBLEScan::setConnectionInProgress(bool inProgress) {
459+
m_connectionInProgress = inProgress;
460+
}
461+
462+
/**
463+
* @brief Get the connection in progress flag.
464+
* @return True if a connection is in progress.
465+
*/
466+
bool NimBLEScan::isConnectionInProgress() {
467+
return m_connectionInProgress;
468+
}
447469

448470
/**
449471
* @brief Start scanning and block until scanning has been completed.

src/NimBLEScan.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class NimBLEScan {
7878
NimBLEScanResults getResults(uint32_t duration, bool is_continue = false);
7979
void setMaxResults(uint8_t maxResults);
8080
void erase(const NimBLEAddress &address);
81+
void setConnectionInProgress(bool inProgress);
82+
bool isConnectionInProgress();
8183

8284

8385
private:
@@ -96,6 +98,7 @@ class NimBLEScan {
9698
uint32_t m_duration;
9799
BleTaskData *m_pTaskData;
98100
uint8_t m_maxResults;
101+
bool m_connectionInProgress;
99102
};
100103

101104
/**

0 commit comments

Comments
 (0)