Simplify tracking of BLE connection handle & improve thread safety. (#10390)

- Redefine isConnected in terms of nimbleBluetoothConnHandle. isConnected was not safe because BLEServer::getConnectedCount is not thread-safe (https://github.com/espressif/arduino-esp32/issues/12538) while isConnected is called from various threads. Now we can avoid checking bleServer every time before calling isConnected.
- getRssi: don't try to "populate nimbleBluetoothConnHandle", that requires calling BLEServer::getPeerDevices which is not thread-safe (same issue as above).
This commit is contained in:
Catalin Patulea
2026-05-29 06:48:43 -05:00
committed by GitHub
parent 1971e5ab13
commit d3c7f05baa
+13 -30
View File
@@ -187,11 +187,9 @@ class BluetoothPhoneAPI : public PhoneAPI, public concurrency::OSThread
LOG_INFO("BLE onConfigStart"); LOG_INFO("BLE onConfigStart");
// Prefer high throughput during config/setup, at the cost of high power consumption (for a few seconds) // Prefer high throughput during config/setup, at the cost of high power consumption (for a few seconds)
if (bleServer && isConnected()) { uint16_t conn_handle = nimbleBluetoothConnHandle.load();
uint16_t conn_handle = nimbleBluetoothConnHandle.load(); if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
if (conn_handle != BLE_HS_CONN_HANDLE_NONE) { requestHighThroughputConnection(conn_handle);
requestHighThroughputConnection(conn_handle);
}
} }
} }
@@ -200,11 +198,9 @@ class BluetoothPhoneAPI : public PhoneAPI, public concurrency::OSThread
LOG_INFO("BLE onConfigComplete"); LOG_INFO("BLE onConfigComplete");
// Switch to lower power consumption BLE connection params for steady-state use after config/setup is complete // Switch to lower power consumption BLE connection params for steady-state use after config/setup is complete
if (bleServer && isConnected()) { uint16_t conn_handle = nimbleBluetoothConnHandle.load();
uint16_t conn_handle = nimbleBluetoothConnHandle.load(); if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
if (conn_handle != BLE_HS_CONN_HANDLE_NONE) { requestLowerPowerConnection(conn_handle);
requestLowerPowerConnection(conn_handle);
}
} }
} }
@@ -337,7 +333,7 @@ class BluetoothPhoneAPI : public PhoneAPI, public concurrency::OSThread
} }
/// Check the current underlying physical link to see if the client is currently connected /// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override { return bleServer && bleServer->getConnectedCount() > 0; } virtual bool checkIsConnected() override { return nimbleBluetoothConnHandle.load() != BLE_HS_CONN_HANDLE_NONE; }
void requestHighThroughputConnection(uint16_t conn_handle) void requestHighThroughputConnection(uint16_t conn_handle)
{ {
@@ -732,32 +728,19 @@ bool NimbleBluetooth::isActive()
bool NimbleBluetooth::isConnected() bool NimbleBluetooth::isConnected()
{ {
return bleServer && bleServer->getConnectedCount() > 0; return nimbleBluetoothConnHandle.load() != BLE_HS_CONN_HANDLE_NONE;
} }
int NimbleBluetooth::getRssi() int NimbleBluetooth::getRssi()
{ {
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6) #if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C6)
if (!bleServer || !isConnected()) { uint16_t conn_handle = nimbleBluetoothConnHandle.load();
if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
return 0; // No active BLE connection return 0; // No active BLE connection
} }
uint16_t connHandle = nimbleBluetoothConnHandle.load();
if (connHandle == BLE_HS_CONN_HANDLE_NONE) {
const auto peers = bleServer->getPeerDevices(true);
if (!peers.empty()) {
connHandle = peers.begin()->first;
nimbleBluetoothConnHandle = connHandle;
}
}
if (connHandle == BLE_HS_CONN_HANDLE_NONE) {
return 0; // Connection handle not available yet
}
int8_t rssi = 0; int8_t rssi = 0;
const int rc = ble_gap_conn_rssi(connHandle, &rssi); const int rc = ble_gap_conn_rssi(conn_handle, &rssi);
if (rc == 0) { if (rc == 0) {
return rssi; return rssi;
@@ -879,7 +862,7 @@ void NimbleBluetooth::setupService()
/// Given a level between 0-100, update the BLE attribute /// Given a level between 0-100, update the BLE attribute
void updateBatteryLevel(uint8_t level) void updateBatteryLevel(uint8_t level)
{ {
if ((config.bluetooth.enabled == true) && bleServer && nimbleBluetooth->isConnected()) { if ((config.bluetooth.enabled == true) && nimbleBluetooth->isConnected()) {
BatteryCharacteristic->setValue(&level, 1); BatteryCharacteristic->setValue(&level, 1);
BatteryCharacteristic->notify(); BatteryCharacteristic->notify();
} }
@@ -894,7 +877,7 @@ void NimbleBluetooth::clearBonds()
void NimbleBluetooth::sendLog(const uint8_t *logMessage, size_t length) void NimbleBluetooth::sendLog(const uint8_t *logMessage, size_t length)
{ {
if (!bleServer || !isConnected() || length > 512) { if (!isConnected() || length > 512) {
return; return;
} }
logRadioCharacteristic->setValue(logMessage, length); logRadioCharacteristic->setValue(logMessage, length);