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 Reply Children
  • Well, I have not been able to successfully get the advertising data to update dynamically. I was originally using the ble_advertising module as my API and tried updating the contents of m_advertising.adv_data between 2 unique structures pointing to different encoding buffers. But any subsequent calls to sd_ble_gap_adv_set_configure(...) resulted in an error code of NRF_ERROR_INVALID_PARAM.

    I then decided to remove all calls to the ble_advertising API and replace it with direct ble_gap calls, and ended up with the exact same error when calling _set_configure(...).

    static uint8_t enc_adv_data_buffer1[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
    static uint8_t enc_adv_data_buffer2[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
    
    
    #define ADV_BUFFERS_USED  	(2)
    static ble_gap_adv_data_t m_gapData[ADV_BUFFERS_USED] = 
    {
    	{ 
    		.adv_data.p_data = enc_adv_data_buffer1,
    		.adv_data.len = sizeof(enc_adv_data_buffer1),
    		.scan_rsp_data.p_data = NULL,
    		.scan_rsp_data.len = 0
    	},
    	{ 
    		.adv_data.p_data = enc_adv_data_buffer2,
    		.adv_data.len = sizeof(enc_adv_data_buffer2),
    		.scan_rsp_data.p_data = NULL,
    		.scan_rsp_data.len = 0
    	},
    };
    
    void updateAdvertisingData(void)
    {
        static uint8_t uiBuffIndex = 0;
        
    	// Encode the advertising packet to the other buffer
    	errCode = ble_advdata_encode( &advData, m_gapData[ uiBuffIndex ].adv_data.p_data, (uint16_t *)&m_gapData[ uiBuffIndex ].adv_data.len );
    	APP_ERROR_CHECK(errCode);
    	
    	errCode = sd_ble_gap_adv_set_configure(&m_advHandle, &m_gapData[ uiBuffIndex ], NULL);
    	APP_ERROR_CHECK( errCode );
    		
    	if( errCode == NRF_SUCCESS )
    	{
    		uiBuffIndex++;
    		uiBuffIndex = uiBuffIndex % ADV_BUFFERS_USED;
    	}
    }
    

    The function updateAdvertisingData() is called periodically to update the advertising data.

    None of the examples update data dynamically, so I am not sure if this sequence is exactly what is expected.

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

Related