-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Description
Answers checklist.
- I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- I have searched the issue tracker for a similar issue and not found a similar issue.
General issue report
ESP32 - Android communication seems to fail if sending a message longer than 23 Bytes (20 bytes payload), when using Nimble.
Before any connection is performed, we run the folwing command to increase the MTU when the phone (client-central) connects to ESP32 (server-peripheral):
if (ble_att_set_preferred_mtu(247) != 0) {return RES_ERROR;}
We already sniffed traffic with a nRF dongle with the following result:
LL_LENGTH_REQ (from Android):
Max RX octets: 251
Max RX time: 2120 microseconds
Max TX octets: 27
MAX TX time: 328 microseconds
LL_LENGTH_RSP (from ESP32):
Max RX octets: 251
Max RX time: 2120 microseconds
Max TX octets: 27
MAX TX time: 328 microseconds
Once the communication starts, the ESP32 can send a notification with any content, but in the sniffed data we can see that only the first 20 bytes of data are sent. It means that ESP32 is honoring the limit of 27 octets for TX even when we used "ble_att_set_preferred_mtu()" before. We also tried to use this function in "BLE_GAP_EVENT_CONNECT" event without success.
It seems that there is a BUG in the way Nimble negotiates MTU!
Android informs that it is ready to receive up to 251 bytes, but when the ESP32 responds, it informs that it will also be able to send 27 bytes, despite the fact that we used "ble_att_set_preferred_mtu(247)" to increase the MTU negotiated.
A solution would be to negotiate the MTU like iOS does. From that point, any notification greater than 20 bytes will be split in chunks with L2CAP protocol. This is performed automatically, but this solution is A BAD IDEA, as a message of 160 bytes will be splitted in A LOT of packets, and the time required for transmission will increase too much.
- Are you planning to add MTU negotiation support to Nimble?
- Is it only available in Bluedroid as it seems to be?
I've found other functions that could help, but they are related to Bluedroid, not to Nimble:
esp_ble_gap_set_pkt_data_len(); esp_ble_gatt_set_local_mtu();
Using IDF 4.3.3
Best regards