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?

Parents
  • Try this code:

    static void advertising_init(void)
    {
        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] 		= 0x00;
    
    	
        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 	= false;
        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;
    
        init.evt_handler 	= on_adv_evt;
        init.error_handler  = ble_advertising_error_handler; 
    
        err_code = ble_advertising_init(&m_advertising, &init);
        APP_ERROR_CHECK(err_code);
    
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }
    
    static void advertising_data_update(uint8_t adv_manuf_byte)
    {
        ret_code_t err_code;
        ble_advdata_t              advdata;       /**< Advertising data: name, appearance, discovery flags, and more. */
        //ble_advdata_t              srdata;        /**< Scan response data: Supplement to advertising data. */
    
    	ble_advdata_manuf_data_t 	adv_manuf_data;
    	
        uint8_array_t            	adv_manuf_data_array;
    	
    	adv_manuf_data_data[0]     = adv_manuf_byte;
    
        memset(&advdata, 0, sizeof(advdata));
        //memset(&srdata, 0, sizeof(srdata));
       
        advdata.name_type          	        = BLE_ADVDATA_FULL_NAME;
        advdata.include_appearance 	        = false;
        advdata.flags              	        = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
        advdata.uuids_complete.uuid_cnt     = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        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;
    	advdata.p_manuf_specific_data 		= &adv_manuf_data;
    
        update_advertising_data(&m_advertising, &advdata, m_advertising.adv_data.adv_data.len, NULL, 0);
    }
    
    /* PARAMS
    [IN] p_advertising: Pointer to an advertising instance, usually m_advertising in 'main' context.
    [IN] p_adv_data:    Pointer to an advertisment data instance.
    [IN] adv_data_len:  Length of advertisment data in bytes.
    [IN] p_sr_data:     Pointer to an scan respose data instance, set to NULL if no SR data.
    [IN] sr_data_len:   Length of scan response data in bytes.
    */
    void update_advertising_data(ble_advertising_t *p_advertising, ble_advdata_t *p_adv_data, uint16_t adv_data_len, ble_advdata_t *p_sr_data, uint16_t sr_data_len)
    {
        ASSERT(p_advertising->initialized);
    
        uint32_t ret = NRF_SUCCESS;
        ble_gap_adv_data_t *new_advdata;
    
        new_advdata->adv_data.len = adv_data_len;      
    
        ret = ble_advdata_encode(p_adv_data, new_advdata->adv_data.p_data, &new_advdata->adv_data.len);
        APP_ERROR_CHECK(ret);
    
        if (p_sr_data)
        {
            new_advdata->scan_rsp_data.len = sr_data_len;
    
            ret = ble_advdata_encode(p_sr_data,
                                   new_advdata->scan_rsp_data.p_data,
                                   &new_advdata->scan_rsp_data.len);
            APP_ERROR_CHECK(ret);
        }
        else
        {
            new_advdata->scan_rsp_data.p_data = NULL;
            new_advdata->scan_rsp_data.len    = 0;
        }
    
        ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, new_advdata, NULL);
        APP_ERROR_CHECK(ret);
    }
    

  • I also tried this, and recieve error 12, with a ble_advdata_encode(). May be we should encode data directly to m_advertising.enc_advdata? like when we initialize advertising?

  • Yes, I know that but why use a "re-start" method if this is not really necessary? 
    apparently agrees with me :)

    Anyway... can I assume that this is a Nordic final answer related to this problem?

  • Please consider this as a final answer in this case.

  • Hello Haakonsh,

    Question to your reply : "Yes! You need at least two buffers to switch between."

    If I use two buffers one after another, do I need to flush the buffers before using it again in sd_ble_gap_adv_set_configure? or I just have to assign them one after another?

  • You just have to assign the one after the other. The SoftDevice requires only that you send it a pointer to an address that is different from the previous buffer, the content can remain the same. 

Reply Children
  • But my content changes every time(battery voltage value. I tried to refer eddystone and hrs example but couldn't go so far).

    manuf_specific_data.company_identifier = battVolt_1;

    this line is called every time when there is time out of timer. So, data is updated.

    Now is it good approach to use if else to assign new data(new buffer) at every cycle? Or am I at wrong approach?

    static void advertising_init(void)
    {
        ret_code_t      err_code;
        ble_advdata_t advdata;
        uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
    		
    		get_battery_volt();
    
        ble_advdata_manuf_data_t manuf_specific_data;
    		
        manuf_specific_data.company_identifier = battVolt_1;   		//changes when time out
    
        manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info;
        manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;
    		
        // Build and set advertising data.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type             = BLE_ADVDATA_NO_NAME;
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
        // Initialize advertising parameters (used when starting advertising).
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
        m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
        m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 0;       // Never time out.
    
        
    		err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
        APP_ERROR_CHECK(err_code);
    
    		if(i==0)
    		{
    			err_code = sd_ble_gap_adv_set_configure(&m_adv_handle_1, &m_adv_data, &m_adv_params);
    			APP_ERROR_CHECK(err_code);
    		}
    		else if(i==1)
    		{
    			err_code = sd_ble_gap_adv_set_configure(&m_adv_handle_2, &m_adv_data, &m_adv_params);
    			APP_ERROR_CHECK(err_code);
    		}
    		   
    		nrf_gpio_pin_toggle(LED_2);
    			
    }

    I set NULL too in _configure but didnt work.

    I will try to read this whole thread but it is quite long so if you can help in this!

  • "Now is it good approach to use if else to assign new data(new buffer) at every cycle? Or am I at wrong approach?"

    That sounds like what I would have done.


  • But sir code still stopped working at _configure().

    I tried to do debugging on keil.

    I did searched infocenter and different threads but could not get the idea about id,pc,info(i know definitions but how to use them to get to the error).

  • Thank you Haakonsh for your help.

    I made mistake by misunderstanding the pointer and buffer, Sorry!

    This thread helped me.

Related