Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Switching advertising type

I have seen that the recommended method for switching between connectable and non-connectable advertising is:

    sd_ble_gap_adv_stop()
    ...change advertising structures as needed...
    sd_ble_gap_adv_start()

My app is doing this, and it works. But using sd_ble_gap_adv_start() instead of ble_advertising_start() causes my app to no longer get events to on_adv_evt(). When I try to change to using ble_advertising_start() instead, I get crashes on restarting (works fine starting the first time).

So is there a way to switch between connectable and non-connectable advertising while still getting advertising events?

  • Hello,

    Your approach seems correct. Stop advertising, run another advertising_init() function where you change your advertising parameters, and start advertising again.

     

    When your project crashes, it might be that a function call, returning an err_code != NRF_SUCCESS is passed onto an APP_ERROR_CHECK(err_code), which will reboot your application. Can you try to define "DEBUG" in your preprocessor defines, turn off optimization, and try to set a breakpoint inside app_error_handler(...) on line 65 approximately (depending on what SDK version you use), and see if you can find the .line_num, .p_file_name and .err_code that caused the error. What function call returned the err_code, and what was the err_code?

     

    Best regards,

    Edvin

  • I'm using SDK 14.2. Here's a gdb stack trace (I have APP_ERROR_CHECK raise a breakpoint):

    #0 app_error_handler_bare (err_code=18) at /home/lee/work/argos/lib/nrf/sys_nrf.c:372
    #1 0x0002a20c in advertising_start (this=0x200043f8 <_ble_object>) at /home/lee/work/argos/lib/nrf/ble_nrf.c:165
    #2 0x0002a288 in on_connect (this=0x200043f8 <_ble_object>) at /home/lee/work/argos/lib/nrf/ble_nrf.c:185
    #3 0x0002a476 in ble_evt_handler (pevt=0x2000fd88, context=0x200043f8 <_ble_object>) at /home/lee/work/argos/lib/nrf/ble_nrf.c:208
    #4 0x000271d2 in nrf_sdh_ble_evts_poll (p_context=0x0) at /opt/Nordic/SDK14.2/components/softdevice/common/nrf_sdh_ble.c:285
    #5 0x000277d4 in nrf_sdh_evts_poll () at /opt/Nordic/SDK14.2/components/softdevice/common/nrf_sdh.c:378

    So it is ble_advertising_start() itself that's returning error 0x12 (NRF_ERROR_CONN_COUNT ?).

    Perhaps it would be better to run my on_connect() handler with the scheduler?

  • Ok,

    It looks like sd_ble_gap_adv_start(...) (in ble_advertising.c) returns 0x12 = NRF_ERROR_CONN_COUNT, yes.

    You can see the different return values for this function here.

     

    Are you in a connection when you stop and restart the advertising? The return value for this function says:

    NRF_ERROR_CONN_COUNT: The limit of available connections has been reached; connectable advertiser cannot be started.

    Best regards,

    Edvin

  • Yes, I'm connected, because I do this inside the reply to BLE_GAP_EVT_CONNECTED. I stop advertising, then I change all the settings in m_adv_params to the non-connectable settings (including setting type to BLE_GAP_ADV_TYPE_NONCONN_IND), then restart advertising. That could well be the core of the issue--ble_advertising_start() takes the same ble_advertising_t structure as _init(), and that structure doesn't seem to have any place for the advertising parameters that would set non-connectable type.

  • Hello,

    Can you try the solution from this post?

    I managed to run sd_ble_gap_adv_start(&adv_params, NULL)     (note that the second input is ignored when you use BLE_GAP_ADV_TYPE_ADV_NONCONN_IND)

     

    I tried the following:

    ret_code_t non_conn_advertising(void)
    {
        NRF_LOG_INFO("non_conn_advertising()");
        ret_code_t err_code;
        
        ble_gap_adv_params_t adv_params;
        memset(&adv_params, 0, sizeof(adv_params));
        adv_params.type         = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;
        adv_params.p_peer_addr  = NULL;
        adv_params.fp           = BLE_GAP_ADV_FP_ANY;
        adv_params.interval     = NON_CONNECTABLE_ADV_INTERVAL;
        adv_params.timeout      = NON_CONNECTABLE_ADV_TIMEOUT;
        
        err_code = sd_ble_gap_adv_start(&adv_params, NULL);
        NRF_LOG_INFO("err_code = %d", err_code);
        APP_ERROR_CHECK(err_code);
        
        return NRF_SUCCESS;
    }

     

    And then I added err_code = non_conn_advertising(); within the BLE_GAP_EVT_CONNECTED event in ble_evt_handler(...)

     

    I have not tried to sniff the advertising yet, but I saw that I could still find the device from nRF Connect for desktop while I was connected with my phone. (The rssi was still changing, but of course, I could not connect to it).

     

    Also note that NON_CONNECTABLE_ADV_INTERVAL must be larger than 160 (=100ms in units of 0.625).

     

    Best regards,

    Edvin

     

Related