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
  • 71 replies, none of them is the solution. Why Nordic changes the original simple API "ble_advdata_set", the new API really sucks !!!

  • I found a solution that seems to work fine. Once you have started the advertising, just use ble_advdata_encode to encode your data and write it to the buffer used when you first called sd_ble_gap_adv_set_configure . Do not call the sd_ble_gap_adv_set_configure function again, only encode the data. Your advertising data will be updated every time you do this. This might not be the recommend way for doing this, but I did not encounter any errors yet.

  • It should be his own custom data he wants to replace at the manufacturer data.

  • I got it working. I ditched the advertising module and followed the migration guide. I use 2 advdata buffers and switch between them when updating advdata. I also switch to boradcaster advertising when connected and updating works then too. 

    status peripheral_advdata_update(uint8_t * advdata_buffer_p, uint8_t len)
    {
        ret_code_t ret;
    
        increment_advdata_buffer();
        set_advdata_buffer(advdata_buffer_p, len);
    
        ret = sd_ble_gap_adv_set_configure(&adv_handle, &adv_data_buffer.adv_data, NULL);
        if (ret != NRF_SUCCESS)
        {
            NRF_LOG_INFO("adv_update error: 0x%02X", ret);
            return BLE_WSI_STATUS_SOFTDEVICE_INVALID_STATE;
        }
        else
        {
            NRF_LOG_INFO("using buffer %d", adv_data_buffer.idx);
            return BLE_WSI_STATUS_SUCCESS;
        }
    }
    status peripheral_advertising_init(uint32_t interval, uint32_t duration, uint8_t * advdata_buffer_p, uint8_t len)
    {
        ret_code_t ret;
        increment_advdata_buffer();
        set_advdata_buffer(advdata_buffer_p, len);
    
        adv_params.interval = interval;
        adv_params.duration = duration;
        memset(adv_params.channel_mask, 0, 5); /*Advertising on all the primary channels */
        adv_params.max_adv_evts = 0;
        adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
        adv_params.primary_phy = BLE_GAP_PHY_AUTO;
        adv_params.scan_req_notification = 1;
        if (!m_periph_params.is_connected)
        {
            adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
            NRF_LOG_INFO("Connectable adv");
        }
        else
        {
            adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED;
            NRF_LOG_INFO("Unconnectable adv");
        }
        if (m_periph_params.is_advertising)
        {
            ret = sd_ble_gap_adv_set_configure(&adv_handle, &adv_data_buffer.adv_data, NULL);
        }
        else
        {
            ret = sd_ble_gap_adv_set_configure(&adv_handle, &adv_data_buffer.adv_data, &adv_params);
        }
        
        NRF_LOG_INFO("adv_init: 0x%02X", ret);
        return ret;
    }

    This works good for me. I need to keep track of if advertising is ongoing or not myself and if i want to change interval or such I have to do that manually. But it isn't to much work.

  • Hello, I am new to programming nrf and don't have much experience with Embedded programming...Can you please tell me that what is advdata_buffer_p, len and how you implemented increment_advdata_buffer() and  set_advdata_buffer(advdata_buffer_p, len).If you can share your code that would be really a GREAT favor...!

  • I am in the same situation as you. I think that advdata_buffer_p is new advertising data and len is the lenght of that data, but dont take my word for it.

    I would also like to see the set_advdata_buffer(); function - struggling a bit in here.

  • If you want you can prevent using two buffers with a little trick. Just use a NULL pointer while you're changing the data. This is my update function, which uses encoded data. If your data is not encoded, just call the ble_advdata_encode() function before.

    uint32_t update_adv_data_set(uint8_t const *p_advdata, uint8_t dlen)
    {
      uint32_t             err_code = NRF_ERROR_API_NOT_IMPLEMENTED;
    
      /* configure adtvertising without data to circumvent Nordics new Buffer rule. */
      err_code = sd_ble_gap_adv_set_configure(&m_advModuleInstance.adv_handle, NULL, NULL);
    
      if (NRF_SUCCESS == err_code)
      {
        /* Edit global struct advertising data. */
        memset(m_advModuleInstance.enc_advdata, 0x00u, BLE_GAP_ADV_SET_DATA_SIZE_MAX);
        memcpy(m_advModuleInstance.enc_advdata, p_advdata, dlen);
        m_advModuleInstance.adv_data.adv_data.len = dlen;
        /* configure softdevice data */
        err_code = sd_ble_gap_adv_set_configure(&m_advModuleInstance.adv_handle, &m_advModuleInstance.adv_data, NULL);
      }
      
      return err_code;
    }

Reply
  • If you want you can prevent using two buffers with a little trick. Just use a NULL pointer while you're changing the data. This is my update function, which uses encoded data. If your data is not encoded, just call the ble_advdata_encode() function before.

    uint32_t update_adv_data_set(uint8_t const *p_advdata, uint8_t dlen)
    {
      uint32_t             err_code = NRF_ERROR_API_NOT_IMPLEMENTED;
    
      /* configure adtvertising without data to circumvent Nordics new Buffer rule. */
      err_code = sd_ble_gap_adv_set_configure(&m_advModuleInstance.adv_handle, NULL, NULL);
    
      if (NRF_SUCCESS == err_code)
      {
        /* Edit global struct advertising data. */
        memset(m_advModuleInstance.enc_advdata, 0x00u, BLE_GAP_ADV_SET_DATA_SIZE_MAX);
        memcpy(m_advModuleInstance.enc_advdata, p_advdata, dlen);
        m_advModuleInstance.adv_data.adv_data.len = dlen;
        /* configure softdevice data */
        err_code = sd_ble_gap_adv_set_configure(&m_advModuleInstance.adv_handle, &m_advModuleInstance.adv_data, NULL);
      }
      
      return err_code;
    }

Children
Related