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

What are nRF52 advertisements exactly good for and what UUID do I have to put?

Hi!

So I managed to create my custom service with one characteristic (a struct with several attribs). I can see it in my app and everything's awesome. Yay.

But in some tutorial and in the sample app I altered initially (ble_bas sample), there is this struct:

static ble_uuid_t m_adv_uuids[] = {
    {BLE_UUID_POWER_SERVICE, BLE_UUID_TYPE_VENDOR_BEGIN},
    {BLE_UUID_BATTERY_SERVICE, BLE_UUID_TYPE_BLE},
    {BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE}
}; /**< Universally unique service identifiers. */

As you can see I already put my own services UUID at the top. I also made it of type VENDOR_BEGIN as stated in the tutorial.

But it then fails to initiate the advertising. Additional data:

#define APP_UUID                         {{ 0xC0, 0xBE, 0xBA, 0xEE, 0xFF, 0xC0,0xBE, 0xBA, 0xEE, 0xFF, 0xC0,0xBE, 0xBA, 0xEE, 0xFF, 0xC0 }}
#define BLE_UUID_POWER_SERVICE 0xBABE
#define BLE_UUID_POWER_CHAR 0xB0BA

And I register my vendor UUID like this:

ble_uuid128_t   base_uuid = APP_UUID;
    
// Add vendor UUID
err_code = sd_ble_u

uid_vs_add(&base_uuid, &ble_uuid.type);

And as expected I register the characteristic and the service with BLE_UUID_POWER_SERVICE and BLE_UUID_POWER_CHAR respectively. This works fine!

So now my question is: If I can see my service already, what do I need the adverts for and how do I register them properly if needbe?

Thanks a lot!

  • Hi,

    The point of advertising the UUID of available services, is to inform central devices of what services the device can provide, without the central needing to establish a connection to the device and perform a service discovery.

    If you place a central device in a room with 100 peripheral devices, where only one of the peripherals contain your power service, the central will not know which device to connect if you do not advertise the service UUID. Worst-case scenario, the central will have to connect to 100 peripherals, one by one, and perform a service discovery to know which one contains the correct service. If the service UUID is put in the advertising packet, the central can easily check if the service is available without establising a connection to any of the 100 peripherals.

    This saves time for the central device, and you avoid bothering the 99 peripheral devices that cannot offer the desired service.

    Note that the advertising packet is limited to 31 bytes. A vendor specific UUID is 128 bits (16 bytes), limiting the available space for name, other UUIDs, etc. You can also put the UUID in the scan response packet. This is described in chapter 5 of the BLE Advertising tutorial, and is also shown in the BLE UART example in the SDK.

    Best regards,

    Jørgen

  • Hi!

    Thank you for your answer! The answer for the first question is very clear, so I wasn't aware it just sees the service after the connect without advertising since I kinda just connected right away in the app ;) Thank you! Sadly the answer to my second question on how to get the advertising of my service going is not in the Tutorial 5 but in the Tutorial 8. And as I stated I closely followed it (to my knowledge it actually just involved adding the UUID to the UUID array that's advertised (I already posted what I did :))). Sadly the BLE stack rejects my given UUID ...

  • Hi, Yes, it is also present in BLE Services tutorial (maybe a better source since advertising tutorial does not mention UUIDs). However, my comment about the max size of the advertising package is still valid. You have to make sure you do not exeed the 31 byte limit. With one vendor specific service and two BLE type services, you have allready reached 20 bytes. There is alos a header overhead of two bytes per field. If your package includes name, appearance, etc., in addition to the UUIDs, you might have exeeded the package size limit. Have you tried adding the UUIDs to the scan response package instead of the advertising package?

  • Oh, sorry, I missunderstood you. I thought it sends a packet per service ... well then It might be ... still I think it's weird ... I indeed broadcasted a devicename. But when I removed the other 2 services from the list meaning (2x4 (2 UUID, 2 header))=8 Bytes less and I shortened the devicename string by 10 bytes. And it still fails me, so now I am confused ;) Also: In the ble_uuid_t there is only the type and the uint16_t UUID. So why does it actually broadcast the entire 128bit address even tho I don't tell it? Maybe because I tell it the service is vendorspecific? I will try the scan response as recommended :) Still I am kinda confused ... Thanks a lot for your help!

  • All advertised UUIDs will be in the same field, meaning you will not save any space on headers. This means that you have totally saved 14 bytes, less than the 16 bytes you added. If the advertising packet was already full, you might not have saved enough space. Please have a look at this comment about how the stack is able to advertise the full 128-bit UUID.

Related