Skip to content

Nimble unable to change MTU (IDFGH-8130) #9627

@FcoFabra

Description

@FcoFabra

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

Metadata

Metadata

Assignees

Labels

Resolution: NAIssue resolution is unavailableStatus: DoneIssue is done internally

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions