Unable to update ATT MTU

Hi everyone,

I'm trying to update the ATT MTU with nRF52833 that connects to an IOS app.

For Hardware/software setup, the following is what I'm using:

  • Our toolchain is ARM GCC
  • Ubuntu 
  • SDK 17.0.2
  • SD 140

I've taken a look at samples BLE_APP_ATT_MTU_THROUGPUT and BLE_APP_UART where the ATT MTU can be updated. The following code is what I implemented to request ATT MTU. However, I wasn't able to update the ATT MTU. I checked the MTU side on IOS app (Xcode software), it showed the MTU is still 23 bytes only when the app connected to nRF52833. Please advise if I need to do anything to change it. Thanks!

/**@brief Function for handling events from the GATT library. */
static void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
{
    if (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)
    {
        m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
        NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
    }
    NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
                  p_gatt->att_mtu_desired_central,
                  p_gatt->att_mtu_desired_periph);
}

static void gatt_init(void) {
    ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
    APP_ERROR_CHECK(err_code);
}

Parents
  • Thanks for the reply, Amanda!

    Yeah, I've read that post and implemented some based on what Jimmy suggested. However, I still received only 23 bytes at MTU read by IOS app. Using nRF Connect, I was able to see DLE updated, so I believe the DLE request happened at IOS app, but somehow I can't know if IOS sent a request to nRF chip for MTU request.

  • You can check by the nRF Sniffer if you have an nRF device. 

    -Amanda H.

  • I used Sniffer to check. The following is what I got:

    • Regarding DLE exchange, I was able to receive the DLE length with a proper request-response from Server & Client.

    • Regarding ATT MTU exchange, as you can see in the first image, Master sent a request to Slave with the MTU length of 527. I don't understand why 527 here. Please advise if you have any clues.
    • Then, Slave sent a request with new MTU length (247 bytes in this case); however, no response from Master. Please advise if you have any suggestions! Thanks!
    • I've attached the sniffer file for the reference.packet sniffer_V3.pcapng

  • Hi, 

    Tai said:
    Regarding ATT MTU exchange, as you can see in the first image, Master sent a request to Slave with the MTU length of 527. I don't understand why 527 here. Please advise if you have any clues.

    Seems iOS 15: MTU was negotiated as 527. See this post. You should check with Apple. 

    Tai said:
    Then, Slave sent a request with new MTU length (247 bytes in this case); however, no response from Master. Please advise if you have any suggestions! Thanks!

    The Slave sends a response to the Master's request instead of sending a request. 

    -Amanda H.

  • You're right. The Slave sent a response to the Master's request. Sorry for not looking at the info at Sniffer carefully! 

    Sending a response to the Master, what I understand is that 247 bytes will be the new MTU when they start sending data. However, I used either IOS app or nRF Connect to check, it still said the MTU is only 23 bytes. 

    I notice that the MTU successfully is established when Slave sent a request to Master first and then Master will response right away. This is from my previous firmware (call V2), I used the same IOS app to connect. However, it didn't happen in my case. Thus, I'm wondering your comments and Jimmy's comment in other posts such as this, saying with IOS app, the Slave needs to send a request for DLE first, and the IOS app (Master) will send a request for MTU before, the Slave gives a response about that. It didn't happen to my previous FW. 

    Edit: Thank for sending me the ticket from Apple developer forum, it's exactly similar to my scenario. Since I keep seeing the MTU length of 23 bytes shown at IOS app ( via Xcode debugger), I'm very confused if the actual MTU is 23 bytes or 247 bytes that I saw the Slave responsed to the Master on Sniffer. Adding more information, I'm sending 76 bytes to the IOS app, so it will be a serious prob if the MTU is only 23 bytes.

Reply
  • You're right. The Slave sent a response to the Master's request. Sorry for not looking at the info at Sniffer carefully! 

    Sending a response to the Master, what I understand is that 247 bytes will be the new MTU when they start sending data. However, I used either IOS app or nRF Connect to check, it still said the MTU is only 23 bytes. 

    I notice that the MTU successfully is established when Slave sent a request to Master first and then Master will response right away. This is from my previous firmware (call V2), I used the same IOS app to connect. However, it didn't happen in my case. Thus, I'm wondering your comments and Jimmy's comment in other posts such as this, saying with IOS app, the Slave needs to send a request for DLE first, and the IOS app (Master) will send a request for MTU before, the Slave gives a response about that. It didn't happen to my previous FW. 

    Edit: Thank for sending me the ticket from Apple developer forum, it's exactly similar to my scenario. Since I keep seeing the MTU length of 23 bytes shown at IOS app ( via Xcode debugger), I'm very confused if the actual MTU is 23 bytes or 247 bytes that I saw the Slave responsed to the Master on Sniffer. Adding more information, I'm sending 76 bytes to the IOS app, so it will be a serious prob if the MTU is only 23 bytes.

Children
Related