Discovery in nRF Connect/Zephyr as *discovery*

Hi, I'm new to nRF Connect, coming from the SDK. I'm building a Central/Peripheral system and I've got to the point where the Central is discovering what services and attributes the Peripheral provides.

The only Zephyr samples in which discovery is being performed is central_hr and central_ht. In both of these, the uuid of the bt_gatt_discover_params is being loaded with the UUID of the service and characteristic that it is looking for. This isn't really *discovery*, not like, say, the nRF Connect tool which upon connecting to an advertising device figures out the service UUID and the characteristic UUIDs without prior knowledge. Now, _that_ is *discovery*. But I figured out that the bt_gatt_discover() subsystem can be used as *discovery* by supplying NULL to the uuid member of bt_gatt_discover_params.

When I do this, the bt_gatt_discover_func_t callback gets called with a bt_gatt_attr argument that includes uuid and a user_data members. The table under the bt_gatt_discover_func_t description indicates what user_data is going to be.

So, I start with looking for what services are offered by my device (there's only one). Call bt_gatt_discover() with the uuid pointer of bt_gatt_discover_params set to NULL and type set to BT_GATT_DISCOVER_PRIMARY. When the callback is called, attr->uuid is a 16-bit UUID with value 0x2800, or BT_UUID_GATT_PRIMARY. Good. Per the table, user_data is a bt_gatt_service_val, and the uuid member of user_data is a 16-bit UUID with value 0x1801, or BT_UUID_GATT. This is true, but unhelpful. I was expecting the UUID of the service. This seems wrong.

Then I look for the characteristics. Call bt_gatt_discover() with the uuid pointer of bt_gatt_discover_params set to NULL and type set to BT_GATT_DISCOVER_CHARACTERISTIC. When the callback is called, attr->uuid is a 16-bit UUID with value 0x2803, or BT_UUID_GATT_CHRC. Good. Per the table, user_data is a bt_gatt_chrc, and the uuid member of user_data is the UUID I assigned to my characteristics. This is the expected behavior. Good.

Then I look for the CCCDs. Call bt_gatt_discover() with the uuid pointer of bt_gatt_discover_params set to NULL and type set to BT_GATT_DISCOVER_STD_CHAR_DESC. This results in bt_gatt_discover() returning a EINVAL error. Even though this type is in the bt_gatt_discover_func_t description. This also seems wrong.  Okay, then I'll follow the central_ht sample and use BT_GATT_DISCOVER_DESCRIPTOR. No error, and the callback function gets called. Per the table, user_data is supposed to be NULL, so I don't bother to look at it. Instead, attr->uuid contains the UUID of the custom service characteristic that "owns" this CCCD. Unexpected, undocumented, but I can go with that.

I'm not at a disadvantage with not getting the service UUID out of discovery, since the provided services are supposed to be in the advertising data, but I would have expected discovery to return the service UUID all the same. Is this a bug, or expected behavior?

Parents Reply Children
Related