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

Check if currently advertising

In my application, a host co-processor controls when to start/stop advertising, connect etc.
I've noticed that soft-device command are state-dependent, e.g. calling ble_advertising_start() while advertising, or calling sd_ble_gap_adv_stop() while not, causes an SD assert which by default soft-resets the device (related question here).

How should I mitigate this? Do I have to keep track of the stack's state (Advertising, Connected, Scanning, etc.), or, better yet, are there API methods to check the state of the stack before issuing a command?

Version: nRF5 SDK 11.0.0, s132, with PCA10040 EVB

Parents
  • Hi,

    First I want to mention that it is not the SD that asserts. It simply returns an error code. The APP_ERROR_CHECK macro is the one that will reset the device, unless you choose to handle it in a different way. You can call any API functions with any parameter, at any time, and as long as you do not lie about the length of any buffers you provide, the SD shall never assert or crash. The functions will return an error code stating what happened.

    And for your question, you are right in your assumption that you have to remember the state in your application. If sd_ble_gap_adv_start() returns NRF_SUCCESS, the device will advertise until

    1. BLE_GAP_EVT_CONNECTED event is received, i.e. a connection is made (in the case of connectable advertisement). If you are trying to use the central to connect at the same time, you need to check the role flag of the connection. If BLE_GAP_ROLE_PERIPH, you are no longer advertising.

    2. BLE_GAP_EVT_TIMEOUT event is received (in the case where you set a timeout, or use high duty-cycle directed advertisements) and the src field is BLE_GAP_TIMEOUT_SRC_ADVERTISING.

    3. sd_ble_gap_adv_stop() has been called.

    There are no commands to check the current state, and it would be prone to race conditions if we had one. Instead, our stack relies on application events to tell you when the internal state changes.

  • If the advertising stops, and you have not yet pulled the event stating this, then I think you should be safe. I'm not 100% sure on the internals, but as far as I know, all states are "pending" until you pull them with sd_ble_evt_get(). From then on, the stack assumes that you have dealt with the consequences of the event.

    I'm not well-wersed in the current SDK, so someone should correct me - but I think the correct way is to simply make an

    if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)
    {
        APP_ERROR_CHECK(err_code);
    }
    
Reply
  • If the advertising stops, and you have not yet pulled the event stating this, then I think you should be safe. I'm not 100% sure on the internals, but as far as I know, all states are "pending" until you pull them with sd_ble_evt_get(). From then on, the stack assumes that you have dealt with the consequences of the event.

    I'm not well-wersed in the current SDK, so someone should correct me - but I think the correct way is to simply make an

    if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)
    {
        APP_ERROR_CHECK(err_code);
    }
    
Children
No Data
Related