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

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

  • That is strange.

    1. What SDK version are you using?
    2. Can you share your entire project? We can make the case private if you prefer confidentiality. 
  • Hi Martin,

    It seems that I had an issue with p_advertising->adv_data.adv_data.len indeed, which was getting unintentionally altered and reading the ServiceData "out of range".

    It is now working but I'm struggling with the NRF_ERROR_INVALID_STATE with sd_ble_gap_adv_set_configure. According to the documentation, "It is invalid to provide the same data buffers while advertising. To update advertising data, provide new advertising buffers."

    I try to contour the issue with the code in attachment but still retrieve the same error. Any ideas to solve it?

     

    I'm using SDK15 and Softdevice6.0.0

    Thank you,

    João

    ret_code_t sdata_set(ble_advertising_t * const p_advertising, uint16_t sdata)
    {
        uint32_t ret;
        
        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);
        
        uint16_t offset = 0;
        if (p_sdata != NULL)
        {
    			*p_sdata = sdata;
    
    			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);
    			
            	offset+=2; //To get the data itself			
    			p_advertising->adv_data.adv_data.p_data[offset++] = MSB_16(sdata);
            	p_advertising->adv_data.adv_data.p_data[offset++] = LSB_16(sdata);
        }
        else //Debug
        {
    			NRF_LOG_ERROR("No SData!");
        }
        
    
        if(m_advdata_idx % 2 == 0)
        {
                memcpy(m_new_enc_advdata1, p_advertising->adv_data.adv_data.p_data, p_advertising->adv_data.adv_data.len);
                m_new_adv_data.adv_data.p_data      = m_new_enc_advdata1;
                m_new_adv_data.adv_data.len         = p_advertising->adv_data.adv_data.len;
    
                m_new_adv_data.scan_rsp_data.p_data = p_advertising->enc_scan_rsp_data;
                m_new_adv_data.scan_rsp_data.len    = p_advertising->adv_data.scan_rsp_data.len;
        }
        else
        {
                memcpy(m_new_enc_advdata2, p_advertising->adv_data.adv_data.p_data, p_advertising->adv_data.adv_data.len);
                m_new_adv_data.adv_data.p_data      = m_new_enc_advdata2;
                m_new_adv_data.adv_data.len         = p_advertising->adv_data.adv_data.len;
    
                m_new_adv_data.scan_rsp_data.p_data = p_advertising->enc_scan_rsp_data;
                m_new_adv_data.scan_rsp_data.len    = p_advertising->adv_data.scan_rsp_data.len;
        }
    
        m_advdata_idx++;
    
        memcpy(&p_advertising->adv_data, &m_new_adv_data, sizeof(p_advertising->adv_data));
        p_advertising->p_adv_data = &p_advertising->adv_data;
    
        ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, &p_advertising->adv_data, &p_advertising->adv_params);
    
        return ret;
    }

  • Hi,

    Unfortunately there is no elegant way of updating the data in the advertising packet while advertising. You need to stop advertising, reconfigure the packet, and restart advertising again.

  • Hi Martin,

    I could do the whole data update when considering a similar strategy by interleaving two different pointers that are passed to p_advertising->adv_data at each data update iteration. Yet, it is not working for the service_data update purpose, as implemented in the code I sent you.

    Do you have any unelegant proposal to solve this issue? It seems like a limitation from the SDK that should be polished.

    Thank you,

    João

  • I'm not sure if I understand your question. My unelegant (and only) proposal is stop advertising and configure the advertising structure from scratch again each time you want to update the content. 

Reply Children
No Data
Related