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

MTU negotiation problem

I'm facing a rather strange problem with an nRF52832 board I'm developing for. I'm using SDK 15.2 and S132 v6.0.0.

Sometimes, during the connection/negotiation phase, my device seems to get stuck in a weird state and can't send notifications. I've examined my logs and found out that when it works, I receive BLE_GATTC_EVT_EXCHANGE_MTU_RSP, and when it gets stuck, there is no such event received.

This is an example of a failed connection attempt:

<info> app: BLE_GAP_EVT_CONNECTED, conn handle: 1, role: 1
<debug> app: max_conn_interval: 11 ms
<debug> app: min_conn_interval: 11 ms
<debug> app: slave_latency: 0 connection events
<debug> app: conn_sup_timeout: 2000 ms
<debug> nrf_ble_gatt: Data length updated to 64 on connection 0x1.
<debug> nrf_ble_gatt: max_rx_octets: 64
<debug> nrf_ble_gatt: max_tx_octets: 64
<debug> nrf_ble_gatt: max_rx_time: 2120
<debug> nrf_ble_gatt: max_tx_time: 2120
<debug> app: BLE EVENT: 0x0024
<debug> nrf_ble_gatt: Peer on connection 0x1 requested an ATT MTU of 515 bytes.
<debug> nrf_ble_gatt: Updating ATT MTU to 64 bytes (desired: 64) on connection 0x1.
<debug> app: BLE EVENT: 0x0055
<debug> app: BLE EVENT: 0x0050
<debug> app: BLE_GATTS_EVT_WRITE, handle: 0x0017, len: 2
<error> app: Failed to notify, error: NRF_ERROR_INVALID_STATE (0x0008)

The central I'm connecting to is a Mac. This happens in the logs on the central:

default	12:11:12.512164+0000	bluetoothd	Sending MTU Request - MTU:515 Transport:2
default	12:11:12.555573+0000	bluetoothd	Received MTU Response - Response:64 Requested:515 Transport:2

This is an example of a successful attempt:

<info> app: BLE_GAP_EVT_CONNECTED, conn handle: 1, role: 1
<debug> app: max_conn_interval: 11 ms
<debug> app: min_conn_interval: 11 ms
<debug> app: slave_latency: 0 connection events
<debug> app: conn_sup_timeout: 2000 ms
<debug> nrf_ble_gatt: Data length updated to 64 on connection 0x1.
<debug> nrf_ble_gatt: max_rx_octets: 64
<debug> nrf_ble_gatt: max_tx_octets: 64
<debug> nrf_ble_gatt: max_rx_time: 2120
<debug> nrf_ble_gatt: max_tx_time: 2120
<debug> app: BLE EVENT: 0x0024
<debug> nrf_ble_gatt: Peer on connection 0x1 requested an ATT MTU of 515 bytes.
<debug> nrf_ble_gatt: Updating ATT MTU to 64 bytes (desired: 64) on connection 0x1.
<debug> app: BLE EVENT: 0x0055
<debug> nrf_ble_gatt: ATT MTU updated to 64 bytes on connection 0x1 (response).
<debug> app: BLE EVENT: 0x003A
<debug> app: BLE EVENT: 0x0050

And the central:

default	12:14:35.229238+0000	bluetoothd	Sending MTU Request - MTU:515 Transport:2
default	12:14:35.260755+0000	bluetoothd	Received MTU Request - MTU:64 Transport:2
default	12:14:35.264938+0000	bluetoothd	Received MTU Response - Response:64 Requested:515 Transport:2

Is there anything obvious that could be missing in some parameters/negotiation steps?

  • YES is the same, because in the example of success he receive the:

    ATT MTU updated to 64 bytes on connection 0x1 (response)

    in case of failed this packet is not present

    Marco

  • Hi

    Do these failures only occur when using a Mac as the central? What kind of application do you have running on your Mac? It seems liek the application doesn't wait for the ATT MTU update to complete and starts doing a BLE_GATTS_EVT_WRITE before the ATT MTU update response returns. How are you handling the ATT MTU update in both central and peripheral? Please make sure that you are waiting for a response before moving on to the next event/process in your application.

    Best regards,

    Simon

  • This happens on Windows also. I've tried both using a custom application to do connection / service discovery, but also going through the Audio Midi Setup application in macOS (this is a Bluetooth MIDI device I'm developing).

    I'm using the nrf_ble_gatt module in the nRF52 SDK to handle the GATT MTU negotiations. I've tried making my nRF52 application wait for the MTU response, but then it just hangs indefinitely in the failure case.

    In the success case, I see a request from the central, as well as a request from my peripheral. Is there a specific reason why we would need this second request from the peripheral?

  • I use IOS (IOS 14.2 iphone XSmax) as a central, connected with a device with nrF52832.

    The application on IOS do not send back the ATT MTU response, so the device close the connection after 30 second and do not manage the "write request" from the phone.

    i will try to follow your advice even if i work one level above the bt stack.

    this is what happens in my situation,  in the first a good connection in the second a bad connection:

    Marco

  • I think that the problem is not IOS but is on the NORDIC chip.

    Now I have done an interesting test with the same phone but with another device that does not use the Nordic chip.

    It is always the phone that first sends the MTU request and the device responds. The connection in this case is always fine. I believe that the our problem may depend on the fact that in the connection an MTU request is sent too soon by the nrF52, indeed perhaps it should not be sent from the chip.

    This is the situation:

Related