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

Another peer manager race condition in SDK 14.2?

I recently experienced an issue with a race condition between peer manager and FDS in SDK 14.2 which was resolved under this case:

https://devzone.nordicsemi.com/f/nordic-q-a/29926/bug-in-peer-manager-in-sdk-14-2

However, I think I may have now found another one!

My application is a datalogger. It samples a sensor at 1 minute intervals using a timer and writes the value to a BLE characteristic using sd_ble_gatts_hvx(). The problem is that occasionally when the characteristic is written the system is crashing with a 0x4001 error (NRF_FAULT_ID_SDK_ERROR).

I have added some logging and found that this is happening when the timer event for logging the sensor reading (which also calls sd_ble_gatts_hvx if there is a central connected) is triggered just after the BLE connection comes up:

 app: BLE_ADV_EVT_FAST
 app: Power saving
 app: Connected to a previously bonded device.
 app: Connected
 app: Connection secured. Role: 1. conn_handle: 0x0, Procedure: 0
 app: PHY update request.
 ble_gatt: Peer on connection 0x0 requested a data length of 251 bytes.
 0x0.
 293 bytes.
app: sending sensor value
[[[[[ APP CRASHES HERE WITH 0x4001 ERROR ]]]]]

This looks like another race condition to me - my guess is the SDK has not finished negotiating the peer connection before the BLE characteristic is written, and this is the cause of the SDK error.

What is the correct way to deal with this? I do check for a valid connection handle before writing to the characteristic, but that doesn't seem to be enough:

    if(p_datalogger->conn_handle != BLE_CONN_HANDLE_INVALID) {

        hvx_len = 4;

        memset(&hvx_params, 0, sizeof(hvx_params));

        hvx_params.handle = p_datalogger->char_handles.pulse.value_handle;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset = 0;
        hvx_params.p_len  = &hvx_len;
        hvx_params.p_data = encoded_meas;

        err_code = sd_ble_gatts_hvx(p_datalogger->conn_handle, &hvx_params);
    } 

I guess I could just ignore the SDK error, but that doesn't feel very safe....

Any help gratefully received!

Related