Advertising both service data and manufacturing data

Hi team,

We are using NRF52833 with PCA10100 on it and soft device version is s140.

We are advertising with both service data and manufacturing data.

1. Initially when we are advertising (advertising_init  function) with both service data and manufacturing data, we are able to see the device full name in advertisement.

2. When we are updating with both service data and manufacturing data(by using vfnUpdateAdvtdata function), we are unable to see the device full name in advertisement

3. When we are updating the only manufacturing data, we are losing service data in advertisement.

Now my question is, How to advertise both service data and manufacturing data dynamically without losing any data ?

Here I am attaching my advertising_init() function and advdata_update() function.

static void advertising_init(void)
{
    uint32_t               err_code;
    uint8_t service_data[16]={0x02,0x01,0x00,0x00,0x01,0x02,0x03,0x04,0x6e,0x61,0x73,0x68,0x00,0x00};
    //uint8_t manfact_data = 0x3c;
    ble_advertising_init_t init;
    ble_advdata_service_data_t st_srviece;

   memset(&init, 0, sizeof(init));

   /* Advertise the battery data */
    ble_advdata_manuf_data_t                  manuf_data; //Variable to hold manufacturer specific data
    uint8_t data                            = (uint8_t)Batfin_per; //Our data to advertise
    manuf_data.company_identifier             =  0xffff; //Nordics company ID
    manuf_data.data.p_data                    = &data;
    manuf_data.data.size                      = sizeof(data);
    init.advdata.p_manuf_specific_data = &manuf_data;


    init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    init.advdata.include_appearance = false; // to change BLE symbol apperence as user mentioned
    init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; //for infinate advertisement
                                      //BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;

   st_srviece.service_uuid = BLE_UUID_NUS_SERVICE;
    st_srviece.data.p_data = service_data;
    st_srviece.data.size = sizeof(service_data);

   /*init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.srdata.uuids_complete.p_uuids  = m_adv_uuids;*/

   init.srdata.uuids_more_available.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.srdata.uuids_more_available.p_uuids  = m_adv_uuids;

   init.srdata.p_service_data_array = &st_srviece;
    init.srdata.service_data_count = 1;

   init.config.ble_adv_fast_enabled  = true;
    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
    init.config.ble_adv_fast_timeout  = 0;//APP_ADV_DURATION; // to make advertisment infinate
    init.evt_handler = on_adv_evt;

   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);

}

void vfnUpdateAdvtdata()
        {
            static uint32_t adv_batt=0;
     

            if(adv_batt != Batfin_per)
             {    
                    adv_batt = Batfin_per;
                    uint32_t               err_code;
                    uint8_t service_data[8]={0x01,0x02,0x03,0x04,0xAA,0xBB,0xCC,0xDD};
                               
                    ble_advdata_service_data_t st_srviece;

                   /* Advertise the battery data */
                    ble_advdata_manuf_data_t                  manuf_data; //Variable to hold manufacturer specific data
                    new_advdata.p_manuf_specific_data = &manuf_data;
                    uint8_t data                            = (uint8_t)Batfin_per; //Our data to advertise
                    manuf_data.company_identifier             =  0xffff; //Nordics company ID
                    manuf_data.data.p_data                    = &data;
                    manuf_data.data.size                      = sizeof(data);

                   new_advdata.name_type          = BLE_ADVDATA_FULL_NAME;
                    new_advdata.include_appearance = false; // to change BLE symbol apperence as user mentioned
                    new_advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; //for infinate advertisement
                                                      //BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
                    
                    st_srviece.service_uuid = BLE_UUID_NUS_SERVICE;
                    st_srviece.data.p_data = service_data;
                    st_srviece.data.size = sizeof(service_data);

                   /*new_advdata.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
                    new_advdata.srdata.uuids_complete.p_uuids  = m_adv_uuids;*/

                   new_advdata.uuids_more_available.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
                    new_advdata.uuids_more_available.p_uuids  = m_adv_uuids;

                   new_advdata.p_service_data_array = &st_srviece;
                    new_advdata.service_data_count = 1;

                  /* init.config.ble_adv_fast_enabled  = true;
                    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
                    init.config.ble_adv_fast_timeout  = 0;//APP_ADV_DURATION; // to make advertisment infinate
                    init.evt_handler = on_adv_evt;*/
                    
                    err_code =  ble_advertising_advdata_update(&m_advertising,&new_advdata, NULL);
                    APP_ERROR_CHECK(err_code);  
            }
        }

Please check the code and let me know if anything I need to change.

Regards,

Hareesh.

  • Hello Hareesh. 

    For future reference: 
    When uploading code, you can use the "Insert -> Code" feature. That makes it a lot easier for us to read your ticket. 

    __________

    As for your questions: 

    we are unable to see the device full name in advertisement

    You have a limited amount of data available in the advertising packet. I don't see you mention anything specific about your setup so I assume this is normal BLE advertising, thus having 31 bytes available. 

    If the advertising packet contains more data than allowed, the SD will automatically shorten the device name in order to fit all the data in the advertising packet. 

    I assume that is why you are missing data. 

    Please take another look at your advertising data and double check that you aren't exceeding the limit. 

    Br, 
    Joakim

  • Hi Joakim,

    Initially I am advertising with manufacturing and service data.

    Once I update the manufacture data, the following error coming.

    <info> app_timer: RTC: initialized.
    <info> app: Updating advertising data!
    <error> app: ERROR 12 [NRF_ERROR_DATA_SIZE] at C:\nRF5_SDK_17.1.0_ddde560\examples\ble_peripheral\ble_app_uart\main.c:363
    PC at: 0x0002B9AB
    <error> app: End of error report.

    err_code = ble_advertising_advdata_update(&m_advertising, &new_advdata, NULL);
    APP_ERROR_CHECK(err_code);    =======================================>>main.c:363

    Please help me to resolve the issue.

    Regards,

    Hareesh.

  • Thanks. 

    The error is most likely returning from ble_advdata_encode(). 

    NRF_ERROR_DATA_SIZE If the operation failed because not all the requested data could fit into the provided buffer or some encoded AD structure is too long and its length cannot be encoded with one octet.
  • Hi Joakim,

    1. Initially when we are advertising (advertising_init  function) with both service data and manufacturing data, we are able to see the device full name in advertisement.

    Initially it is working fine. That you can see in the following image.

    Once I update the manufacture data and service data with the  same length, the following error coming.

    <info> app_timer: RTC: initialized.
    <info> app: Updating advertising data!
    <error> app: ERROR 12 [NRF_ERROR_DATA_SIZE]

    Here I am attaching both advertise_init() and advdata_update() functions.

    static ble_advdata_t  new_advdata;
    
    static void advertising_init(void)
    {
        uint32_t  err_code;
        uint8_t serv_data[16] = {0};
        uint8_t manf_data[1] = {0x3C};
    
        ble_advertising_init_t init;
    
        ble_advdata_manuf_data_t manuf_spec_data;
    
        ble_advdata_service_data_t service_data;
    
        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; 
       
        service_data.service_uuid =  BLE_UUID_NUS_SERVICE;
        service_data.data.size = sizeof(serv_data);
        service_data.data.p_data = serv_data; 
    
        manuf_spec_data.company_identifier = 0xFFFF;
        manuf_spec_data.data.p_data = manf_data;
        manuf_spec_data.data.size = sizeof(manf_data);
    
        init.srdata.uuids_more_available.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.srdata.uuids_more_available.p_uuids = m_adv_uuids;
    
        init.srdata.p_service_data_array = &service_data;
        init.srdata.service_data_count = 1;
    
        init.advdata.p_manuf_specific_data = &manuf_spec_data;
    
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = 0;//APP_ADV_DURATION; // to make advertisment infinate
    
        init.evt_handler = on_adv_evt;
    
        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 adv_data_update_timer_handler(void * p_context)
    {
        ret_code_t                  err_code;
        ble_advdata_manuf_data_t    manuf_data;
        ble_advdata_service_data_t  new_servdata;
    
        uint8_t new_serv_data[16] = {0};
    
        static uint8_t payload_index = 0;
    
        NRF_LOG_INFO("Updating advertising data!");
        
        manuf_data.company_identifier = 0xFFFF;
        manuf_data.data.p_data = manufacturing_data_payload_list + payload_index;
        manuf_data.data.size = PAYLOAD_SIZE;
    
        new_advdata.name_type          = BLE_ADVDATA_FULL_NAME;
        new_advdata.include_appearance = false; // to change BLE symbol apperence as user mentioned
        new_advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; //for infinate advertisement
    
        new_servdata.service_uuid =  BLE_UUID_NUS_SERVICE;
        new_servdata.data.size = sizeof(new_serv_data);
        new_servdata.data.p_data = new_serv_data; 
    
        new_advdata.uuids_more_available.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        new_advdata.uuids_more_available.p_uuids = m_adv_uuids;
    
        new_advdata.p_service_data_array = &new_servdata;
        new_advdata.service_data_count = 1;        
    
        new_advdata.p_manuf_specific_data = &manuf_data;
    
        err_code = ble_advertising_advdata_update(&m_advertising, &new_advdata, NULL);
        APP_ERROR_CHECK(err_code);  
    
        if(payload_index == TOP_INDEX)
        {
            payload_index = 0;
        }
        else
        {
            payload_index++;
        }
    
        NRF_LOG_INFO("Advertising data updated!");
    
    }
    
        

    Now my question is, How to advertise both service data and manufacturing data dynamically without losing any data ?

    Please check the code and let me know if anything I need to change.

    Regards,

    Hareesh.

Related