Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLE Gatt Queue Library with sd_ble_gattc_write NRF_ERROR_RESOURCES

I am running SDK 16.0 on nrf52840. For GATT Writes I am using the BLE Gatt Queue Library. When I try to performing lots of writes in succession some packets do not get transmitted and I have tied it to sd_ble_gattc_write returning NRF_ERROR_RESOURCES and the data not being queued. My question is why does the GATT Queue library not queue up this transmission? The only time it will be queued is if the write attempt returns NRF_ERROR_BUSY. Seems like if NRF_ERROR_RESOURCES is received then it too should be queued. What is the reason for not queuing?

Parents
  • Hi, 

    Please see sd_ble_gattc_write() document: 

    Only one write with response procedure can be ongoing per connection at a time. If the application tries to write with response while another write with response procedure is ongoing, the function call will return NRF_ERROR_BUSY. A BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer. The number of Write without Response that can be queued is configured by ble_gattc_conn_cfg_t::write_cmd_tx_queue_size When the queue is full, the function call will return NRF_ERROR_RESOURCES. A BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete. The application can keep track of the available queue element count for writes without responses by following the procedure below:

    • Store initial queue element count in a variable.
    • Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns NRF_SUCCESS.
    • Increment the variable, which stores the current available queue element count, by the count variable in BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event.

    -Amanda H.

  • Hi, yes I read all of that. I have increased ble_gattc_conn_cfg_t::write_cmd_tx_queue_size to the maximum my ram will allow and I still get NRF_ERROR_RESOURCES. I could keep my own queue for this case but then what is the point of the Gatt Queue? I feel this would be a perfect use of the Gatt Queue. If the Gattc Tx Queue is full then push to Gatt Queue. And then it could handle popping off the data when BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE is received. 

    My question truly is why does it not do this already? What is the rationale? It seems that Gatt Queue only handles a small set of use cases and could be easily expanded, it already handles Write with Response properly, would be easy to handle Write without Response.

  • Yes, my question is why doesn't the Gatt Queue do all of this for me? What is the rationale behind not queuing Write Without Responses when it will queue Write With Response? You are pointing me to all great information but I have read and know all of this.

  • Hi, 

    It seems like NRF_ERROR_RESOURCES error should also trigger the queuing mechanism in the BLE Gatt Queue Library so that Softdevice request could be handled later on when Softdevice is free. You can modify the library code so that this error is also taken into account when queuing data, we will fix it in future releases. 

    -Amanda H.

  • I had try as your suggestion,but i found when i send a packege to slave, there appear five time call back for "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE".

    I don't think "Store initial queue element count in a variable" can work well.

    My chip is 52832,SDK 16.0.0

  • Hi,

    I would suggest that you use either internal Softdevice queue (configurable ble_gattc_conn_cfg_t::write_cmd_tx_queue_size) or BLE Gatt Queue module for GATTC Writes. Actually, the Softdevice queue is a better option because you can track its size at the application level.

    You cannot assess BLE GATT Queue size the same way, because all Softdevice requests use exactly the same queue and the information about it is unavailable. So the algorithm for tracking the BLE GATT queue state cannot be used in this case: "Store initial queue element count in a variable" can work well....".

    You are probably using both queues in your solution (judging from your screenshot). In that case, the SD queue will fill up first and the BLE GATT Queue will be used. That's why you see the disparity between the number of times when the item was added to the BLE GATT queue (only 1 time in your screenshot) and the number of BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE events (5).

    -Amanda H.

  • In my experience the internal SD queue requires a lot of RAM. If you modify nrf_ble_gq.c and add  || err_code == NRF_ERROR_RESOURCES to both places where NRF_ERROR_BUSY is checked then the library should work fine.

Reply
  • In my experience the internal SD queue requires a lot of RAM. If you modify nrf_ble_gq.c and add  || err_code == NRF_ERROR_RESOURCES to both places where NRF_ERROR_BUSY is checked then the library should work fine.

Children
No Data