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

Dynamically updating Advertising data in SDK 15

(side note : it would have been handy if the migration guide mentioned that the advertising timeout configs have changed from seconds to 10's of ms)

It seems to have become harder to dynamically update the advertising packet in SDK15. In SDK14, using ble_advertising, I could just update the manufacturer data used by my instance of ble_advertising_t and call ble_advdata_set and be done. Then whenever ble_advertising did something later, it would continue with the latest data (eg auto restart advertising, change speed etc). Advertising would not be restarted and if you use fast and slow advertising, then that timing and transition would not be affected if you changed the manufacturer data.

Now, we need to use sd_ble_gap_adv_set_configure instead of ble_advdata_set, but the new call wont allow changing the encoded data contents and using the same buffer. You need to provide a new buffer if its busy advertising. Providing a new long lived buffer for each update causes many other issues. One way to deal with this is to stop and restart advertising with the same but updated buffer. But that affects the fast to slow advertising timing and transitions : say you update the data every 1 minute, and your fast advertising goes slow after 2 minutes, then you'll always be in fast mode.

Is there an easy and minimally impactful way to update just the manufacturer data in SDK15 ?

  • Did you previously start advertising using sd_ble_gap_adv_set_configure with a non null parameter, and only then call updateAdvertisingData while actively advertising ? 

    Even if this works, and you go back to using ble_advertising, every time there is a transition (fast->slow, stop->start etc), ble_advertising goes back to using its own adv_data which is probably not pointing to your recent encoded buffer, and so you'll be advertising old data until your next call to updateAdvertisingData.

    What has worked for me is to stop advertising, encode and then restart. Not great as it messes up fast/slow advertising periods. 

  • (side note : it would have been handy if the migration guide mentioned that the advertising timeout configs have changed from seconds to 10's of ms)

    Good point. I think this is missing from the documentation and migration guide as well.

  • There is mention of this in the s140 v6.0.0 migration document under the 'Configuring advertising parameters for an advertising set' section.

    "ble_gap_adv_params_t::timeout has been renamed ble_gap_adv_params_t::duration and is now measured in 10 ms units."

  • I have been working on this with SDK13.   

    We want to advertise sensor data using the nRF52840 so I need to use SDK15.  

    I have been trying what you suggested and here is what works for me.

    I set the advertising interval to the same as my update interval.

    then in the timer function I call advertisement_update()

    #define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(2000, UNIT_0_625_MS) 
    APP_TIMER_DEF(m_update_timer_id);
    #define UPDATE_TIMER_INTERVAL			APP_TIMER_TICKS(2000)
    
    void update_timer_handler(void * p_context){
    	
    
    
    	NRF_LOG_INFO("timer handler\r\n");
     
    	advertisement_update();
    	
    	
    }
    
    uint8_t sensor_data = 0;
    
    
    static void advertisement_update(void){
     ret_code_t err_code = sd_ble_gap_adv_stop(m_adv_handle);
      raw_adv_data_buffer1[7] = 0x23;
      raw_adv_data_buffer1[8] = sensor_data;
      ++ sensor_data;
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &adv_data1, &m_adv_params);
        APP_ERROR_CHECK(err_code);
         err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
        APP_ERROR_CHECK(err_code);
      }
    

    If you need more code I can clean up what I am working with and post the whole thing.  But that would be In a day or two

  • I would rather not have to do stop and start because I would like to make sure the fast advertising timeout does not get reset. My advertisement data is updated roughly every 5 seconds and I have a fast adv. timeout of 60 seconds. The framework my company uses was designed around SDK 12.1 and integrates nicely with the fact that the advertising data could easily be updated on-the-fly.

    I have something that does work... most of the time. I have adapted the solution I was having trouble with earlier by adding 3 buffers to cycle through. Occasionally I get an assert. All I can assume is that I must be pointing to a buffer that is currently in use and somehow my logic for advancing to the next buffer is error prone. One hypothesis I have is that I may be calling it too quickly and I advance to the in-use buffer before it had a chance to update to the last buffer requested. I have not had the time to dig into the exact issue here though.

Related