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

BLE GATTC questions

2 Questions, both short:

1. Documentation error in Softdevice 15.x and 14.x header files:

/** @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
 *       type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
*/
ble_vs_uuids_assign() does not exist anywhere in the softdevice headers nor in any of the examples/components code.
Based on reading other related Q&A posts this function should be ble_vs_uuid_add(). Is that correct?

2. And now for some real disappointment on my end:

a. It appears that a generic Service Discovery Protocol cannot be written against the softdevice. The UUIDs need to be known ahead of time and if they are not defined then client UUIDs can never be discovered via SDP. True or False?

b. If 2.a. above is True then it appears that this deficiency is purely derived from the attempt at keeping an internal database within the softdevice of all VS (vendor specific 128-bit) UUIDs. And that was motivated by wanting to conserve RAM through the use of 16-bit UUIDs wherever possible. True or False?

This works fine if you are writing a GATT Server (which I would guess is 99% of the use cases out there).

But if you are writing a generic GATT Client, this not only a real disappointment but gratuitously unnecessary. I can see no reason why the GATTC service discovery calls

sd_ble_gattc_primary_services_discover()
sd_ble_gattc_relationships_discover()
sd_ble_gattc_characteristics_discover()
... etc ...

Should not return full 128-bit UUIDs even for registered Bluetooth SIG services and characteristics. These are stack variables and need not be stored by the client in their full 128-bit form. Let the choice be that of the developer writing the softdevice client code.

Correct me where I am wrong.

Thanks. I will go lie down in deep depression.

Parents
  • Hi,

    I've stumbled over the same "issue". The same problem arrises, when discovering services. And in that context, I've learned that `sd_ble_gattc_attr_info_discover()` might be used to retrieve the 128 bit UUID of a service (https://devzone.nordicsemi.com/f/nordic-q-a/37916/how-can-i-get-the-primary-service-uuid/146211#146211). The documentation of `sd_ble_gattc_attr_info_discover()`is a little vague, as it does not define, which (and if) GATT procedure is used (and which handle would have to be provided in case of a characteristic, the Characteristic Declaration, the Characteristic Value?). In theory, it should be possible to get the UUID by ATT read the Characteristic Declaration attribute, but the SD provides not access to the ATT layer (but, of cause the mapping for reads between ATT and GATT is pretty trivial).

    So, I also would be interested, if there is a way to discover 128 bit UUID characteristics without knowing the UUID ahead.

    have you solved that problem?

    Do you have an answer?

    best regards,

    Torsten

Reply
  • Hi,

    I've stumbled over the same "issue". The same problem arrises, when discovering services. And in that context, I've learned that `sd_ble_gattc_attr_info_discover()` might be used to retrieve the 128 bit UUID of a service (https://devzone.nordicsemi.com/f/nordic-q-a/37916/how-can-i-get-the-primary-service-uuid/146211#146211). The documentation of `sd_ble_gattc_attr_info_discover()`is a little vague, as it does not define, which (and if) GATT procedure is used (and which handle would have to be provided in case of a characteristic, the Characteristic Declaration, the Characteristic Value?). In theory, it should be possible to get the UUID by ATT read the Characteristic Declaration attribute, but the SD provides not access to the ATT layer (but, of cause the mapping for reads between ATT and GATT is pretty trivial).

    So, I also would be interested, if there is a way to discover 128 bit UUID characteristics without knowing the UUID ahead.

    have you solved that problem?

    Do you have an answer?

    best regards,

    Torsten

Children
  • As a hobby project, which I have not had time for in the last year, I play with these Nordic boards.

    Here is a link to the answer somewhere else in this Q/A forum:

  • Thanks! What a hassle ;-) I think this should also apply to characteristic discovery.

  • I recall reading in a Nordic press release over the last  year that they have fixed this issue.

    Since I don't have to time play with the Nordic stuff these days, I did not dig into it.

    But searching through the SDK, version 17.0.2 I found this:

    Line 378 of file: nRF5_SDK_17.0.2_d674dde/components/softdevice/s132/headers/ble_gattc.h

    /**@brief UUID discovery option.
     *
     * @details Used with @ref sd_ble_opt_set to enable and disable automatic insertion of discovered 128-bit UUIDs to the
     *          Vendor Specific UUID table. Disabled by default.
     *          - When disabled, if a procedure initiated by
     *            @ref sd_ble_gattc_primary_services_discover,
     *            @ref sd_ble_gattc_relationships_discover,
     *            @ref sd_ble_gattc_characteristics_discover,
     *            @ref sd_ble_gattc_descriptors_discover
     *            finds a 128-bit UUID which was not added by @ref sd_ble_uuid_vs_add, @ref ble_uuid_t::type will be set
     *            to @ref BLE_UUID_TYPE_UNKNOWN in the corresponding event.
     *          - When enabled, all found 128-bit UUIDs will be automatically added. The application can use
     *            @ref sd_ble_uuid_encode to retrieve the 128-bit UUID from @ref ble_uuid_t received in the corresponding
     *            event. If the total number of Vendor Specific UUIDs exceeds the table capacity, @ref ble_uuid_t::type will
     *            be set to @ref BLE_UUID_TYPE_UNKNOWN in the corresponding event.
     *            See also @ref ble_common_cfg_vs_uuid_t, @ref sd_ble_uuid_vs_remove.
     *
     * @note @ref sd_ble_opt_get is not supported for this option.
     *
     * @retval ::NRF_SUCCESS Set successfully.
     *
     */
    typedef struct
    {
      uint8_t auto_add_vs_enable : 1;   /**< Set to 1 to enable (or 0 to disable) automatic insertion of discovered 128-bit UUIDs. */
    } ble_gattc_opt_uuid_disc_t;

    So my guess is that this can be done more efficiently than the solution that I referenced. Note what it says:

    "The drawback of this solution is that there are exactly two more command-response GATT messages which makes Service Discovery longer by at least 4 connection intervals per unknown 128-bit UUID entries."

    A small price to pay really. But here it looks like Nordic has solved the issue. I hope that this simple method works for you!

  • Ah, ok. I'm currently with Version 16.x. The problem with the solution is, that it allocates resources (UUID slots) which one is not able to deallocate (`sd_ble_uuid_vs_remove´seems to be pretty useless).

  • Yes, I would expect there to be an allocated 128-bit UUID during discovery. It would have to keep it around as well for the lifetime of the connection since it will have to match any associated updates to data with the UUID.

Related