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

Trying to add custom service UUID to adv_uuids

I have been following BLE Services, a beginner's tutorial to add a service to my ble_app_template project. But tutorial was written for SDK 11 and I'm using SDK 12 (s130 & pca10028 kit).

It's compiling and flashing fine, using GDB I can see my custom service is being added and I can log out the UUIDs. But using LightBlue on my phone I can't see the new custom service.

After a while I found m_adv_uuids doesn't exist in the source for the SDK 11 tutorial whereas it does in all the examples for SDK 12. So I'm guessing something has changed in the newer SDKs where it's a requirement.

If I add the defined UUID from my ble_custom_service.h file (#define BLE_UUID_OUR_SERVICE 0xDCBA) into my main.c advertising_init function:

ble_uuid_t m_adv_uuids[] = {{BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_OUR_SERVICE}}; /**< Universally unique service identifiers. */

I get:

In file included from ../../../main.c:30:0:
../../../main.c: In function 'advertising_init':
../../../ble_lamp_service.h:9:30: error: large integer implicitly truncated to unsigned type [-Werror=overflow]
 #define BLE_UUID_OUR_SERVICE 0xDCBA // Just a random, but recognizable value

Also I have tried the service handler and tried to access things such as .uuid / .uuid_type like some of the SDK 12 examples use:

ble_uuid_t m_adv_uuids[] = {{BLE_UUID_DEVICE_INFORMATION_SERVICE, m_our_service.uuid}}; /**< Universally unique service identifiers. */

But I get:

../../../main.c:727:84: error: 'ble_os_t {aka struct <anonymous>}' has no member named 'uuid'

I'm not sure what I need to do, do I have to expose this from my custom function or is there something in the SDK that I can use on the handler?

I have uploaded some snippets from my main.c, ble_custom_service.c, ble_custom_service.h to this GitHub Gist if anyone can help :)

On a side note are there any more up to date tutorials for adding services / characteristics in the newer SDKs? I find most of the included examples in the SDK too sporadic and messy for a newbie to grasp.

  • Hi DJM,

    you're simply missing the member variable .uuid in your ble_os_t Service structure, which realy should be uuid_type

    typedef struct {
        uint16_t    service_handle;     /**< Handle of Our Service (as provided by the BLE stack). */
        uint8_t     uuid_type; 
    } ble_os_t;
    

    You also need to set this in your our_service_init() function, i.e.

    void our_service_init(ble_os_t * p_our_service) {
    
      uint32_t   err_code;
      ble_uuid_t        service_uuid;
      ble_uuid128_t     base_uuid = BLE_UUID_OUR_BASE_UUID;
    
      err_code = sd_ble_uuid_vs_add(&base_uuid, &service_uuid.type);
      APP_ERROR_CHECK(err_code);
    
      /* This line was missing */
      p_our_service->uuid_type =  service_uuid.type;
    
      service_uuid.uuid = BLE_UUID_OUR_SERVICE;
    
      err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
                                        &service_uuid,
                                        &p_our_service->service_handle);
      APP_ERROR_CHECK(err_code);
       
      NRF_LOG_INFO("Exectuing our_service_init().\n");
      NRF_LOG_INFO("Service UUID: 0x%#04x\n", service_uuid.uuid);
      NRF_LOG_INFO("Service UUID type: 0x%#02x\n", service_uuid.type);
      NRF_LOG_INFO("Service handle: 0x%#04x\n", p_our_service->service_handle);
    
    }
    

    You could also just set type directly, i.e.

     ble_uuid_t m_adv_uuids[] = {{BLE_UUID_OUR_SERVICE , BLE_UUID_TYPE_VENDOR_BEGIN }};
    
  • Hi Bjørn, thanks for your answer. I'm making progress.

    I have exposed the uuid_type variable, set it in my service init, and added it to my list of service IDs.

    ble_uuid_t m_adv_uuids[] = {{BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE}, {BLE_UUID_OUR_SERVICE, m_our_service.uuid_type}}; /**< Universally unique service identifiers. */

    but now when it gets err_code = ble_advertising_init(&advdata, NULL, &options, on_adv_evt, NULL); I get a fatal error:

    Breakpoint 19, advertising_init () at ../../../main.c:747
    747	    APP_ERROR_CHECK(err_code);
    (gdb) p err_code
    $1 = 12
    

    I'm not sure what error 12 is, any ideas?

  • Error code 12 is NRF_ERROR_DATA_SIZE, see this Infocenter page. If step into advertisment_init, then adv_data_encode and then flags_encode you'll see that it returns NRF_ERROR_DATA_SIZE. Can you set a breakpoint there and check if this is the cause? If so, then you've put to much data into your advertisment packet.

  • So I just changed m_adv_uuids[] = {{BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE}, {BLE_UUID_OUR_SERVICE, m_our_service.uuid_type}}; to ble_uuid_t m_adv_uuids[] = {{BLE_UUID_OUR_SERVICE, m_our_service.uuid_type}}; and I can see the service now.

    {BLE_UUID_DEVICE_INFORMATION_SERVICE, BLE_UUID_TYPE_BLE} was included in the ble_app_template, are they needed? Does this mean I'm limited to advertising one service?

  • No, if you're not adding the Device Information Service in services_init, then you can remove it. The advertisement packet may contain 31 bytes and a vendor specific UUID is 128-bit, i.e. 16 bytes. So you will only be able to fit one 128-bit UUID in the advertisment packet. Remember that you can sue the Scan Response Packet to send an additional 31-bytes.

Related