Skip to content

Commit 724e1a7

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 `NimBLEDevice` that is checked before starting a scan while a client is trying to connect. * Adds `NimBLEDevice::setConnectionInProgress` and `NimBLEDevice::isConnectionInProgress` functions.
1 parent 7d0636b commit 724e1a7

File tree

4 files changed

+37
-2
lines changed

4 files changed

+37
-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::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::setConnectionInProgress(false);
239243
m_lastErr = rc;
240-
241244
if (rc != 0) {
242245
m_pTaskData = nullptr;
243246
return false;

src/NimBLEDevice.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ std::vector<NimBLEAddress> NimBLEDevice::m_ignoreList{};
101101
std::vector<NimBLEAddress> NimBLEDevice::m_whiteList{};
102102
uint8_t NimBLEDevice::m_ownAddrType{BLE_OWN_ADDR_PUBLIC};
103103

104+
# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
105+
bool NimBLEDevice::m_connectionInProgress{false};
106+
# endif
107+
104108
# ifdef ESP_PLATFORM
105109
# ifdef CONFIG_BTDM_BLE_SCAN_DUPL
106110
uint16_t NimBLEDevice::m_scanDuplicateSize{CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE};
@@ -1232,6 +1236,23 @@ bool NimBLEDevice::setCustomGapHandler(gap_event_handler handler) {
12321236
return rc == 0;
12331237
} // setCustomGapHandler
12341238

1239+
/**
1240+
* @brief Set the connection in progress flag.
1241+
* @param [in] inProgress The connection in progress flag.
1242+
* @details This is used to prevent a scan from starting while a connection is in progress.
1243+
*/
1244+
void NimBLEDevice::setConnectionInProgress(bool inProgress) {
1245+
m_connectionInProgress = inProgress;
1246+
} // setConnectionInProgress
1247+
1248+
/**
1249+
* @brief Check if a connection is in progress.
1250+
* @return True if a connection is in progress.
1251+
*/
1252+
bool NimBLEDevice::isConnectionInProgress() {
1253+
return m_connectionInProgress;
1254+
} // isConnectionInProgress
1255+
12351256
/**
12361257
* @brief Return a string representation of the address of this device.
12371258
* @return A string representation of this device address.

src/NimBLEDevice.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ class NimBLEDevice {
183183
static bool isBonded(const NimBLEAddress& address);
184184
static bool deleteAllBonds();
185185
static NimBLEAddress getBondedAddress(int index);
186+
static void setConnectionInProgress(bool inProgress);
187+
static bool isConnectionInProgress();
186188
# endif
187189

188190
private:
@@ -194,6 +196,10 @@ class NimBLEDevice {
194196
static uint8_t m_ownAddrType;
195197
static std::vector<NimBLEAddress> m_whiteList;
196198

199+
# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
200+
static bool m_connectionInProgress;
201+
# endif
202+
197203
# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
198204
static NimBLEScan* m_pScan;
199205
# endif

src/NimBLEScan.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,11 @@ bool NimBLEScan::isScanning() {
292292
bool NimBLEScan::start(uint32_t duration, bool is_continue) {
293293
NIMBLE_LOGD(LOG_TAG, ">> start: duration=%" PRIu32, duration);
294294

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

0 commit comments

Comments
 (0)