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

Issue with sd_ble_gap_disconnect

Hello everybody

I hit another issue with sd_ble_gap_disconnect.

The short story is this one. I want the peripheral to initiate a disconnect if no activity for a predefined interval. At this moment, for test purpose only, i just implemented a timer which triggers sd_ble_gap_disconnect 5sec after the connect event. So i have my application running on a 52810 board. I use nrfConnect to connect to the device and the device triggers disconnect 5 sec after. After disconnect event i reconnect manually again to the device in nrfConnect. The log captured in the console shows like this

[00:00:00.000,000] <info> app_timer: RTC: initialized.
[00:00:00.000,000] <info> app: Ble tutorial started.
[00:00:00.000,000] <info> app: on adv_evt - evt = 3
[00:00:00.000,000] <info> app: Fast advertising.
[00:00:00.000,000] <info> app: Connected to a previously bonded device.
[00:00:00.000,000] <info> app: BLE event received. Event type = 16

[00:00:00.000,000] <info> app: Connected.
[00:00:00.454,162] <info> app: BLE event received. Event type = 18

[00:00:00.717,834] <info> app: BLE event received. Event type = 18

[00:00:04.967,285] <info> app: on adv_evt - evt = 3
[00:00:04.967,285] <info> app: Fast advertising.
[00:00:04.967,285] <info> app: BLE event received. Event type = 17

[00:00:04.967,346] <info> app: Disconnected.
[00:00:04.967,346] <info> app: Connected to a previously bonded device.
[00:00:04.967,346] <info> app: BLE event received. Event type = 16

[00:00:04.967,346] <info> app: Connected.
[00:00:05.447,326] <info> app: BLE event received. Event type = 18

[00:00:05.714,721] <info> app: BLE event received. Event type = 18

[00:00:09.967,346] <error> app: ERROR 8 [NRF_ERROR_INVALID_STATE] at C:\dev\52810\nRF5_SDK_17.0.2_d674dde\examples\ble_peripheral\ble_app_empty\main.c:338
PC at: 0x0001F429
[00:00:09.982,727] <error> app: End of error report

As you can see there is a first Disconnect event but the second one is missing because the device crashes and it shows the error report with error code = 8 which is invalid parameters

Digging further, the crash happens in in send_update_request when calling sd_ble_gap_conn_param_update because the second parameter p_new_conn_params is totaly invalid. Soething happen when pushet to the stack. SP = 20005f40 which is reasonable

In caller function update_timeout_handler the p_instance variable has valid values, but somehow when calling send_update_request the address is changed from 20002d8c+8 (how it is shown in update_timeout_handler) to 3ff00000 and this wrong value is pushed on the stack

Here is the call stack (hope you can access the link)

the way i call sd_ble_gap_disconnect is this one:

  - i instantiated a timer in main with time_ms = 5000 

 

const nrf_drv_timer_t INACTIVITYTIMER = NRF_DRV_TIMER_INSTANCE(1);
...
nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
err_code = nrf_drv_timer_init(&INACTIVITYTIMER, &timer_cfg, inactivity_timer_evt_handler);
...
time_ticks = nrf_drv_timer_ms_to_ticks(&INACTIVITYTIMER, time_ms);
nrf_drv_timer_extended_compare(&INACTIVITYTIMER, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);

In ble_evt_handler on connect/disconnect events i start/stop the timer

 switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_DISCONNECTED:
            NRF_LOG_INFO("Disconnected.");
            err_code = bsp_indication_set(BSP_INDICATE_DISCONNECTED);
            APP_ERROR_CHECK(err_code);
            nrf_drv_timer_disable(&INACTIVITYTIMER);
            board_state = DISCONNECTED;
            break;

        case BLE_GAP_EVT_CONNECTED:
            NRF_LOG_INFO("Connected.");
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
            err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
            APP_ERROR_CHECK(err_code);
            nrf_drv_timer_enable(&INACTIVITYTIMER);
            board_state = CONNECTED;
            break;

And finally in the timer callback, sd_ble_gap_disconnect is invoked

 switch (event_type)
    {
    case NRF_TIMER_EVENT_COMPARE0:
      if (board_state == CONNECTED && m_conn_handle != BLE_CONN_HANDLE_INVALID)
        {
        sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
        }

The environment i use is segger studio and sdk 17.02

The issue happens randomly after 2 to 20 manual reconnects

What am i doing wrong?Frowning2

Parents
  • It looks awneil is right. Its about NRF_ERROR_INVALID_STATE.

    send_update_request is calling sd_ble_gap_conn_param_update and the error is returned by the last one.

    According to the documentation the return value of sd_ble_gap_conn_param_update 

    NRF_ERROR_INVALID_STATE Disconnection in progress or link has not been established.

    My guess now is that i am in the situation i send a disconnect when 52810 is already disconnected but disconnect event is not yet processed. 

    Will dig further

  • After further digging i have a theory.

    I trigger the disconnect from my timer handler which has a timeout value of 5sec

    The soft device performs a sd_ble_gap_conn_param_update from inside another timer (app timer) which has a timeout value of 5sec as it is set in my app

    #define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)

    Now between the trigger of disconnect and soft device entering disconnected state some time interval is needed.

    If inside this time interval app_timer triggers sd_ble_gap_conn_param_update then this function will return an invalid state because the disconnect process is in progress.

    Here is a log supporting this theory. I put a long info in my timer handler: “disconnect triggered” and another log info in send_update_request just before sd_ble_gap_conn_param_update

    >>>> success case: disconnect happens before sd_ble_gap_conn_param_update

    [00:00:04.996,459] <info> app: Connected.

    [00:00:09.913,818] <info> app: disconnect triggered

    [00:00:09.992,248] <info> app: Disconnected.

     

    >>>> success case: disconnect happens before sd_ble_gap_conn_param_update

    [00:00:09.992,309] <info> app: Connected.

    [00:00:14.909,973] <info> app: disconnect triggered

    [00:00:14.964,782] <info> app: Disconnected.

     

    >>>> failure case: sd_ble_gap_conn_param_update is triggered before disconnect complete

    [00:00:14.964,782] <info> app: Connected.

    [00:00:19.883,544] <info> app: disconnect triggered

    [00:00:19.964,782] <info> app: send_update_request

    [00:00:19.969,482] <error> app: ERROR 8 [NRF_ERROR_INVALID_STATE] at C:\dev\52810\nRF5_SDK_17.0.2_d674dde\examples\ble_peripheral\ble_app_empty\main.c:339 PC at: 0x0001F429

    [00:00:19.984,863] <error> app: End of error report

    The bad luck was that both timeouts have the same value

    I need Nordic if possible to confirm this theory and suggest a way to avoid this issue.

    In my case disconnect is triggered by app and I can handle the invalid state return because I know the state of the app.

    But this issue might happen also when disconnect is triggered by the remote device if it is triggered at some time close to   FIRST_CONN_PARAMS_UPDATE_DELAY 

  • Hi Hung

    Take the second usecase in my previous post.

    sd_ble_gap_conn_param_update on nrf52810 device returns NRF_ERROR_INVALID_STATE.

    At this point i dont know if it is because a disconnect received over the air is in progress, so i can ignore it, or it is because some other reason, so i need to take some actions.

    Then again the question if sd_ble_gap_conn_param_update can return other than invalid state error in case a disconnect is in progress

  • .. or there is an other API which i can use to interrogate the status of the SD

  • Hi Viorel, 
    There are only two options that the function would return INVALID_STATE: Disconnection in progress or link has not been established.

    In both case it wouldn't cause any consequence to the softdevice. You can safely ignore that. 

  • Great and thanks!

    I think this case can be closed now Clap

  • I think this case can be closed now

    You do that by marking the solution:

Reply Children
No Data
Related