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

Can you not call sd_ble_gatts_hvx() in a loop?

I basically need clarification on the last point of this question, which seems to imply that: the first time you call sd_ble_gatts_hvx() while the SoftDevice's transmit buffer is full, it reliably returns NRF_ERROR_RESOURCES, but you should not call it in a loop that checks for NRF_SUCCESS. You must wait for BLE_GATTS_EVT_HVN_TX_COMPLETE. Is this correct?

If so, why? Wouldn't that imply that there is a race condition in the SoftDevice, i.e. the possibility that the application could call sd_ble_gatts_hvx() at just the wrong time, which is what the loop forces?

Indeed, I'm looking into this because I think the SoftDevice was sending some packets in an unexpected order because I was being lazy and using a loop instead of an event handler. If the race condition exists, then I need to spend the time to make sure that the peer is robust to receiving packets out of order.

  • Hi,

    The number of Handle Value Notifications that can be queued is configured by ble_gatts_conn_cfg_t::hvn_tx_queue_size. When the queue is full, the function sd_ble_gatts_hvx() will return NRF_ERROR_RESOURCES. A BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete.

    You have 2 options, either call sd_ble_gatts_hvx() in a loop until the function returns NRF_SUCCESS, or wait for the BLE_GATTS_EVT_HVN_TX_COMPLETE and then send the next packet. There is no race condition here.

  • I'm having a different problem with the same piece of code now: is there any reason that calling sd_ble_gatts_hvx() in a loop would prevent transmission? Usually, it works, but there's one scenario in my application where the loop consistently gets stuck with sd_ble_gatts_hvx returning NRF_ERROR_RESOURCES. It looks like a transmission event never happens because I never see the last successful sd_ble_gatts_hvx packet at the peer, and this causes that loop to repeat indefinitely.

    I think the unique thing about the scenario is that it's the first time I'm trying two sd_ble_gatts_hvx loops within the same event handler, rather than looping until one packet is queued and then returning control to the SoftDevice before I try another loop.

  • Does it work fine when you only use 1 sd_ble_gatts_hvx in the event handler? How big it your hvn_tx_queue_size ?

Related