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!

Parents
  • Hi,

     

    Could you add the preprocessor define "DEBUG" to your project and check the m_error_data variable once an assert occurs?

    This define will add blocking assertions instead of a system-reset.

    You should then be able to read out m_error_data.line_num/p_file_name/err_code to get more detailed information.

    The 0x4001 error indicates that the error comes from the application, and not specifically where it comes from.

    Cheers,

    Håkon

  • Ok, it seems the issue was that security negotiation hadn't been completed before I wrote to the characteristic - in my bench testing I'm getting NRF_ERROR_FORBIDDEN and haven't seen the SDK error again.

    For now I'm working around this by just ignoring this error case - is there a "correct" way to handle this, i.e. should I have more conditions on the if statement that wraps the call to sd_ble_gatts_hvx in my code sample above?

Reply
  • Ok, it seems the issue was that security negotiation hadn't been completed before I wrote to the characteristic - in my bench testing I'm getting NRF_ERROR_FORBIDDEN and haven't seen the SDK error again.

    For now I'm working around this by just ignoring this error case - is there a "correct" way to handle this, i.e. should I have more conditions on the if statement that wraps the call to sd_ble_gatts_hvx in my code sample above?

Children
Related