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

Updating advertising data (manuf. spec. data) in SDK15

Hello guys! And girls Slight smile

My project is working as expected in SDK14.2.
I'm updating adv data (manuf. spec. data) without any problem with this function

static void advertising_data_update(uint8_t adv_manuf_byte)
{
		ret_code_t err_code;

		ble_advertising_init_t 		init;
		ble_advdata_manuf_data_t 	adv_manuf_data;
		uint8_array_t            	adv_manuf_data_array;
		uint8_t                  	adv_manuf_data_data[1];
		adv_manuf_data_data[0] 		= adv_manuf_byte;

		memset(&init, 0, sizeof(init));

		init.advdata.name_type          		 = BLE_ADVDATA_FULL_NAME;
		init.advdata.include_appearance 		 = false;
		init.advdata.flags              		 = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
		init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
		init.advdata.uuids_complete.p_uuids  = m_adv_uuids;

		adv_manuf_data_array.p_data 							 = adv_manuf_data_data;
		adv_manuf_data_array.size 								 = sizeof(adv_manuf_data_data);
		adv_manuf_data.company_identifier 				 = APP_COMPANY_IDENTIFIER;
		adv_manuf_data.data 											 = adv_manuf_data_array;
		init.advdata.p_manuf_specific_data 				 = &adv_manuf_data;

		init.config.ble_adv_whitelist_enabled      = true;
		init.config.ble_adv_directed_enabled       = true;
		init.config.ble_adv_directed_slow_enabled  = false;
		init.config.ble_adv_directed_slow_interval = 0;
		init.config.ble_adv_directed_slow_timeout  = 0;
		init.config.ble_adv_fast_enabled  				 = true;
		init.config.ble_adv_fast_interval 				 = APP_ADV_INTERVAL;
		init.config.ble_adv_fast_timeout  				 = APP_ADV_TIMEOUT_IN_SECONDS;
							
		err_code = ble_advdata_set(&init.advdata, NULL);
		APP_ERROR_CHECK(err_code);	   
}


But in SDK15 the function ble_advdata_set() has been deprecated.
The migration guide is says to use ble_advdata_encode() and sd_ble_gap_adv_set_configure() instead.

So I changed it to something like this

static void advertising_data_update(uint8_t adv_manuf_byte)
{
		ret_code_t err_code;

		ble_advertising_init_t 		init;
		ble_advdata_manuf_data_t 	adv_manuf_data;
		uint8_array_t            	adv_manuf_data_array;
		adv_manuf_data_data[0] 		= adv_manuf_byte;

		memset(&init, 0, sizeof(init));

    init.advdata.name_type          		 = BLE_ADVDATA_FULL_NAME;
    init.advdata.include_appearance 		 = false;
    init.advdata.flags              		 = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
			
		adv_manuf_data_array.p_data 							 = adv_manuf_data_data;
		adv_manuf_data_array.size 								 = sizeof(adv_manuf_data_data);
		adv_manuf_data.company_identifier 				 = APP_COMPANY_IDENTIFIER;
		adv_manuf_data.data 											 = adv_manuf_data_array;
		init.advdata.p_manuf_specific_data 				 = &adv_manuf_data;

    init.config.ble_adv_whitelist_enabled      			= true;
		init.config.ble_adv_directed_high_duty_enabled 	= true;
    init.config.ble_adv_directed_enabled       			= false;
    init.config.ble_adv_fast_enabled  				 			= true;
    init.config.ble_adv_fast_interval 				 			= APP_ADV_INTERVAL;
    init.config.ble_adv_fast_timeout  				 			= APP_ADV_FAST_DURATION;

		//err_code = sd_ble_gap_adv_stop(m_advertising.adv_handle);
		//APP_ERROR_CHECK(err_code);
			
		err_code = ble_advdata_encode(&init.advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);	
		APP_ERROR_CHECK(err_code);

		err_code = sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, NULL);
		APP_ERROR_CHECK(err_code);
		
		//err_code = sd_ble_gap_adv_start(m_advertising.adv_handle, APP_BLE_CONN_CFG_TAG);
		//APP_ERROR_CHECK(err_code);
}


And of course... it's not working. :)
I'm getting a very strange error at sd_ble_gap_adv_set_configure() --> app: ERROR 12801 [Unknown error code]

Any idea why?
What I'm doing wrong?
What I have to change to get this working like in the SDK14.2?

  • Then you've got to change the advertisement data in m_advertising in main.c because this is the fallback advertising data for the advertising module, who restarts advertisements on a BLE_GAP_EVT_DISCONNECT. 

  • Can you please tell me or better, show me in my code, how to do it?

  • Hi,

    I will try to clear up any misunderstandings here.

    There are mainly two ways to control the advertising data. The first one is to go directly, using the SoftDevice call sd_ble_gap_adv_set_configure(). This is what you do to change advertising data on the fly, as you have already successfully implemented.

    The second way to control advertising data is through the advertising module. The way that it works, is that you provide advertising data when initializing the advertising module with ble_advertising_init(). That piece of advertising data is stored by the advertising module, and it will automatically use that same data whenever it starts advertising. In other words: The advertising module calls sd_ble_gap_adv_set_configure() on its own, with the data that it was given during initialization. (To find all the places it does that you can search for ble_advertising_start in your project. It is multiple places, three of them is in event handling inside the advertising module itself.)

    The easy way to not getting erroneous data is to initialize the advertising module to not send manufacturer specific data at all. That way all the manufacturer specific data (if present in the advertising packet) is controlled in the first way described above. This is safe as long as the device receiving the packets can handle advertising packets without manufacturer specific data. (If you use other advertising types for the changing data then you do the same for them instead, i.e. do not include it for the advertising initialization.)

    The hard way is to change the advertising data stored by the advertising module, whenever that is needed. For that you can have a look at advertising_init() and the call to ble_advertising_init(). In example code, the first argument to ble_advertising_init() is usually &m_advertising. This is where the advertising module will save state information such as the advertising data. More precisely, m_advertising.adv_data.adv_data.p_data is a pointer to the buffer containing advertising data, and m_advertising.adv_data_adv_data.len is the size of that buffer. Similar to how you manage advertising data for sending directly through sd_ble_gap_adv_set_configure(), you should be able to update the p_data and len fields correspondingly, so that the advertising module will use those values instead. You may be able to do that in ble_evt_handler() in main if you change the priorities for that event handler (APP_BLE_OBSERVER_PRIO) and that of the adveritising module (BLE_ADV_BLE_OBSERVER_PRIO) so that your event handler is run before that of the advertising module. I am not quite sure if something else will blow up if you change those priorities around, though. You may have other parts of code that relies on a certain order of execution for the ble event handlers.

    Regards,
    Terje

  • Thank you  for such a comprehensive answer, I very appreciate this.

    I have been trying and trying already for months to make work this hard way of your approach (except changing the priorities). But for now without any success Disappointed

    So now I'm really begging you, to show me how to do this on an example. Slight smile
    Only a function to update that damn byte in the specf manuf data will be completely enough.
    I do not need the whole project. Just these a few correctly written lines to make this work like it was working in the SDK14. Please.

Related