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 ?

Parents
  • 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

Reply
  • 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

Children
  • 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.

  • I think that when you switch buffers, at some point, you'll get a BLE_GAP_EVT_ADV_SET_TERMINATED event to notify you when the previous buffer was released. Until then, you cant reuse that buffer. And if you are switching buffers yourself, its probably not going to work well with ble_advertising : when it transitions from fast to slow (or any transition), it will revert to using its buffers and not yours, so it will advertise old data at the new rate. 

  • Hmm... that would be great if it did. I have not noticed that.. but maybe I was not looking for it and just didn't notice. I will try to verify that soon, but currently I'm working on getting the bootloader working.

  • I did verify that I am not seeing the BLE_GAP_EVT_ADV_SET_TERMINATED event after updating my advertising data/buffers. I let it run and update about 10 times without seeing the event in my NRF_SDH_BLE_OBSERVER callback function.

  • According to this  link -  The data shall be kept alive until either: ... Advertising data is changed. So, after calling sd_ble_gap_adv_set_configure with p_adv_params = null, the buffer should be released. But it seems that is not what you are observing and you have occasional errors. 

Related