NRF_ERROR_RESOURCES caused by sd_ble_gap_data_length_update()

Hi all,

I am currently developing on the development board nRF52832, SDK16.0 and SD132v7.2.0.

My development board acts as a slave, while an app that tries to connect to it acts as a master. I set following values for the respective parameters:

// <o> NRF_SDH_BLE_GAP_EVENT_LENGTH - GAP event length. 
// <i> The time set aside for this connection on every connection interval in 1.25 ms units.

#ifndef NRF_SDH_BLE_GAP_EVENT_LENGTH
#define NRF_SDH_BLE_GAP_EVENT_LENGTH 320
#endif

// <o> NRF_SDH_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size. 
#ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE
#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 185
#endif

// <o> NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE - Attribute Table size in bytes. The size must be a multiple of 4. 
#ifndef NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE
#define NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE 1408

So, i tried to establish a connection from the app to my development board and i got the following comment:

<error> nrf_ble_gatt: sd_ble_gap_data_length_update() (request) on connection 0x0 returned NRF_ERROR_RESOURCES.
<error> nrf_ble_gatt: The requested TX/RX packet length is too long by 62/62 octets.

By using the sniffer i also figuredthat the development board does not respond to LL_LENGTH_REQ sent out from the Master.

Based on this i took a deeper look and figured out that this error is caused by the function: data_length_update(uint16_t conn_handle, uint16_t data_length). I modified this function in following way and it seems to work:

static ret_code_t data_length_update(uint16_t conn_handle, uint16_t data_length)
{
    NRF_LOG_DEBUG("Updating data length to %u on connection 0x%x.",
                  data_length, conn_handle);

    ble_gap_data_length_params_t const dlp =
    {
        .max_rx_octets  = data_length,
        .max_tx_octets  = data_length,
        .max_rx_time_us = BLE_GAP_DATA_LENGTH_AUTO,
        .max_tx_time_us = BLE_GAP_DATA_LENGTH_AUTO,
    };

    ble_gap_data_length_params_t updated_dlp = {0};

    ble_gap_data_length_limitation_t dll = {0};

    ret_code_t err_code = sd_ble_gap_data_length_update(conn_handle, &dlp, &dll);

    if( err_code == NRF_ERROR_RESOURCES)
    {
      updated_dlp.max_rx_octets = dlp.max_rx_octets - dll.rx_payload_limited_octets;
      updated_dlp.max_rx_octets = dlp.max_tx_octets - dll.tx_payload_limited_octets;
      updated_dlp.max_rx_time_us = BLE_GAP_DATA_LENGTH_AUTO;
      updated_dlp.max_tx_time_us = BLE_GAP_DATA_LENGTH_AUTO;
      
      err_code = sd_ble_gap_data_length_update(conn_handle, &updated_dlp, &dll);
    }

    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_ERROR("sd_ble_gap_data_length_update() (request) on connection 0x%x returned %s.",
                      conn_handle, nrf_strerror_get(err_code));

        if (   (dll.tx_payload_limited_octets != 0)
            || (dll.rx_payload_limited_octets != 0))
        {
            NRF_LOG_ERROR("The requested TX/RX packet length is too long by %u/%u octets.",
                          dll.tx_payload_limited_octets, dll.rx_payload_limited_octets);
        }

        if (dll.tx_rx_time_limited_us != 0)
        {
            NRF_LOG_ERROR("The requested combination of TX and RX packet lengths "
                          "is too long by %u microseconds.",
                          dll.tx_rx_time_limited_us);
        }
    }

    return err_code;
}

So i basically added a new variable (ble_gap_data_length_limitation_t dll = {0};), adjusted max_rx_octets and max_tx_octets and passed it as parameter for sd_ble_gap_data_length_update() function. My development board is responding now with LL_LENGTH_RSP and the adjusted RX and TX octets. Based on the Figure in Data Length Upate Procedure i would expect that the development board replies with LL_LENGTH_REQ:

Did i misunderstood somethink and is the way how i implemented it correct or is there a better solution available?

Thanks in advace.

BR,

Karl

Parents
  • Hi Karl

    What is the NRF_SDH_BLE_GAP_DATA_LENGTH parameter set to in your sdk_config.h file?

    Best regards
    Torbjørn

  • Hi Torbjørn,

    thanks for your response. NRF_SDH_BLE_GAP_DATA_LENGTH is currently set to 251, so to the maximum value.

    BR,

    Karl

  • Hi Karl

    On second thought I guess it is the NRF_SDH_BLE_GATT_MAX_MTU_SIZE parameter that is too low here, and the peer device is requesting a larger value. 

    Can you show me the code you use to initialize the nrf_ble_gatt module?

    Normally you would tell this module how large MTU you can accept, like in this excerpt from the ble_app_uart example:

    /**@brief Function for initializing the GATT library. */
    void gatt_init(void)
    {
        ret_code_t err_code;
    
        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);
    }
    

    Then the nrf_ble_gatt module should take care of the rest. 

    Best regards
    Torbjørn

  • Hi Torbjørn,

    that is the function that initializes the GATT module:

    /**@brief Function for initializing the GATT module.
     */
    static void gatt_init(void)
    {
    
      ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
      APP_ERROR_CHECK(err_code);
    }
    

    The reason we reduced NRF_SDH_BLE_GATT_MAX_MTU_SIZE to 185 is to save RAM memory.

    Can't you agree on the smaller MTU size with the peer? Not sure, but I think I read somewhere that an MTU size agreement is made based on the smaller MTU size of one of the participants?

    Based on the figure send above i think it should be possible to find an agreement, am i right? 

    Best regards,

    Karl

  • Hi Karl

    It should be possible to negotiate a smaller MTU size, yes, but you need to configure the GATT library with your desired MTU size. 

    Can you try to add the nrf_ble_gatt_att_mtu_periph_set(..) function call, as I showed in my snippet below, to your gatt_init() implementation?

    Best regards
    Torbjørn

Reply Children
No Data
Related