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

Why is BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST coming from a GATT server?

Using nRF5 SDK 14.0.0 with Softdevice s132 v5.0.0 on nRF52832.

I've set up my nrf to be a GATT client (in central role), and I'm using bluez on my Linux desktop with a LairdTech BT831 dongle as a GATT server (in peripheral role).

I found that when the client connects to the server, the server sends an ATT EXCHANGE MTU REQUEST. This is received by the softdevice on the client and I get a BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event, which is very confusing to me -- the MTU is in the client_rx_mtu field, which makes no sense because the server is telling me its MTU.

Q1: I thought the BLE spec was that only the client could initiate an ATT exchange MTU request?

Q2: Why wouldn't the softdevice event be something like BLE_GATTC_EVT_EXCHANGE_MTU_REQUEST? (I know, this isn't in the header files, but it's an event for the client, not the nonexistent server).

Thanks!

--Rob

Parents
  • Hey Rob,

    that is an excellent question. 

    From BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G:

    4.3 SERVER CONFIGURATION

     

    This procedure is used by the client to configure the Attribute Protocol. This procedure has only one sub-procedure used to set the MTU sizes.

     

    4.3.1 Exchange MTU

     

    This sub-procedure is used by the client to set the ATT_MTU to the maximum possible value that can be supported by both devices when the client supports a value greater than the default ATT_MTU for the Attribute Protocol. This subprocedure shall only be initiated once during a connection.

     

    This sub-procedure shall not be used on a BR/EDR physical link since the MTU size is negotiated using L2CAP channel configuration procedures.

     

    The Attribute Protocol Exchange MTU Request is used by this sub-procedure. The Client Rx MTU parameter shall be set to the maximum MTU that this client can receive.

     

    Two possible responses can be sent from the server for the Exchange MTU Request: Exchange MTU Response and Error Response.

     

    Error Response is returned if an error occurred on the server.

     

    The server shall respond to this message with an Exchange MTU Response with the Server Rx MTU parameter set to the maximum MTU that this server can receive.

     

    If the Error Response is sent by the server with the Error Code set to Request Not Supported, the Attribute Opcode is not supported and the default MTU shall be used.

     

    Once the messages have been exchanged, the ATT_MTU shall be set to the minimum of the Client Rx MTU and Server Rx MTU values. 

    "This sub-procedure is used by the client " Indicates that MTU exchange is only used by the Client, but the paragraph does not explicitly prohibit the server from doing the same. BT spec is usually not this vague in its description. 

    I need to start an investigation on our side. Do note that our GATT library will automatically issue an MTU exchange whenever a connection is established, regardless if it's a Client or Server. This does cause some issues with certain Android BLE stacks and BlueEZ. 

    EDIT:
    You can of course easily disable this GATT library feature.

    Cheers,

    Håkon.

Reply
  • Hey Rob,

    that is an excellent question. 

    From BLUETOOTH SPECIFICATION Version 5.0 | Vol 3, Part G:

    4.3 SERVER CONFIGURATION

     

    This procedure is used by the client to configure the Attribute Protocol. This procedure has only one sub-procedure used to set the MTU sizes.

     

    4.3.1 Exchange MTU

     

    This sub-procedure is used by the client to set the ATT_MTU to the maximum possible value that can be supported by both devices when the client supports a value greater than the default ATT_MTU for the Attribute Protocol. This subprocedure shall only be initiated once during a connection.

     

    This sub-procedure shall not be used on a BR/EDR physical link since the MTU size is negotiated using L2CAP channel configuration procedures.

     

    The Attribute Protocol Exchange MTU Request is used by this sub-procedure. The Client Rx MTU parameter shall be set to the maximum MTU that this client can receive.

     

    Two possible responses can be sent from the server for the Exchange MTU Request: Exchange MTU Response and Error Response.

     

    Error Response is returned if an error occurred on the server.

     

    The server shall respond to this message with an Exchange MTU Response with the Server Rx MTU parameter set to the maximum MTU that this server can receive.

     

    If the Error Response is sent by the server with the Error Code set to Request Not Supported, the Attribute Opcode is not supported and the default MTU shall be used.

     

    Once the messages have been exchanged, the ATT_MTU shall be set to the minimum of the Client Rx MTU and Server Rx MTU values. 

    "This sub-procedure is used by the client " Indicates that MTU exchange is only used by the Client, but the paragraph does not explicitly prohibit the server from doing the same. BT spec is usually not this vague in its description. 

    I need to start an investigation on our side. Do note that our GATT library will automatically issue an MTU exchange whenever a connection is established, regardless if it's a Client or Server. This does cause some issues with certain Android BLE stacks and BlueEZ. 

    EDIT:
    You can of course easily disable this GATT library feature.

    Cheers,

    Håkon.

Children
  • This is a bug. If nrf_ble_gatt.c sends the MTU request from the GATT server, it causes problems. For example, HID over GATT on Windows 10 (at least the version on my Stream 7 tablet) will retrieve only the first packet of the report descriptor if the Windows device supports ATT over 23 but data length of only 27. As a result, HID over GATT will not work for any non-trivial device. One solution is to disable MTU over 23, but this severely limits the speed of HID over GATT. If, instead, the GATT server waits for the Windows device to send the request (*as it should*), it works correctly. Please provide a way to disable this incorrect use of the specification in the nrf_ble_gatt.c. It should only be sent by GATT clients. Thanks!

  • As a workaround you need to put in a check for the GATT role in nrf_ble_gatt.c in the function on_connected_evt, where it initiates the mtu exchange request with a call to sd_ble_gattc_exchange_mtu_request.  

  • FWIW this bit me when trying to implement a linux NUS client to upload logs from a device.  The workaround does allow for 247 MTU when the request comes from the linux client.   

    Unfortunately the workaround breaks the nRF UART v2.0 client app for android as that app doesn't request an MTU change.  Any suggestions for getting both to work?

  • You can delay the MTU exchange until after you know what kind of device you're connected to.

  • There is a further confusion I have when reading the text in the spec after the text quoted above.

    3.4.2.2

    ....

    If either Client Rx MTU or Service Rx MTU are incorrectly less than the default
    ATT_MTU, then the ATT_MTU shall not be changed and the ATT_MTU shall
    be the default ATT_MTU.
    If a device is both a client and a server, the following rules shall apply:
    1. A device's Exchange MTU Request shall contain the same MTU as the
    device's Exchange MTU Response (i.e. the MTU shall be symmetric).
    2. If MTU is exchanged in one direction, that is sufficient for both directions.
    3. It is permitted, (but not necessary - see 2.) to exchange MTU in both
    directions, but the MTUs shall be the same in each direction (see 1.)
    4. If an Attribute Protocol Request is received after the MTU Exchange
    Request is sent and before the MTU Exchange Response is received, the
    associated Attribute Protocol Response shall use the default MTU. Figure
    3.1 shows an example that is covered by this rule. In this case device A and
    device B both use the default MTU for the Attribute Protocol Response.
    5. Once the MTU Exchange Request has been sent, the initiating device shall
    not send an Attribute Protocol Indication or Notification until after the MTU
    Exchange Response has been received. Note: This stops the risk of a crossover
    condition where the MTU size is unknown for the Indication or
    Notification.

    If the device is playing the role of both server and client (or thinks it is) how do I interpret 5? As far as I know only servers send notification or indications. The bold text in 5 suggests that it is the server that sends the MTU request....contrary to all text above.

    HEELLLP!!! Confuse me more BT SIg!

Related