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

ble_gatt: sd_ble_gap_data_length_update() (request) on connection 0x0 returned unexpected value 0x13.

I am trying to understand why my program is returning this error (NRF_ERROR_RESOURCES). I read through a lot of other posts in the devzone and tried replicating them, but they don't seem to be doing the right thing

Error:

00> <info> ble_gatt: Requesting to update data length to 201 on connection 0x0.
00> <error> ble_gatt: sd_ble_gap_data_length_update() (request) on connection 0x0 returned unexpected value 0x13.

I printed out the limitations struct for debugging:
00> <error> ble_gatt: limitation tx_payload_limited_octets: 174
00> <error> ble_gatt: limitation rx_payload_limited_octets: 174
00> <error> ble_gatt: limitation tx_rx_time_limited_us: 0

The update data length is 201 - why is it so high? What can I do to decrease this value?

I read on the forums that NRF_SDH_BLE_GAP_EVENT_LENGTH governs the tx/rx payload size. I increased it from 3 to 6:

// <o> NRF_SDH_BLE_GAP_EVENT_LENGTH - 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 6
#endif
...but the error persists and the tx/rx lpayload_limited_octets remained the same. I tried values 5, 200, 201, 250, 260... no change at all.
I wondered if I was including the wrong sdk_config.h file, but I confirmed I was using the correct one by putting an #error statement in the sdk_config.h file.
I'm using SDK 4.2.0, and softdevice 5.0.0
How can I increase the limit and/or decrease the data length?
Parents
  • As an update, I increased the MTU size, and it stopped crashing.

    // <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 205
    #endif
    But, I'm not sure this is what I want. I don't think I'm sending much data, yet I doubled my time set aside for this connection, and I increased the MTU by a lot, requiring a lot more space to be used. Why is my data length so long?
  • I am not able to reproduce your behaviour. Could you upload your project as a zip?

    Best regards,

    Simon

  • It's hard for me to upload my project... I also am not using any example, and I'm writing in C++, so it might be a lot of stuff to ramp up on.

    I already got past the compilation problem. but I want to know what I can change to decrease the NRF_SDH_BLE_GAP_EVENT_LENGTH. I was digging through the SDK code, but I had to stop at the Softdevice boundary.

    How are the {tx,rx}_payload_limited_octets calculated? I am mainly worried that I set some other parameter incorrectly, leading to some large buffers being allocated.

  • I have been sick lately, and not been able to make any progress on your issue, but I'll look into it the next couple of days.

    Best regards,

    Simon

  • I assume you are using SDK 14.2, I will try to explain how the rx and tx octets are set using that sdk and the example SDK_14.2\examples\ble_central\ble_app_rscs_c\main.c

    • First a struct of type static nrf_ble_gatt_t m_gatt is created 
      • It is done through NRF_BLE_GATT_DEF(..) in main.c
      • The macro NRF_BLE_GATT_DEF() is defined in nrf_ble_gatt.h
      • This struct is also the context to the handler of the GATT observer nrf_ble_gatt_on_ble_evt(..) in nrf_ble_gatt.h/c
      • This struct contains data length fields: nrf_ble_gatt_t.links.data_length_desired/data_length_effective and nrf_ble_gatt_t.data_length
    • A pointer to the mentioned struct is passed in to an init function and the mentioned data length fields are updated
      • main()→gatt_init()→nrf_ble_gatt_init(): 
        • p_gatt→data_length = NRF_SDH_BLE_GATT_MAX_MTU_SIZE + L2CAP_HDR_LEN;
      • main()→gatt_init()→nrf_ble_gatt_init()→link_init(): 
        • p_link->data_length_desired        = NRF_SDH_BLE_GATT_MAX_MTU_SIZE + L2CAP_HDR_LEN;
        • p_link->data_length_effective      = BLE_GATT_ATT_MTU_DEFAULT + L2CAP_HDR_LEN;
    • Then, after a connection, the event BLE_GAP_EVT_CONNECTED happens, and the observer earlier mentioned will get triggered, and the struct mentioned earlier will be brought along as context (redefined to p_gatt)
      • The data length procedure is triggered in the following manner (Starting in nrf_ble_gatt.c):  on_connected_evt(..)→data_length_update(..)→sd_ble_gap_data_length_update()
      • Inside on_connected_evt the following runs: p_link->data_length_desired = p_gatt->data_length
      • Inside data_length_update(..) the rx and tx octets are in the following manner:
        •  ble_gap_data_length_params_t const dlp =
          {
          • .max_rx_octets  = p_gatt->links[conn_handle].data_length_desired,
          • .max_tx_octets  = p_gatt->links[conn_handle].data_length_desired,
          • ....
        • }
      • The struct dlp is then fed into sd_ble_gap_data_length_update(..)

    Hopefully you were able to follow along, and hopefully I was able to explain it to you in a somehow understandable manner.

    Best regards,

    Simon

  • Thanks for the explanation. I changed my MAX MTU back to 23, and my GAP_EVENT_LENGTH back to 3, and I'm not getting errors.

    The important part for me was

    • p_link->data_length_desired        = NRF_SDH_BLE_GATT_MAX_MTU_SIZE + L2CAP_HDR_LEN;
    • p_link->data_length_effective      = BLE_GATT_ATT_MTU_DEFAULT + L2CAP_HDR_LEN;

    After making these two values the same by changing the values in sdk_config.h, no length update was needed at all.

Reply
  • Thanks for the explanation. I changed my MAX MTU back to 23, and my GAP_EVENT_LENGTH back to 3, and I'm not getting errors.

    The important part for me was

    • p_link->data_length_desired        = NRF_SDH_BLE_GATT_MAX_MTU_SIZE + L2CAP_HDR_LEN;
    • p_link->data_length_effective      = BLE_GATT_ATT_MTU_DEFAULT + L2CAP_HDR_LEN;

    After making these two values the same by changing the values in sdk_config.h, no length update was needed at all.

Children
No Data
Related