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. 

  • Hi Martin,

    I tried to import your sdata_set function and it results the same => offset is always zero and thus p_sdata is never different than NULL.

    I checked p_advertising->adv_data.adv_data.len and it is always 31.

    Do you have any idea what might be the problem?

    Thanks,

    João

  • 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

Reply
  • 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

Children
Related