mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-11-21 20:50:55 +01:00
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.
This commit is contained in:
parent
7d0636bc91
commit
724e1a7083
4 changed files with 37 additions and 2 deletions
|
@ -182,6 +182,9 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes)
|
||||||
m_pTaskData = &taskData;
|
m_pTaskData = &taskData;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
// Set the connection in progress flag to prevent a scan from starting while connecting.
|
||||||
|
NimBLEDevice::setConnectionInProgress(true);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
# if CONFIG_BT_NIMBLE_EXT_ADV
|
# if CONFIG_BT_NIMBLE_EXT_ADV
|
||||||
rc = ble_gap_ext_connect(NimBLEDevice::m_ownAddrType,
|
rc = ble_gap_ext_connect(NimBLEDevice::m_ownAddrType,
|
||||||
|
@ -207,7 +210,7 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BLE_HS_EBUSY:
|
case BLE_HS_EBUSY:
|
||||||
// Scan was still running, stop it and try again
|
// Scan was active, stop it through the NimBLEScan API to release any tasks and call the callback.
|
||||||
if (!NimBLEDevice::getScan()->stop()) {
|
if (!NimBLEDevice::getScan()->stop()) {
|
||||||
rc = BLE_HS_EUNKNOWN;
|
rc = BLE_HS_EUNKNOWN;
|
||||||
}
|
}
|
||||||
|
@ -236,8 +239,8 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes)
|
||||||
|
|
||||||
} while (rc == BLE_HS_EBUSY);
|
} while (rc == BLE_HS_EBUSY);
|
||||||
|
|
||||||
|
NimBLEDevice::setConnectionInProgress(false);
|
||||||
m_lastErr = rc;
|
m_lastErr = rc;
|
||||||
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
m_pTaskData = nullptr;
|
m_pTaskData = nullptr;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -101,6 +101,10 @@ std::vector<NimBLEAddress> NimBLEDevice::m_ignoreList{};
|
||||||
std::vector<NimBLEAddress> NimBLEDevice::m_whiteList{};
|
std::vector<NimBLEAddress> NimBLEDevice::m_whiteList{};
|
||||||
uint8_t NimBLEDevice::m_ownAddrType{BLE_OWN_ADDR_PUBLIC};
|
uint8_t NimBLEDevice::m_ownAddrType{BLE_OWN_ADDR_PUBLIC};
|
||||||
|
|
||||||
|
# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
bool NimBLEDevice::m_connectionInProgress{false};
|
||||||
|
# endif
|
||||||
|
|
||||||
# ifdef ESP_PLATFORM
|
# ifdef ESP_PLATFORM
|
||||||
# ifdef CONFIG_BTDM_BLE_SCAN_DUPL
|
# ifdef CONFIG_BTDM_BLE_SCAN_DUPL
|
||||||
uint16_t NimBLEDevice::m_scanDuplicateSize{CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE};
|
uint16_t NimBLEDevice::m_scanDuplicateSize{CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE};
|
||||||
|
@ -1232,6 +1236,23 @@ bool NimBLEDevice::setCustomGapHandler(gap_event_handler handler) {
|
||||||
return rc == 0;
|
return rc == 0;
|
||||||
} // setCustomGapHandler
|
} // setCustomGapHandler
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the connection in progress flag.
|
||||||
|
* @param [in] inProgress The connection in progress flag.
|
||||||
|
* @details This is used to prevent a scan from starting while a connection is in progress.
|
||||||
|
*/
|
||||||
|
void NimBLEDevice::setConnectionInProgress(bool inProgress) {
|
||||||
|
m_connectionInProgress = inProgress;
|
||||||
|
} // setConnectionInProgress
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if a connection is in progress.
|
||||||
|
* @return True if a connection is in progress.
|
||||||
|
*/
|
||||||
|
bool NimBLEDevice::isConnectionInProgress() {
|
||||||
|
return m_connectionInProgress;
|
||||||
|
} // isConnectionInProgress
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return a string representation of the address of this device.
|
* @brief Return a string representation of the address of this device.
|
||||||
* @return A string representation of this device address.
|
* @return A string representation of this device address.
|
||||||
|
|
|
@ -183,6 +183,8 @@ class NimBLEDevice {
|
||||||
static bool isBonded(const NimBLEAddress& address);
|
static bool isBonded(const NimBLEAddress& address);
|
||||||
static bool deleteAllBonds();
|
static bool deleteAllBonds();
|
||||||
static NimBLEAddress getBondedAddress(int index);
|
static NimBLEAddress getBondedAddress(int index);
|
||||||
|
static void setConnectionInProgress(bool inProgress);
|
||||||
|
static bool isConnectionInProgress();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -194,6 +196,10 @@ class NimBLEDevice {
|
||||||
static uint8_t m_ownAddrType;
|
static uint8_t m_ownAddrType;
|
||||||
static std::vector<NimBLEAddress> m_whiteList;
|
static std::vector<NimBLEAddress> m_whiteList;
|
||||||
|
|
||||||
|
# if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) || defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL)
|
||||||
|
static bool m_connectionInProgress;
|
||||||
|
# endif
|
||||||
|
|
||||||
# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||||
static NimBLEScan* m_pScan;
|
static NimBLEScan* m_pScan;
|
||||||
# endif
|
# endif
|
||||||
|
|
|
@ -292,6 +292,11 @@ bool NimBLEScan::isScanning() {
|
||||||
bool NimBLEScan::start(uint32_t duration, bool is_continue) {
|
bool NimBLEScan::start(uint32_t duration, bool is_continue) {
|
||||||
NIMBLE_LOGD(LOG_TAG, ">> start: duration=%" PRIu32, duration);
|
NIMBLE_LOGD(LOG_TAG, ">> start: duration=%" PRIu32, duration);
|
||||||
|
|
||||||
|
if (NimBLEDevice::isConnectionInProgress()) {
|
||||||
|
NIMBLE_LOGE(LOG_TAG, "Connection in progress, cannot start scan");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Save the duration in the case that the host is reset so we can reuse it.
|
// Save the duration in the case that the host is reset so we can reuse it.
|
||||||
m_duration = duration;
|
m_duration = duration;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue