From 9cb298b60d5ca6d04725778c954c95aba230d1ce Mon Sep 17 00:00:00 2001 From: Florian <1technophile@users.noreply.github.com> Date: Tue, 12 Nov 2024 07:24:37 -0600 Subject: [PATCH] [BT] Fix BT command triggering a stack trace due to conflict related to the vector between BLE scanning and BLE control --- docs/use/ble.md | 5 +++++ main/ZgatewayBT.ino | 42 ++++++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/docs/use/ble.md b/docs/use/ble.md index 89e5854d93..f89a4ca41d 100644 --- a/docs/use/ble.md +++ b/docs/use/ble.md @@ -317,6 +317,11 @@ By the way, if you want to load the default built-in configuration (on any board `mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"init":true}'` Note that it will not change the stored configuration, `erase` or `save` is still needed to overwrite the saved configuration. +## Controlling devices +::: tip +To control devices reliably, set the interval between scans to at least 5 seconds and the scan duration to 1 second to ensure commands are successfully transmitted to your devices. +::: + ## Read/write BLE characteristics over MQTT The gateway can read and write BLE characteristics from devices and provide the results in an MQTT message. diff --git a/main/ZgatewayBT.ino b/main/ZgatewayBT.ino index 64082e6dcf..61f4e0117c 100644 --- a/main/ZgatewayBT.ino +++ b/main/ZgatewayBT.ino @@ -1359,22 +1359,27 @@ void immediateBTAction(void* pvParameters) { } if (xSemaphoreTake(semaphoreBLEOperation, pdMS_TO_TICKS(5000)) == pdTRUE) { - // swap the vectors so only this device is processed - std::vector dev_swap; - dev_swap.push_back(getDeviceByMac(BLEactions.back().addr)); - std::swap(devices, dev_swap); - - std::vector act_swap; - act_swap.push_back(BLEactions.back()); - BLEactions.pop_back(); - std::swap(BLEactions, act_swap); - - // Unlock here to allow the action to be performed - BTProcessLock = false; - BLEconnect(); - // back to normal - std::swap(devices, dev_swap); - std::swap(BLEactions, act_swap); + if (xSemaphoreTake(semaphoreCreateOrUpdateDevice, pdMS_TO_TICKS(QueueSemaphoreTimeOutTask)) == pdTRUE) { + // swap the vectors so only this device is processed + std::vector dev_swap; + dev_swap.push_back(getDeviceByMac(BLEactions.back().addr)); + std::swap(devices, dev_swap); + + std::vector act_swap; + act_swap.push_back(BLEactions.back()); + BLEactions.pop_back(); + std::swap(BLEactions, act_swap); + + // Unlock here to allow the action to be performed + BTProcessLock = false; + BLEconnect(); + // back to normal + std::swap(devices, dev_swap); + std::swap(BLEactions, act_swap); + xSemaphoreGive(semaphoreCreateOrUpdateDevice); + } else { + Log.error(F("CreateOrUpdate Semaphore NOT taken" CR)); + } // If we stopped the scheduled connect for this action, do the scheduled now if (millis() > (timeBetweenConnect + BTConfig.intervalConnect) && BTConfig.bleConnect) { @@ -1383,7 +1388,8 @@ void immediateBTAction(void* pvParameters) { } xSemaphoreGive(semaphoreBLEOperation); } else { - Log.error(F("BLE busy - command not sent" CR)); + Log.error(F("BLE busy - immediateBTAction not sent" CR)); + gatewayState = GatewayState::ERROR; StaticJsonDocument BLEdataBuffer; JsonObject BLEdata = BLEdataBuffer.to(); BLEdata["id"] = BLEactions.back().addr; @@ -1575,7 +1581,7 @@ void XtoBT(const char* topicOri, JsonObject& BTdata) { // json object decoding XtoBTAction(BTdata); xSemaphoreGive(semaphoreBLEOperation); } else { - Log.error(F("BLE busy - command not sent" CR)); + Log.error(F("BLE busy - BTActions not sent" CR)); gatewayState = GatewayState::ERROR; } } else if (strstr(topicOri, subjectTrackerSync) != NULL) {