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

Adding service_data to advertising (custom service)

Hi guys,

i asked a similar question [1] few days ago, but yesterday i stumbled over the "service_data" type when advertising packages.

I've written a custom service (uuid: 0x1004) with a custom base-uuid (i don't know if its necessary to mention :). Is it now possible to send additional information corresponding to this custom service? Or is the usage of the service_data just allowed for registered services of Bluetooth SIG?

ble_advdata_service_data_t 	srv_data;
uint8_array_t			   	data_array;
uint8_t						data[1];

data[0] = 0x01
data_array.p_data = data;
data_array.size = sizeof(data);
srv_data.service_uuid = SERVICE_UUID;
srv_data.data = data_array;

[...]
advdata.p_service_data_array 	= &srv_data;
advdata.service_data_count		= 1;

apparently it will be send, but in service data nothing shows up: image description

Thanks in advance, cheers!

[1] devzone.nordicsemi.com/.../

  • Use manufacturer specific data:

    // Variables used for manufacturer specific data
    ble_advdata_manuf_data_t adv_manuf_data;
    uint8_array_t            adv_manuf_data_array;
    uint8_t                  adv_manuf_data_data[2];
    
    // Configuration of manufacturer specific data
    adv_manuf_data_data[0] = 0xAA;
    adv_manuf_data_data[1] = 0xBB;
    
    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 = 0xFF00;
    adv_manuf_data.data = adv_manuf_data_array;
    
    advdata.p_manuf_specific_data = &adv_manuf_data;
    

    You can additionaly add manufacturer specific data field in scan response packet:

    ble_advdata_t advdata;
    ble_advdata_t scanrsp;
    
    // Variables used for manufacturer specific data
    ble_advdata_manuf_data_t adv_manuf_data;
    uint8_array_t            adv_manuf_data_array;
    uint8_t                  adv_manuf_data_data[2];
    
    ble_advdata_manuf_data_t scanrsp_manuf_data;
    uint8_array_t            scanrsp_manuf_data_array;
    uint8_t                  scanrsp_manuf_data_data[27];
    
    // Build and set advertising data
    memset(&advdata, 0, sizeof(advdata));
    
    ...
    
    // Configuration of manufacturer specific data
    adv_manuf_data_data[0] = 0xAA;
    adv_manuf_data_data[1] = 0xBB;
    
    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 = 0xFF00;
    adv_manuf_data.data = adv_manuf_data_array;
    
    advdata.p_manuf_specific_data = &adv_manuf_data;
    
    // Build and set scan response data
    memset(&scanrsp, 0, sizeof(scanrsp));
    
    ...
    
    // Configuration of manufacturer specific data
    scanrsp_manuf_data_data[0] = 0xCC;
    scanrsp_manuf_data_data[1] = 0xDD;
    
    scanrsp_manuf_data_array.p_data = scanrsp_manuf_data_data;
    scanrsp_manuf_data_array.size = sizeof(scanrsp_manuf_data_data);
    
    scanrsp_manuf_data.company_identifier = 0xFF00;
    scanrsp_manuf_data.data = scanrsp_manuf_data_array;
    
    scanrsp.p_manuf_specific_data = &scanrsp_manuf_data;
    
    err_code = ble_advdata_set(&advdata, &scanrsp);
    APP_ERROR_CHECK(err_code);
    

    This works for me:

    ble_advdata_t scanrsp;
    ble_advdata_service_data_t  srv_data;
    uint8_array_t               data_array;
    uint8_t                     data[6];
    data_srv[0] = 0xAA;
    data_srv[1] = 0xBB;
    data_srv[2] = 0xCC;
    data_srv[3] = 0xDD;
    data_srv[4] = 0xEE;
    data_srv[5] = 0xFF;
    data_array.p_data = data;
    data_array.size = sizeof(data);
    srv_data.service_uuid = BLE_UUID_TX_POWER_SERVICE;
    srv_data.data = data_array;
    
    memset(&scanrsp, 0, sizeof(scanrsp));
    scanrsp.p_service_data_array    = &srv_data;
    scanrsp.service_data_count      = 1;
    
    err_code = ble_advdata_set(&advdata, &scanrsp);
    APP_ERROR_CHECK(err_code);
    

    It seems it didn't work for you because in your advdata packet was not enough free space for your service_data.

  • I don't know why your code does not appear to work. However on concern I would have of putting the 16-bit portion of your custom UUID is if it could cause inter-operability problems if it ever collides with a SIG defined profile UUID. Perhaps putting your data into the manufacturers specific data portion of the advertising packet would be safer?

    I noticed that you are advertising the 16-bit portion of your custom UUID in the 16-bit UUID section. Perhaps you should advertise the whole 128-bit UUID for similar reasons?

  • hi john,

    thanks for your comment. I'm not sure whats the common way is. I'm not sure.. using the manufacturers specific data portion looks little bit like an hack for me. I thought, i have a service, and i want to advertise little bit more information to this service -> service_data. But i'm not sure whats the right way is :) Is it possible to advertise the whole 128bit UUID? hm..

  • Hi Nikita

    thanks for your answer and the code example. But, do you know, is there a reason why i shouldn't use service_data? Is this the common way to advertise additional data relating to services?

  • Hm.. actually its working (as you can see in the attached picture above). In the data section, you can see at the end the byte values "04 16 04 10 01". Thus "4 bytes length, 16 specifies the service data, 04 10 is my service uuid, and 01 is the sent value" but, it seems its not correct, since the application doesn't recognize it as service data (the empty value next to "service data")

Related