-
-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BLE attributes are not published / can't be set after a while #155
Comments
Hey, Thanks for the log! First of all, there's a crash there, which is kind of odd, but I can make sure it doesn't happen. It might also be related that the ESP32 and the BLE devices have a very poor connection. I see many connection attempts that fail and the ones that do succeed disconnect shortly after. |
Hi! Thank you for looking into this issue. Yes it happens to all four of my esp32 sticks all the time, just need to wait 10 minutes or so. I can help with debugging if you provide instructions; I really want it to work 🙂 But idk where to start, I don't write anything for esp32. |
I figured out how to enable verbose logging and here it is: 2022-05-08-002.log |
Thanks for the log, some weird and interesting stuff there. When we try to connect to a BLE device, we stop scanning during that time frame. IIRC, at the time, the ESP had issues to do both simultaneously so that was added. What I see from the logs is that at some point, we try to connect to a device and stop scanning, then (before we get a response from that connection attempt) we try to connect to a different device (which happens because we got a notification on it before the scanning was actually stopped) and that also tries to stop scanning. That second stopping event fails with an error So, we can first try to remove that mechanism altogether since it might not be needed anymore and will remove some noise. Can you apply the below (untested) patch and see what happens? diff --git a/main/ble.c b/main/ble.c
index e189601..7ab75a3 100644
--- a/main/ble.c
+++ b/main/ble.c
@@ -159,8 +159,6 @@ static inline void ble_operation_perform(ble_operation_t *operation)
switch (operation->type)
{
case BLE_OPERATION_TYPE_CONNECT:
- /* Stop scanning while attempting to connect */
- esp_ble_gap_stop_scanning();
esp_ble_gattc_open(g_gattc_if, operation->device->mac,
operation->device->addr_type, true);
break;
@@ -805,10 +803,6 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
need_dequeue = 1;
- /* Resume scanning, if requested */
- if (scan_requested)
- esp_ble_gap_start_scanning(-1);
-
if (param->open.status != ESP_GATT_OK)
{
ESP_LOGE(TAG, "Open failed, status = 0x%x", param->open.status); As for a real fix, we have a queue that's supposed to make sure we don't try to perform multiple BLE operations at once and we wait until the operation completed before dequeuing the next operation. There's also another mechanism that if the queue is empty, we don't do the operation right away but wait for 0.5s to let it fill up (like when you first connect to a device and want to read all of its characteristics). This was intended just to keep the CPU at bay when querying a device and a burst of BLE operations is added without the overhead of actually doing anything yet. I now understand that this also had an added (unintended) benefit for the case where the last operation in the queue, which is still in progress (like trying to read a characteristic), has time to complete before a new operation is added to the (now empty) queue is actually executed. What happens in your case is that connecting to devices often fails. I don't know if it's because of the distance between the ESP and the BLE devices or just a noisy environment, but connection attempts do timeout and that takes over 0.5 seconds. So, I have a connect event in the queue, I dequeue it and ask the ESP library to connect. Then I add another connection request to queue, wait 0.5s and send it too to the ESP library before the first one completed. We can try to add another flag somewhere that an operation is still pending a response and make sure not to dequeue anything if the 0.5s timer expires and that way it'll be dequeued only when the first operation completed (as is the regular case). This might be achieved with something (also untested) like: diff --git a/main/ble.c b/main/ble.c
index e189601..5396858 100644
--- a/main/ble.c
+++ b/main/ble.c
@@ -59,6 +59,7 @@ typedef struct ble_operation_t {
/* Internal state */
static uint8_t scan_requested = 0;
+static uint8_t operation_in_progress = 0;
static esp_gatt_if_t g_gattc_if = ESP_GATT_IF_NONE;
static ble_device_t *devices_list = NULL;
static ble_operation_t *operation_queue = NULL;
@@ -200,10 +201,14 @@ static void ble_operation_dequeue(ble_operation_t **queue)
"len: %u, val: %p", operation->type, MAC_PARAM(operation->device->mac),
UUID_PARAM(operation->characteristic->uuid), operation->len,
operation->value);
+ operation_in_progress = 1;
ble_operation_perform(operation);
if (operation->type == BLE_OPERATION_TYPE_WRITE_CHAR)
+ {
+ operation_in_progress = 0;
ble_operation_dequeue(queue);
+ }
if (operation->len)
free(operation->value);
@@ -212,7 +217,9 @@ static void ble_operation_dequeue(ble_operation_t **queue)
static void ble_queue_timer_cb(TimerHandle_t xTimer)
{
- ESP_LOGD(TAG, "Queue timer expired");
+ ESP_LOGD(TAG, "Queue timer expired, operation_in_progress: %u", operation_in_progress);
+ if (operation_in_progress)
+ return;
ble_operation_dequeue(&operation_queue);
}
@@ -994,7 +1001,10 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
}
if (need_dequeue)
+ {
+ operation_in_progress = 0;
ble_operation_dequeue(&operation_queue);
+ }
}
static void ble_purge_device_list_timer_cb(TimerHandle_t xTimer) I apologize if the above was too much but at least I have a better understanding of your issue now. |
Thanks for the very detailed analysis! |
Describe the bug
ble2mqtt stops publishing BLE GATT values after working for some time. After it happens, trying to set any GATT value does not have any effect either.
Interestingly, it still continues to publish beacon information.
To Reproduce
<mqtt_prefix>/<bt_mac>/<service_uuid>/<attr_uuid>/Set
does not have any effect.Expected behavior
GATT values can be read and written at all times.
Configuration and logs
Logs obtained by running
./idf.py monitor
:2022-05-08.log
MQTT:
mqtt.log
Additional context
I'm running esp32-ble2mqtt on M5Stack's AtomU ESP32 Development Kit with USB-A.
The text was updated successfully, but these errors were encountered: