This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLE Notifications and MTU Negotiation on Bluetooth 4.0

I've managed to successfully increase BLE MTU Size and Data Length on a 52840 to 247 and 251 respectively.

This works fine  with BLE Notifications on a recent MacBook Pro with Bluetooth 4.2 (it negotiates to 247 and 251) and I can transfer 244 bytes at a time

However on an Mac Pro (late 2013) which is Bluetooth 4.2, mtu and data length negotiation, negotiate to 247 and 27 respectively.

When I then try to send a notification of 244 bytes in length, it's truncated to 101 bytes (i.e. an MTU of 104 bytes).

However equally confusing, Bluetooth 4.0 suggests that the MTU size is 23 bytes.

So why:

a) Is Bluetooth 4.0 capable of a large MTU size than expected?

b) Why is data getting truncated at 101 bytes when 244 has been negotiated successfully?

c) How can I get the mtu negotiation in the erf sdk to negotiate the correct size or identify it's a Bluetooth 4.0 device?

Thanks

  • Hello,

    a) Yes, the specification does not limit it to 23 bytes. The max. ATT MTU size implementation specific and thus dependent on the device you are connected to. Some 4.0 devices support long MTUs while others only support the default length (23 bytes). The same applies to newer devices. There is for instance no guarantee that a new Bluetooth 5.2 device will support long att MTU.

    Data length extension was however not supported in v4.0 of the specification, that was introduced in v4.2

    b) I'm afraid this doesn't make sense to me either, it should not be possible. Is the notification sent from the nRF52840? In that case, could you maybe show the implementation of your send function? A sniffer trace may also be helpful (nRF Sniffer).

    c) There isn't any easy way for the app to determine what BT version the peer device is running.

    Best regards,

    Vidar

  • Thanks for the fast reply.  That explains a), and i've found out that OSX is limiting and sending a smaller MTU of 104 bytes, however the sdk receives it and sets to 247 anyway.

    Console log on Mac OSX:

    App log:

    Could this have anything to do with setting:

    #define BLE_GATT_ATT_MTU_DEFAULT          NRF_SDH_BLE_GATT_MAX_MTU_SIZE   (which is 247)

    in ble_gatt.h ?  I.E. does BLE_GATT_ATT_MTU_DEFAULT ignore what central sends as the MTU and force the negotiation to BLE_GATT_ATT_MTU_DEFAULT

    I had to change BLE_GATT_ATT_MTU_DEFAULT from 23 to get larger mtu's, otherwise I was getting a hard fault in sd_ble_gattc_exchange_mtu_request when NRF_SDH_BLE_GATT_MAX_MTU_SIZE was > 23 and BLE_GATT_MTU_DEFAULT was 23. 

    RAM_START is correct btw, I have some code in there to refuse to run and error when it's not correct for the settings.

    SDK16.0.0 S140 7.0.1

  • it does appear that changing BLE_GATT_ATT_MTU_DEFAULT to a value other than 23, causes issues with MTU negotiation if the client cannot handle the maximum MTU size requested and replies with a smaller value, this can be found in "on_exchange_mtu_request_evt" in "nrf_ble_gatt.c":

    client_mtu = MAX(client_mtu, BLE_GATT_ATT_MTU_DEFAULT);

    This can be changed from MAX to MIN for a workaround to solve this.

    But I suspect that maybe BLE_GATT_ATT_MTU_DEFAULT should be left at 23 when increasing MTU size (however in my case that causes this  hard fault on negotiation).

    Q. So when changing NRF_SDH_BLE_GATT_MAX_MTU_SIZE to 247, should BLE_GATT_ATT_MTU_DEFAULT be changed to match ?

    And if not, then any ideas why if NRF_SDH_BLE_GATT_MAX_MTU_SIZE is raised, and BLE_GATT_ATT_MTU_DEFAULT is kept at 23, this happens in "sd_ble_gattc_exchange_mtu_request" in "nrf_ble_gatt.c" with all bluetooth clients (including 4.2) ?

    Thanks

  • It's interesting that the hardfault appears occur inside the Softdevice, not sure if actually I've seen it before (except for internal SD assertions that makes it trigger it on purpose). Anyway. As you suspected, BLE_GATT_ATT_MTU_DEFAULT is not supposed to be modified.

    Would it be possible for you to test the same with the SDK ble_app_uart example? This is one of the SDK examples which is set up to request 247 bytes for the MTU and 251 for data length by default. 

Related