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

Discovery of 128bit UUID services confusing

Hi

I am using sd_ble_gattc_primary_services_discover(conn_handle,0x0001,NULL) to discover primary services on a GATT server. After the first call to this function, I get 2 BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP, BLE_GATTC_EVT_CHAR_DISC_RSP and BLE_GATTC_EVT_DESC_DISC_RSP events:

  1. BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP with service count = 2, with 2 Standard BLE services listed and all handles linked
  2. BLE_GATTC_EVT_CHAR_DISC_RSP and BLE_GATTC_EVT_DESC_DISC_RSP events
  3. BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP with service count = 0 (I guess this means discovery is complete)

I know there are more 128 bit services, but why am I receiving the 2nd event with service count = 0. This tells my code that there are no more services, right? If I do another call to sd_ble_gattc_primary_services_discover(conn_handle,0x000c,NULL), but with the start handle set to the handle of the first 128 bit uuid in the list, it correctly returns with the BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP response and some service info, but just the single event with its corresponding CHAR and DESC events...no second event with "service count = 0". So the first time I call it the response is different to the second time I call it.

So, why am I receiving the second event on the first api call, but not on any other there after?

I'm using the following

  • IC: nRF52840
  • Softdevice: S140 SDK: nRF5_SDK_13.0.0_04a0bfd
  • Example as base: ble_app_hrs_c
  • IDE: Eclipse + GCC

Thanks

Parents
  • Hi Tielman,

    As David suggested Nordic Soft Device work on (G)ATT layer with UUIDs represented as 128-bit base + 16-bit "short" UUID. All base UUIDs are listed in "virtual" table inside SD and instead of values APP can only get base UUID "index" + short UUID whenever it uses GATT API. By default when SD is initialized after boot it knows only one base UUID = BT SIG default 128-bit UUID (that's quite logical). All other UUIDs will be referred as "UNKNOWN" base + short value. Now you have four options how to handle this:

    • You don't care about base because you work only with UUIDs defined by BT SIG in their 16-bit space.
    • You work with any proprietary UUIDs so you will scale ATT table size during SD init properly and you provision all 128-bit bases right after it before starting to work with GATT API (note that you need to keep some internal base UUID table or system in your APP because since then SD returns only indexes and it's up to the APP to link them to real UUIDs).
    • You work with proprietary UUIDs but you cannot or don't want to provision all the bases during SD init. Then you can simply wait until you discover some handle with UUID referred by SD as "UNKNOWN" base, read the Characteristic's UUID handle "manually" and use response value (128-bit UUID) as base to provision SD for later use (so now it will get some specific index).
    • Alternatively to previous point you can simply live with the fact that all proprietary UUIDs will be referred to "UNKNOWN" base and you need to verify full UUID by one (G)ATT Read method round-trip.

    Btw. this thread has some source code examples (also with pretty old SD but I guess it still helps).

    Cheers Jan

  • Hi Jan

    Thanks so much for the detailed response. You definitely shed some light on steps that I might have been doing, but not fully understood. Thanks for that.

    I think that my original question does not quite relay my issue correctly (or maybe it does, but I just don't understand it yet). I don't (think) that I have an issue with the 128 bit uuid as such. I do already register my uuid using sd_ble_uuid_vs_add(). I will break up my issue with the following steps that I follow:

    • ble_stack_init() => All good
    • err_code = sd_ble_uuid_vs_add(&base_uuid, &uuid_sd_type ); // => SUCCESS
    • Scan and connect to peripheral

    • err_code = sd_ble_gattc_primary_services_discover(conn_handle, 0x0001, NULL); // => SUCCESS

    Now this is where it gets confusing. According to the softdevice manual, I should only be getting BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP event, yet, I am getting 3 different events:

    • EVT RX: BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP => svc_count = 2; - SVC Handles: 0x1-0x4 - type:1 - uuid:0x1801 - SVC Handles: 0x5-0xb - type:1 - uuid:0x1800
    • EVT RX: BLE_GATTC_EVT_CHAR_DISC_RSP disc cnt=1: 0x2a05 - handle 0x3
    • EVT RX: BLE_GATTC_EVT_CHAR_DISC_RSP disc cnt=0: 0x2a05 - handle 0x3
    • EVT RX: BLE_GATTC_EVT_DESC_DISC_RSP disc cnt=1: 0x2902 - handle 0x4
    • EVT RX: BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: Count 0x0

    According to what I have read, after issuing the sd_ble_gattc_primary_services_discover() api call, I will receive BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP event. If the count is more than 0, there are more services to read and I need to do another call. If count=0, then there are no more services to read. Simple enough, except that I receive all of the above events with a single API call, ending with another BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP event, but with count=0.

    This does not line up with the softdevice manual at all and I don't understand why:

    1. I'm getting the additional events
    2. why I get the second BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP event saying there are no more services, yet there are more events (btw, I get the exact same response sequence when I start reading from a handle that is a 128bit service)

    Please help

Reply
  • Hi Jan

    Thanks so much for the detailed response. You definitely shed some light on steps that I might have been doing, but not fully understood. Thanks for that.

    I think that my original question does not quite relay my issue correctly (or maybe it does, but I just don't understand it yet). I don't (think) that I have an issue with the 128 bit uuid as such. I do already register my uuid using sd_ble_uuid_vs_add(). I will break up my issue with the following steps that I follow:

    • ble_stack_init() => All good
    • err_code = sd_ble_uuid_vs_add(&base_uuid, &uuid_sd_type ); // => SUCCESS
    • Scan and connect to peripheral

    • err_code = sd_ble_gattc_primary_services_discover(conn_handle, 0x0001, NULL); // => SUCCESS

    Now this is where it gets confusing. According to the softdevice manual, I should only be getting BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP event, yet, I am getting 3 different events:

    • EVT RX: BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP => svc_count = 2; - SVC Handles: 0x1-0x4 - type:1 - uuid:0x1801 - SVC Handles: 0x5-0xb - type:1 - uuid:0x1800
    • EVT RX: BLE_GATTC_EVT_CHAR_DISC_RSP disc cnt=1: 0x2a05 - handle 0x3
    • EVT RX: BLE_GATTC_EVT_CHAR_DISC_RSP disc cnt=0: 0x2a05 - handle 0x3
    • EVT RX: BLE_GATTC_EVT_DESC_DISC_RSP disc cnt=1: 0x2902 - handle 0x4
    • EVT RX: BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: Count 0x0

    According to what I have read, after issuing the sd_ble_gattc_primary_services_discover() api call, I will receive BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP event. If the count is more than 0, there are more services to read and I need to do another call. If count=0, then there are no more services to read. Simple enough, except that I receive all of the above events with a single API call, ending with another BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP event, but with count=0.

    This does not line up with the softdevice manual at all and I don't understand why:

    1. I'm getting the additional events
    2. why I get the second BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP event saying there are no more services, yet there are more events (btw, I get the exact same response sequence when I start reading from a handle that is a 128bit service)

    Please help

Children
No Data
Related