GATT Service Discovery Failure on SIG BASE UUID

Support,

I've encountered a challenge while integrating my product with device from a third-party. Unfortunately, they've utilized the SIG base UUID for their unregistered vendor services, and with their product already on the market for a few years, they've expressed no intention to revise this approach. I'm integrating with two of their devices, which I'll distinguish as device A and device B for our discussion. Establishing a connection with device A poses no issue, as its service characteristics are easily discoverable due to the use of 16-bit UUIDs. However, with device B, their oldest product, I'm not as fortunate. During the discovery process on device B, I encounter the error BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND. Research conducted using tools such as nRF Connect for both iOS and desktop reveals differences in how devices A and B present their services and characteristics. I have attached screenshots and logs from these tools for reference. From what I've gathered from another topic on this support site, the Softdevice manages the SIG Base UUID internally in a manner that I haven't fully grasped yet. It seems like I need to adopt an approach where I utilize the full 128-bit UUID instead of the 16-bit UUID for service discovery. From the log screenshots below, you can clearly see the differences between the to devices.  However, I'm uncertain how to implement this when the SIG base UUID is in use, which is causing some confusion in getting this to work. I've reached the limits of my knowledge in resolving this issue and need assistance from support to guide me toward a solution. Are there questions I'm overlooking, and do you fully grasp my problem? If so, is there a viable path to resolving it? Thank you.

This screenshot merges the log outputs from nRF Connect for iOS. As evident, the implementation of the SIG Base UUID appears to vary slightly in the way it's being published. I'm having difficulty comprehending these two differences: the utilization of 128-bit and 16-bit UUIDs.

Here's a screenshot of the device connect to nRF Connect for Desktop

   

As always, thank you for the amazing support!

Parents
  • Hello,

    When working with vendor-specific UUIDs that do not use the BT SIG base UUID, you must first add the 128-bit base UUID to the SoftDevice's UUID table. This allows the application to reference the UUID later. New base UUIDs are added through the sd_ble_uuid_vs_add()  function.

    Note: If sd_ble_uuid_vs_add() returns NRF_ERROR_NO_MEM, it means you must increase the 'NRF_SDH_BLE_VS_UUID_COUNT' in sdk_config.h to allocate additional UUID slots in the SoftDevice table.

    You can take a look at the Nordic UART Service Client  project for a practical example of a client using a 128-bit vendor-specific UUID. This client include the following service and characteristics:

    Code to add the Nordic UART service base uuid

    #define NUS_BASE_UUID                   {{0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}} /**< Used vendor-specific UUID. */
    
    ...
    
    uint32_t ble_nus_c_init(ble_nus_c_t * p_ble_nus_c, ble_nus_c_init_t * p_ble_nus_c_init)
    {
        uint32_t      err_code;
        ble_uuid_t    uart_uuid;
        ble_uuid128_t nus_base_uuid = NUS_BASE_UUID;
    
        VERIFY_PARAM_NOT_NULL(p_ble_nus_c);
        VERIFY_PARAM_NOT_NULL(p_ble_nus_c_init);
        VERIFY_PARAM_NOT_NULL(p_ble_nus_c_init->p_gatt_queue);
    
        err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_ble_nus_c->uuid_type);
        VERIFY_SUCCESS(err_code);
        ...

    Notice that the NUS_BASE_UUID symbol is represented in little-endian format, as opposed to the big-endian representation that tends to be used in user-facing applications and documentation. Also, the 'p_ble_nus_c-->uuid_type' holds the index of the base UUID, which the app uses as a tag to reference the UUID. 

    Service discovery registration

    Characteristic discovery

    If anything is unclear, please let me know.

    Best regards,

    Vidar

  • Vidar,

    Thanks for getting back to me promptly. I fully understand your reply. My product also interfaces with multiple other vendor products through their distinct UUIDs and services. When I integrated other products a few years back, I followed the NUS client model as outlined.

    In my explanation, both devices utilize the SIG base UUID for their services. This can be verified in the screenshot of the nRF Connect logs I posted.  My client code for connecting to Device-A functions smoothly. Since the services of Device-A and Device-B appear identical, I aimed to utilize the same code to connect to either device. When connecting to Device-A, there are no issues with discovering the service. Upon reviewing the logs, we observe that it returns the short UUID (2-byte). However, Device-B is now returning the full UUID (16-byte), and inexplicably, it cannot be discovered, resulting in an "attribute not found" error. So in short, the discovery process cannot find the service "0000FFE0-0000-1000-8000-00805F9B34FB" (Device-B) but can find "FFE0" (Device-A).

    Logs from nRF Connect for both devices, with the highlighted comparison.

    Device-B debug output from the connection attempt reveals failure due to the inability to find the service FFE0 during the discovery process.

    <info> srm_ble_svcs: CENTRAL: Scan Event - Found Peripheral Device PeekSmith-030CA3
    .
    <info> srm_ble_svcs: CENTEAL: Peripheral Device Address - D0:78:87:05:0C:A3
    <debug> nrf_sdh_ble: BLE event: 0x10.
    <debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
    <debug> nrf_ble_gatt: Updating data length to 251 on connection 0x0.
    <info> srm_ble_svcs: CENTRAL: Scan Event - Connected to device.
    <debug> ble_display_c: CONNECTED Event Recieved!
    <info> srm_ble_svcs: CENTRAL: GAP - Device Connected, handle 0
    <info> ble_display_c: Assigning Connection Handle, handle 0
    <debug> nrf_ble_gq: Registering connection handle: 0x0000
    <debug> ble_db_disc: Starting discovery of service with UUID 0xFFE0 on connection handle 0x0.
    <debug> nrf_ble_gq: Adding item to the request queue
    <debug> nrf_ble_gq: GATTC Primary Services Discovery Request
    <debug> nrf_ble_gq: SD is currently busy. The GATT request procedure will be attempted                       again later.
    <debug> nrf_ble_gq: Processing the request queue...
    <debug> nrf_ble_gq: GATTC Primary Service Discovery Request
    <debug> nrf_ble_gq: SD is currently busy. The GATT request procedure will be attempted                           again later.
    <debug> nrf_sdh_ble: BLE event: 0x39.
    <debug> nrf_ble_gq: Processing the request queue...
    <debug> nrf_ble_gq: GATTC Primary Service Discovery Request
    <debug> nrf_ble_gq: SD is currently busy. The GATT request procedure will be attempted                           again later.
    <debug> nrf_sdh_ble: BLE event: 0x3A.
    <debug> nrf_ble_gatt: ATT MTU updated to 247 bytes on connection 0x0 (response).
    <debug> srm_ble_svcs: GATT: ATT MTU exchange completed. central 0xF7 peripheral 0xF7
    <debug> nrf_ble_gq: Processing the request queue...
    <debug> nrf_ble_gq: GATTC Primary Service Discovery Request
    <debug> nrf_ble_gq: SD GATT procedure (2) succeeded on connection handle: 0.
    <debug> nrf_sdh_ble: BLE event: 0x24.
    <debug> nrf_ble_gatt: Data length updated to 251 on connection 0x0.
    <debug> nrf_ble_gatt: max_rx_octets: 27
    <debug> nrf_ble_gatt: max_tx_octets: 251
    <debug> nrf_ble_gatt: max_rx_time: 328
    <debug> nrf_ble_gatt: max_tx_time: 2120
    <debug> srm_ble_svcs: GATT: ATT MTU exchange completed. central 0xF7 peripheral 0xF7
    <debug> nrf_sdh_ble: BLE event: 0x30.
    <debug> ble_db_disc: Service UUID 0xFFE0 not found.
    <info> srm_ble_svcs: CENTRAL: Display Database Discovery Event.
    <debug> ble_display_c: Database Discovery Event: BLE_DB_DISCOVERY_SRV_NOT_FOUND
    <info> srm_ble_svcs: CENTRAL: Display Database Discovery Event.
    <debug> ble_display_c: Database Discovery Event: BLE_DB_DISCOVERY_AVAILABLE
    <debug> nrf_ble_gq: Processing the request queue...
    <debug> nrf_sdh_ble: BLE event: 0x39.
    <debug> nrf_ble_gq: Processing the request queue...
    <debug> nrf_sdh_ble: BLE event: 0x39.
    <debug> nrf_ble_gq: Processing the request queue...
    <debug> nrf_sdh_ble: BLE event: 0x39.
    <debug> nrf_ble_gq: Processing the request queue...

    Here's the code snippet for initializing the client.

    // 00000000-0000-1000-8000-00805F9B34FB
    #define BLE_SIG_UUID_BASE                 { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, \
                                                0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
    
    ....
    
    #define PS_UUID_DISPLAY_SERVICE  0xFFE0
    #define PS_UUID_DISPLAY_CHAR_1   0xFFE1
    #define PS_UUID_DISPLAY_CHAR_2   0xFFE2
    #define PS_UUID_DISPLAY_CHAR_3   0xFFE3
    #define PS_UUID_DISPLAY_CHAR_4   0xFFFF
    
    ....
    
    ret_code_t m_ble_display_c_init(ble_display_c_init_t  *p_ble_display_c_init,
                                    ble_display_config_t **p_display_config) {
        ret_code_t err_code;
        
        VERIFY_PARAM_NOT_NULL(p_ble_display_c_init);
        VERIFY_PARAM_NOT_NULL(p_ble_display_c_init->p_gatt_queue);
    
        memcpy(&s_display_config, &s_display_config_default, sizeof(ble_display_config_t));
        *p_display_config = &s_display_config;
    
        ble_uuid128_t base_uuid = BLE_SIG_UUID_BASE;
        err_code = sd_ble_uuid_vs_add(&base_uuid, &m_ble_display_c.uuid_type);
        VERIFY_SUCCESS(err_code);
        
        ble_uuid_t srvc_uuid = {
    	.type = m_ble_display_c.uuid_type,
    	.uuid = PS_UUID_DISPLAY_SERVICE
        };
    
        m_ble_display_c.peer_display_db.cccd_handle    = BLE_GATT_HANDLE_INVALID;
        m_ble_display_c.peer_display_db.display_handle = BLE_GATT_HANDLE_INVALID;
        m_ble_display_c.conn_handle                    = BLE_CONN_HANDLE_INVALID;
        m_ble_display_c.p_gatt_queue                   = p_ble_display_c_init->p_gatt_queue;
        //m_ble_display_c.uuid_type                      = BLE_UUID_TYPE_VENDOR_BEGIN;
        //m_ble_display_c.uuid_type                      = BLE_UUID_TYPE_BLE;
    
        return ble_db_discovery_evt_register(&srvc_uuid);
    }

    Thank you,

    - Matt

  • As I examined the logs, I observed variances highlighted in the screenshots. Notably, there's a differences in the response to a GATT primary service declaration request. I speculate whether the issue revolves around the 128-bit UUID response. Given that this UUID is categorized as a SIG base UUID, could it be plausible that the Softdevice is encountering parsing difficulties?

  • Thanks for providing the HCI log. This confirms that Device B is responding with the 128-bit UUID in the type response, rather than the 16-bit UUID like device A, which might be confusing the SoftDevice. 

    Could you try to discover 'ALL' services using the SD API directly, as shown in the message sequence chart (GATTC Primary Service Discovery)? This might be a possible workaround that will allow you to find the attribute handles despite the non-standard use of UUIDs by Device B.

  • Vidar,

    Thank you for confirming the problem and offering a suggestion. Although I'm not familiar with the suggested approach, I did some research in the SDK documentation and found the blue_app_interactive example. Do you think this would be a good starting point for implementing the recommended solution?

    nRF5_SDK_17.1.0_ddde560/examples/ble_central_and_peripheral/experimental/ble_app_interactive

    - Matt

  • Matt,

    I cannot confirm with 100% certainty that this is why service discovery is failing, as I do not have a GATT server that would provide the same 'Read by Group Type' response as your 'Device B'. However, I believe it's the most likely explanation. In any case, I'm hoping you can work around the problem by using the other discovery method that the 'ble_app_interactive' example uses.

    -Vidar

  • Vidar,

    I have made some progress in resolving this issue, but I encountered another problem and have opened a new ticket for it.

    https://devzone.nordicsemi.com/f/nordic-q-a/113066/gatt-service-discovery---hard-fault

Reply Children
No Data
Related