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

S110 - ble_advertising_on_ble_evt always starts advertising on intentional disconnect

I would like to be able to manually disconnect from a device and then begin advertising.

However, I have discovered that on disconnect, ble_advertising_on_ble_evt handler restarts the (direct) advertising process to reconnect to a previously started device (assuming due to loss of connection). This leads to my start advertising call to return a INVALID_STATE error (already advertising).

Now, if I am intentionally disconnecting with the HCI code BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION or BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION then surely ble_advertising_on_ble_evt should check for this, see that the disconnect was intentional and that no reconnect is needed and, therefore, not start direct advertising? This would allow me to start my own advertising at will.

Currently, I'm having to stop this advertising (if I initiated disconnect) and start my own.

  • Hi,

    No, ble_advertising_on_ble_evt does not check what was the disconnect reason before initiating advertising. It will start directed advertising if this was enabled on init. The advertising module is supposed to cover the common case, but extended functionality is not included. It is lightweight by design, but more features can be built on top of it if need be.

    For instance you can make your own handler for the cases where you need different behaviour than that of ble_advertising_on_ble_evt(). Then you can call ble_advertising_on_ble_evt() from your own handler for the cases that do not require special handling. In the case of BLE_GAP_EVT_DISCONNECTED events this should be a safe approach, at least with the current SDK (SDK 10.0.0). I have drafted one such solution here:

    // My own advertising BLE event handler, for changes in disconnect event handling.
    void my_improved_ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt)
    {
        switch (p_ble_evt->header.evt_id)
        {
            // Special handling is needed for some disconnects
            case BLE_GAP_EVT_DISCONNECTED:
                // We consider the following disconnects intentional (do not start directed advertising)
                if (p_ble_evt->evt.gap_evt.params.disconnected.reason == BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION
                  || p_ble_evt->evt.gap_evt.params.disconnected.reason == BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION))
                {
                    // Start regular advertising (i.e. skip directed)
                    uint32_t err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
                    if (err_code != NRF_SUCCESS)
                    {
                        APP_ERROR_CHECK(err_code);
                    }
                }
                // Let the advertising module handle all other disconnects
                else
                {
                    ble_advertising_on_ble_evt(p_ble_evt);
                }
                break;
    
            // Let the advertising module handle all other events
            default:
                ble_advertising_on_ble_evt(p_ble_evt);
                break;
        }
    }
    

    In other cases you may have to modify the SDK itself to get the desired functionality, in particular if there is internal bookkeeping involved that could potentially break the advertising module or put it in an invalid state. Do also note that the advertising module may change in future releases of the SDK, so that your event handler has to be reviewed and updated if you port your project to a newer SDK.

    Regards, Terje

Related