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

sd_ble_gap_sec_params_reply() returns NRF_ERROR_INVALID_STATE

I have an nRF51822 application using the Soft Device 110. I want to perform bonding with a central without MITM protection. In my on_ble_evt() event handler, when the event ID is BLE_GAP_EVT_SEC_PARAMS_REQUEST, I reply in the same fashion as one of the example apps, like this:

        err_code = sd_ble_gap_sec_params_reply(m_conn_handle,
                                               BLE_GAP_SEC_STATUS_SUCCESS,
                                               &m_sec_params);
        APP_ERROR_CHECK(err_code);

The error_code is then 8, which is NRF_ERROR_INVALID_STATE.

The m_sec_params have earlier been set to these values:

#define SEC_PARAM_TIMEOUT                 30                                                /**< Timeout for Pairing Request or Security Request (in seconds). */
#define SEC_PARAM_BOND                    1                                                 /**< Perform bonding. */
#define SEC_PARAM_MITM                    0                                                 /**< Man In The Middle protection NOT required. */
#define SEC_PARAM_IO_CAPABILITIES         BLE_GAP_IO_CAPS_NONE                              /**< No I/O capabilities. */
#define SEC_PARAM_OOB                     0                                                 /**< Out Of Band data not available. */
#define SEC_PARAM_MIN_KEY_SIZE            7                                                 /**< Minimum encryption key size. */
#define SEC_PARAM_MAX_KEY_SIZE            16                                                /**< Maximum encryption key size. */

m_conn_handle has been set earlier on, when the BLE_GAP_EVT_CONNECTED event comes into the same handler, like this:

        m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;

I also know the connection event has happened, from my logs:

sd_app_evt_wait()
sd_app_evt_wait()
DM_EVT_CONNECTION
BLE_GAP_EVT_CONNECTED
sd_app_evt_wait()
DM_EVT_SECURITY_SETUP
BLE_GAP_EVT_SEC_PARAMS_REQUEST

How can I tell what's invalid about the state I'm in? The central is an Android app and is my code.

  • Hi Eliot,

    It would help if you had a sniffer trace of the transaction.

    What could be the reason is that there is a disconnection event that arrived right after you received the BLE_GAP_EVT_SEC_PARAMS_REQUEST, thus a pending disconnection event in the buffer. This could cause the NRF_ERROR_INVALID_STATE that you are receiving.

    Hope this helps

    [Update 1]

    After looking at the btsnoop log you provided I notice that the pairing procedure have actually started. (In frame 95, and continued until the start of exchanging keys in frame 128) At this point there are 6 packets that have not been exchanged. The EDIV and Rand from the slave, the IRK and Identity Address Information from both slave and master plus the CSRK from the master.

    This tells me that you have successfully replied to at least one BLE_GAP_EVT_SEC_PARAMS_REQUEST, but must have called sd_ble_gap_sec_params_resp one more time. thus it is out of state at that point. I'm not sure why it stops the procedure at that point. But it could be that you have asserted in the event handler, and the chip is only able to keep the link alive. Could you try to add a counter to where you call the sd_ble_gap_sec_params_reply and see how many times you call it?

    The reason you don't have the problem when disabling authentication on the characteristic is that the pairing procedure is never started.

    BR Pål

  • Hi Pal,

    Here's the Wiresdhark output for the moment when the central tries to read a characteristic. That starts at about packet 85 in this file: invalid_state_on_sec_params_request.pcapng.

    However, what might be more relevant is that I've since noticed I get this problem when the characteristic I'm trying to read has been configured with BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(), but not when I've used BLE_GAP_CONN_SEC_MODE_SET_OPEN().

    Cheers,

    Eliot.

    [Update 1]

    Thanks Pal. The only place in my code where I call sd_ble_gap_sec_params_reply() is the on_ble_evt() event handler and I'm fairly sure I'm only calling it once. Here's my whole log output right from the reset:

    ble_advertising_start()
    Advertising to all
    sd_app_evt_wait()
    sd_app_evt_wait()
    DM_EVT_CONNECTION
    BLE_GAP_EVT_CONNECTED
    sd_app_evt_wait()
    sd_app_evt_wait()
    BLE_CONN_PARAMS_EVT_SUCCEEDED
    Bat level update
    sd_app_evt_wait()
    sd_app_evt_wait()
    DM_EVT_SECURITY_SETUP
    BLE_GAP_EVT_SEC_PARAMS_REQUEST
    

    And here's the gdb trace:

    app_error_handler (error_code=8, line_num=410, p_file_name=0x3d550 <_fini+32> "../bike_tracker_ble.c") at ../main.c:100
    100	    for (;;) {}
    (gdb) bt full
    #0  app_error_handler (error_code=8, line_num=410, p_file_name=0x3d550 <_fini+32> "../bike_tracker_ble.c") at ../main.c:100
    No locals.
    #1  0x000180e6 in on_ble_evt (p_ble_evt=0x20002188) at ../bike_tracker_ble.c:410
            LOCAL_ERR_CODE = 8
            err_code = 8
            m_conn_handle = 2083
    #2  0x00018dc0 in ble_evt_dispatch (p_ble_evt=0x20002188) at ../bike_tracker_ble.c:462
    No locals.
    #3  0x00034aac in intern_softdevice_events_execute () at /Users/Eliot/dev/nrf51_sdk_v6_0_0_43681/nrf51822/Source/sd_common/softdevice_handler.c:133
            evt_len = 12
            err_code = 0
            no_more_soc_evts = true
            no_more_ble_evts = false
    #4  0x00034c24 in SWI2_IRQHandler () at /Users/Eliot/dev/nrf51_sdk_v6_0_0_43681/nrf51822/Source/sd_common/softdevice_handler.c:310
    No locals.
    #5  <signal handler called>
    No symbol table info available.
    #6  0x000119ce in ?? ()
    No symbol table info available.
    #7  0x0000116a in ?? ()
    No symbol table info available.
    #8  0x0000116a in ?? ()
    No symbol table info available.
    

    Would it help if I posted my app code in a support case? It's a little bit too much code to post here.

    Which is the best sample app code in the SDK to use as a starting point for an app that uses Just Works bonding with a vendor specific read/write characteristic? I've just noticed the new ble_app_template code handles these BLE events where the proximity app I'd based my code on doesn't:

    BLE_GATTS_EVT_SYS_ATTR_MISSING
    BLE_GAP_EVT_AUTH_STATUS
    BLE_GAP_EVT_SEC_INFO_REQUEST
    

    [Update 2]

    Carles, here's how I'm setting up the handlers:

    // Register with the SoftDevice handler module for BLE events.
    err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
    APP_ERROR_CHECK(err_code);
    

    And here's the dispatcher:

    static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
    {
        dm_ble_evt_handler(p_ble_evt);
        ble_conn_params_on_ble_evt(p_ble_evt);
        ble_ias_on_ble_evt(&m_ias, p_ble_evt);
        ble_lls_on_ble_evt(&m_lls, p_ble_evt);
        ble_bas_on_ble_evt(&m_bas, p_ble_evt);
        ble_bts_on_ble_evt(&m_bts, p_ble_evt);
        on_ble_evt(p_ble_evt);
    }
    

    I never call sd_ble_evt_get() explicitly. Of those functions, only the last two are mine. There is certainly one and only one call to sd_ble_gap_sec_params_reply() in on_ble_evt() and it's certainly when the event is BLE_GAP_EVT_SEC_PARAMS_REQUEST. There are no calls to sd_ble_gap_sec_params_reply() in ble_bts_on_ble_evt(), which is for my custom characteristic.

    What's going on in dm_ble_evt_handler()?

  • Thanks Pål. Have added an update below, where the formatting works better than in a comment.

Related