mongoose-os-libs/bt-common

Low performance of NOTIFY or INDICATE

Opened this issue · 9 comments

zdila commented

We are sending cca 120 notifications per second. When we subscribe to indications with nRF Connect Android App then ESP32 (as GATTS) device quickly runs out of heap memory because elements from pending_inds in esp32_bt_gatts.c are removed much less ofthen than they are added.

With notifications only (no indications) it is better but still it fills up. What is interesting that if we subscribe to that notifications with another ESP32 (as GATTC) then the performance of GATTS is even worse.

This can be reproduced by creating project which uses https://github.com/mongoose-os-libs/bt-service-debug, logging 200 messages per second and turnign of indications on the client.

Is there anything we can check?

rojer commented

ok, so two issues here:

  1. there should be a limit on the number of items we queue so that the system degrades gracefully when under load - start dropping notifications but not crash
  2. increase performance to be able to process more notifications.

(1) is easy, (2) is more challenging. what kind of performance are you looking for? would just (1) be enough?

zdila commented

Major bottleneck seems to be on the client when it calls mgos_event_trigger_schedule in ESP_GATTC_NOTIFY_EVT case in file esp32_bt_gattc.c. Initially ESP_GATTC_NOTIFY_EVT case is executed 120x per second and then it gets very quickly "saturated" (probably because of rtos task queue full) and is executed cca 4x per second. If we comment mgos_event_trigger_schedule call then the rate of ESP_GATTC_NOTIFY_EVT doesn't decrease.

This also causes problems on the server, because ESP_GATTS_CONF_EVT is then surprisingly delayed and it doesn't catch emptying of pending_inds. I said surprisingly because in case on notifications (unconfirmed) this should be called immediately on sending without asking on response (see espressif/esp-idf#749).

I think that in mgos_bt_gatts_notify there is no need to put anything to queue unless mode == MGOS_BT_GATT_NOTIFY_MODE_INDICATE. It would then prevent that problems on server.

zdila commented

BTW nRF Connect app has no problems reading the data without observed data loss from the ESP32 client (used recording functionality).

zdila commented

Regarding slow mgos_event_trigger_schedule our MGOS_BT_GATTC_EV_NOTIFY event handler was during the test empty.

zdila commented

BTW nRF Connect app has no problems reading the data without observed data loss from the ESP32 client (used recording functionality).

But it also causes memory exhaustion by big pending_inds.

zdila commented

I am now playing with bare ESP-IDF gatt_client and gatt_server examples and there is no problem sending and receiving 100 notifications per second.

zdila commented

...also no problem with 300 notif per second.

Did you make further progress with this, did you end up simply using ESP-IDF?

zdila commented

I am using my hacks directly accessing ESP-IDF API. Also the project is now hibernating (you know, start-ups...).