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

Updating Advertising Service Data

Good afternoon,

I'm running advertising with a uint16_t service data associated with a 16-bit service UUID.

I would like to update the service data regularly without the need to update the whole advertising package.

Is there a way to do this similarly to the flags_set() function in the BLE Advertising Module? When I try to accomplish it by recurring to "uint8_t * p_service_data = ble_advdata_parse(p_advertising->adv_data.adv_data.p_data, p_advertising->adv_data.adv_data.len, BLE_GAP_AD_TYPE_SERVICE_DATA)" I can never return the correct offset in the advertising data related to the Service Data field - it always returns 0 offset - and therefore can't access the actual Service Data to update it. Any suggestions to accomplish this?

Thank you,

João

  • Hi,

    If ble_advdata_parse() always returns NULL it indicates that your advertising packets doesn't contain any Service Data. Have you confirmed that your packet actually contains a Service Data field before you call ble_advdata_parse()? You can easily see if the field is there with nRF Connect for mobile for example. 

    If it is there, can you upload your code? 

  • Hi Martin,

    Thank you for your reply.

    I'm totally sure the advertising packet contains the ServiceData and it is working as expected. I'm updating the whole advertising data everytime I need to update the ServiceData and it works perfectly.

    Any queues what might be wrong?

    Thank you,

    João

  • Not sure what it can be. Do you mind sharing your code? We can make the case private if you prefer confidentiality. 

  • Hi Martin,

    I compiled the parts of code in respect to this matter for you to assess it.

    Looking forward to hear any suggestion from you,

    Thank you,

    João

        //======= main.c =======
        
        static ble_advertising_init_t 		   m_init_adv_data_and_params;
     	static ble_advdata_service_data_t      m_service_data;
    	uint16_t 							   m_sdata;
    	static ble_uuid_t 					   m_adv_uuids[] = {{UUID_SERV_BEEP, BLE_UUID_TYPE_BLE}};
    	static ble_gap_phys_t 				   m_phys;
    	
        void advertising_init(void)
        {
        	uint32_t err_code;
    
        	//Build and Set Service Data
        	m_service_data.service_uuid       = UUID_SERV_BEEP;
        	m_service_data.data.size          = 2;
      
        	m_sdata                           = get_new_advertising_data();
        	m_service_data.data.p_data        = (uint8_t*)&m_sdata;
    
    
        	memset(&m_init_adv_data_and_params, 0, sizeof(m_init_adv_data_and_params));
    
        	//Build and Set Advertising Data.
        	m_init_adv_data_and_params.advdata.flags                        = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        	m_init_adv_data_and_params.advdata.name_type                    = BLE_ADVDATA_FULL_NAME;
        	m_init_adv_data_and_params.advdata.include_appearance           = false;
        
        	m_init_adv_data_and_params.advdata.uuids_complete.uuid_cnt       = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        	m_init_adv_data_and_params.advdata.uuids_complete.p_uuids        = m_adv_uuids;
        	m_init_adv_data_and_params.advdata.p_service_data_array          = &m_service_data;
        	m_init_adv_data_and_params.advdata.service_data_count            = 1;
    
        	//Build and Set Advertising Params.
        	m_init_adv_data_and_params.config.ble_adv_whitelist_enabled      = true;
        	m_init_adv_data_and_params.config.ble_adv_fast_enabled           = true;
        	m_init_adv_data_and_params.config.ble_adv_fast_interval          = APP_ADV_INTERVAL_FAST;
        	m_init_adv_data_and_params.config.ble_adv_fast_timeout           = APP_ADV_DURATION_10MS_FAST;
        	m_init_adv_data_and_params.config.ble_adv_slow_enabled           = true;
        	m_init_adv_data_and_params.config.ble_adv_slow_interval          = APP_ADV_INTERVAL_SLOW;
        	m_init_adv_data_and_params.config.ble_adv_slow_timeout           = APP_ADV_DURATION_10MS_SLOW;
        	m_init_adv_data_and_params.config.ble_adv_primary_phy            = BLE_GAP_PHY_1MBPS;
        	m_init_adv_data_and_params.config.ble_adv_secondary_phy          = BLE_GAP_PHY_1MBPS;
    
    
        	err_code = ble_advertising_init(&m_advertising, &m_init_adv_data_and_params);
        	APP_ERROR_CHECK(err_code);
    
        	ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
        }
        
        //====== ble_advertising.c =======
        
        uint32_t ble_advertising_init(ble_advertising_t            * const p_advertising,
                                  ble_advertising_init_t const * const p_init)
    	{
    	
        	uint32_t ret;
        	if ((p_init == NULL) || (p_advertising == NULL))
        	{
        	    return NRF_ERROR_NULL;
        	}
        	if (!config_is_valid(&p_init->config))
        	{
        	    return NRF_ERROR_INVALID_PARAM;
        	}
    
        	p_advertising->adv_mode_current               = BLE_ADV_MODE_IDLE;
        	p_advertising->adv_modes_config               = p_init->config;
        	p_advertising->conn_cfg_tag                   = BLE_CONN_CFG_TAG_DEFAULT;
        	p_advertising->evt_handler                    = p_init->evt_handler;
        	//p_advertising->error_handler                = p_init->error_handler;
        	p_advertising->current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;
        	p_advertising->p_adv_data                     = &p_advertising->adv_data;
    
        	memset(&p_advertising->peer_address, 0, sizeof(p_advertising->peer_address));
    
        	if (!p_advertising->initialized)
        	{
            	p_advertising->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
        	}
    
        	uint16_t max_len = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
    
        	ret = ble_advdata_encode(&p_init->advdata, p_advertising->enc_advdata, &max_len);
        	VERIFY_SUCCESS(ret);
    
    
        	p_advertising->adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;
        	p_advertising->adv_params.duration        = p_advertising->adv_modes_config.ble_adv_fast_timeout;
        
        	p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    
        	p_advertising->adv_params.p_peer_addr     = NULL;
        	p_advertising->adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        	p_advertising->adv_params.interval        = p_advertising->adv_modes_config.ble_adv_fast_interval;
    
        	p_advertising->adv_params.scan_req_notification=true;
    
        	ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, NULL, &p_advertising->adv_params);
        	VERIFY_SUCCESS(ret);
    
        	p_advertising->initialized = true;
    
        	return ret;
    	}
    	
    	ret_code_t sdata_set(ble_advertising_t * const p_advertising, uint16_t sdata)
    	{
        	uint8_t * p_sdata = ble_advdata_parse(p_advertising->adv_data.adv_data.p_data,
                                              p_advertising->adv_data.adv_data.len,
                                              BLE_GAP_AD_TYPE_SERVICE_DATA);
    
        	if (p_sdata != NULL)
        	{
            	*p_sdata = sdata;
        	}
        	else //Debug
        	{
    			uint16_t offset = 0;
            	ble_advdata_search(p_advertising->adv_data.adv_data.p_data, BLE_GAP_ADV_SET_DATA_SIZE_MAX, &offset, BLE_GAP_AD_TYPE_SERVICE_DATA);
            	NRF_LOG_INFO("OFFSET: %d", offset);
            }
            
        	return sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, &p_advertising->adv_data, &p_advertising->adv_params);
    	}

  • Hi,

    What SDK are you using? I tried to use your advertising_init() and sdata_set() functions together with the ble_app_uart example in SDK 15 and it seems to work fine. ble_advdata_parse() returns the address of Service Data in the advertising packet and the offset is correct. When you call ble_advdata_parse(), can you check the value of p_advertising->adv_data.adv_data.len and make sure that it makes sense? Maybe the length has been altered somewhere and that your Service Data is "out of range".

Related