We have an nRF52840 operating as BLE peripheral that ix using sd_ble_gatts_hvx() to notify an attribute value. Because we are using an RTOS, after calling sd_ble_gatts_hvx() our function then makes a blocking RTOS call to wait on an RTOS event, which is set when we receive BLE_GATTS_EVT_HVN_TX_COMPLETE. In the case where sd_ble_gatts_hvx() returns NRFX_ERROR_INVALID_STATE — which can occur if a BLE disconnect or disable occurs in parallel with the thread that's calling sd_ble_gatts_hvx() -- our function gracefully exits with an error, but all other errors we've been treating as serious errors that represent something fundamentally with our code or system.
However, in testing we've run across two other unexpected return values from sd_ble_gatts_hvx(). We'd like to understand what could be causing these errors.
1) We've run into a case where sd_ble_gatts_hvx() returns NRF_SUCCESS but on exit the uint32_t pointed to by the p_len field of the ble_gatts_hvx_params_t struct we pass contains zero instead of the byte count we actually requested to notify. This occurred in a case where we were testing rapid BLE connections and disconnections while shifting a device quickly in and out of range to test the reliability of reconnections. Two questions about this:
- What does this mean if it happens? Why aren't we getting an error return code if the SoftDevice indicates that no data was sent?
- If this occurs, will we still get a BLE_GATTS_EVT_HVN_TX_COMPLETE event notification following the sd_ble_gatts_hvx() call?
2) We've run into a case where sd_ble_gatts_hvx() returns NRF_ERROR_RESOURCES. We understand that this means that all the BLE buffers in the SoftDevice are full. But we're confused about why this is occurring, since we only call sd_ble_gatts_hvx() from this single function, we always wait for an BLE_GATTS_EVT_HVN_TX_COMPLETE event before exiting the function after sd_ble_gatts_hvx() is called, and the function is protected by a mutex, so we don't think our code should be using more than one BLE buffer for transmit at a time. Two questions about this:
- We understand that we can modify the number of TX queue elements used by the SoftDevice by calling sd_ble_cfg_set(), but can you help us understand -- given how we're using sd_ble_gatts_hvx() -- why we'd be getting an NRF_ERROR_RESOURCES result?
- We do have a timeout while waiting on the RTOS event being set by BLE_GATTS_EVT_HVN_TX_COMPLETE, which is currently set to 2 seconds. Is there an upper bounds to how long after sd_ble_gatts_hvx() is called the BLE_GATTS_EVT_HVN_TX_COMPLETE may be sent? Or to put it another way, does sd_ble_gatts_hvx() ever time out and, if so, how long does that take?