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:
@@ -187,26 +187,22 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onConfigComplete() override
|
virtual void onConfigComplete() override
|
||||||
{
|
{
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool runOnceHasWorkToDo() { return runOnceHasWorkToPhone() || runOnceHasWorkFromPhone(); }
|
bool runOnceHasWorkToDo() { return runOnceHasWorkToPhone() || runOnceHasWorkFromPhone(); }
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user