GATT Discovery Manager

The GATT Discovery Manager handles service discovery on GATT servers.

When a client connects to a peer device that has a desired server, service discovery is necessary to ensure that the client interacts with the server’s characteristics using the correct attributes handles. Service discovery is also important because Bluetooth LE advertising does not mandate that all services are advertised. To actually know if a service is present on a peer device, you must perform a service discovery.

The GATT Discovery Manager simplifies the usage of Zephyr’s bt_gatt_discover() function by processing the data using predefined filters.

The GATT Discovery Manager is used, for example, in the Bluetooth: Central HIDS sample.

Limitations

  • Only one discovery procedure can be running at the same time.

API documentation

Header file: include/bluetooth/gatt_dm.h
Source file: subsys/bluetooth/gatt_dm.c
group bt_gatt_dm

Module for GATT Discovery Manager.

Functions

struct bt_gatt_service_val *bt_gatt_dm_attr_service_val(const struct bt_gatt_dm_attr *attr)

Access service value saved with service attribute.

This function access the service value parsed and saved previously in the user_data attribute field.

Note

Use it only on the attribute parsed in this module. To access service attribute use bt_gatt_dm_service_get function.

Return

The service value from the parsed attribute or NULL when attribute UUID value is unexpected.

Parameters
  • [in] attr: Service attribute

struct bt_gatt_chrc *bt_gatt_dm_attr_chrc_val(const struct bt_gatt_dm_attr *attr)

Access characteristic value saved with characteristic attribute.

This function access the characteristic value parsed and saved previously in the user_data attribute field.

Note

Use it only on the attribute parsed in this module. To access characteristic attribute use bt_gatt_dm_char_next function.

Return

The characteristic value from parser attribute or NULL when attribute UUID value is unexpected.

Parameters
  • [in] attr: Characteristic attribute

struct bt_conn *bt_gatt_dm_conn_get(struct bt_gatt_dm *dm)

Get the connection object.

Function returns connection object that is used by given discovery manager instance.

Return

Connection object.

Parameters
  • [in] dm: Discovery Manager instance

size_t bt_gatt_dm_attr_cnt(const struct bt_gatt_dm *dm)

Get total number of attributes decoded.

The number of attributes including the service attribute. It means that service without any attribute would return 1 here.

Return

Total number of attributes parsed.

Parameters
  • [in] dm: Discovery Manager instance.

const struct bt_gatt_dm_attr *bt_gatt_dm_service_get(const struct bt_gatt_dm *dm)

Get service value.

Function returns the value that contains UUID and attribute end handler of the service found.

Return

The pointer service value structure.

Parameters
  • [in] dm: Discovery Manager instance.

const struct bt_gatt_dm_attr *bt_gatt_dm_char_next(const struct bt_gatt_dm *dm, const struct bt_gatt_dm_attr *prev)

Get next characteristic.

Return

The pointer for an attribute that describes the characteristic or NULL if no more characteristic is present.

Parameters
  • [in] dm: Discovery Manager instance.

  • [in] prev: An attribute where start to search. If NULL - the first characteristic in the service would be found. Note: It can be the previous characteristic attribute or the last descriptor inside the previous attribute. Function would start searching for the next characteristic from that point.

const struct bt_gatt_dm_attr *bt_gatt_dm_char_by_uuid(const struct bt_gatt_dm *dm, const struct bt_uuid *uuid)

Get the characteristic by its UUID.

Function finds characteristic attribute by the UUID stored in its characteristic value. If the selected characteristic is not found in parsed service it returns NULL.

Return

The characteristic attribute (the one with UUID set to BT_UUID_GATT_CHRC) with the selected UUID inside the characteristic value. Returns NULL if no such characteristic is present in the current service.

Parameters
  • [in] dm: Discovery instance

  • [in] uuid: The UUID of the characteristic

const struct bt_gatt_dm_attr *bt_gatt_dm_attr_by_handle(const struct bt_gatt_dm *dm, uint16_t handle)

Get attribute by handle.

Function returns any type of the attribute using its handle.

Return

The pointer to the attribute or NULL if there is no attribute with such a pointer.

Parameters
  • [in] dm: Discovery Manager instance.

  • [in] handle: The handle to find

const struct bt_gatt_dm_attr *bt_gatt_dm_attr_next(const struct bt_gatt_dm *dm, const struct bt_gatt_dm_attr *prev)

Get next attribute.

Function returns the attribute next to the given one. It returns any type of the attribute.

Return

Attribute next to the prev or the first attribute if NULL is given.

Parameters
  • [in] dm: Discovery Manager instance.

  • [in] prev: Previous attribute or NULL if we wish to get first attribute (just after service).

const struct bt_gatt_dm_attr *bt_gatt_dm_desc_by_uuid(const struct bt_gatt_dm *dm, const struct bt_gatt_dm_attr *attr_chrc, const struct bt_uuid *uuid)

Search the descriptor by UUID.

Function searches for the descriptor with given UUID inside given characteristic.

Return

Pointer to the attribute or NULL if the attribute cannot be found.

Parameters
  • [in] dm: Discovery Manager instance.

  • [in] attr_chrc: The characteristic attribute where to search

  • [in] uuid: The UUID of the searched descriptor.

const struct bt_gatt_dm_attr *bt_gatt_dm_desc_next(const struct bt_gatt_dm *dm, const struct bt_gatt_dm_attr *prev)

Get next descriptor.

Function returns next descriptor. The difference between this function and bt_gatt_dm_attr_next is that it returns NULL also when returned attribute appears to be next characteristic.

Return

The pointer to the descriptor attribute or NULL if there is no more descriptors in the characteristic.

Parameters
  • [in] dm: Discovery Manager instance.

  • [in] prev: Previous attribute. The characteristic if we wish to get first descriptor or previous descriptor. If NULL or pointer to service attribute is given the result is undefined.

int bt_gatt_dm_start(struct bt_conn *conn, const struct bt_uuid *svc_uuid, const struct bt_gatt_dm_cb *cb, void *context)

Start service discovery.

This function is asynchronous. Discovery results are passed through the supplied callback.

Note

Only one discovery procedure can be started simultaneously. To start another one, wait for the result of the previous procedure to finish and call bt_gatt_dm_data_release if it was successful.

Note

If svc_uuid is set to NULL, all services may be discovered. To process the next service, call bt_gatt_dm_continue.

Parameters
  • [in] conn: Connection object.

  • [in] svc_uuid: UUID of target service or NULL if any service should be discovered.

  • [in] cb: Callback structure.

  • [inout] context: Context argument to be passed to callback functions.

Return Value
  • 0: If the operation was successful. Otherwise, a (negative) error code is returned.

int bt_gatt_dm_continue(struct bt_gatt_dm *dm, void *context)

Continue service discovery.

This function continues service discovery. Call it after the previous data was released by bt_gatt_dm_data_release.

Parameters
  • [inout] dm: Discovery Manager instance.

  • [in] context: Context argument to be passed to callback functions.

Return Value
  • 0: If the operation was successful. Otherwise, a (negative) error code is returned.

int bt_gatt_dm_data_release(struct bt_gatt_dm *dm)

Release data associated with service discovery.

After calling this function, you cannot rely on the discovery data that was passed with the discovery completed callback (see bt_gatt_dm_cb).

Parameters
  • [in] dm: Discovery Manager instance

Return Value
  • 0: If the operation was successful. Otherwise, a (negative) error code is returned.

static inline void bt_gatt_dm_data_print(const struct bt_gatt_dm *dm)

Print service discovery data.

This function prints GATT attributes that belong to the discovered service.

Parameters
  • [in] dm: Discovery Manager instance

struct bt_gatt_dm_attr
#include <gatt_dm.h>

Discovery Manager GATT attribute.

This structure is used to hold GATT attribute information. The Discovery Manager attribute descriptor is a reduced version of bt_gatt_attr. The new definition is used to save memory that is used by this module.

Public Members

struct bt_uuid *uuid

Attribute UUID

uint16_t handle

Attribute handle

uint8_t perm

Attribute permissions

struct bt_gatt_dm_cb
#include <gatt_dm.h>

Discovery callback structure.

This structure is used for tracking the result of a discovery.

Public Members

void (*completed)(struct bt_gatt_dm *dm, void *context)

Discovery completed callback.

The discovery procedure has completed successfully.

Note

You must release the discovery data with bt_gatt_dm_data_release if you want to start another discovery.

Parameters
  • [inout] dm: Discovery Manager instance

  • [inout] context: The value passed to gatt_db_discovery_start()

void (*service_not_found)(struct bt_conn *conn, void *context)

Service not found callback.

The targeted service could not be found during the discovery.

Parameters
  • [inout] conn: Connection object.

  • [inout] context: The value passed to gatt_db_discovery_start()

void (*error_found)(struct bt_conn *conn, int err, void *context)

Discovery error found callback.

The discovery procedure has failed.

Parameters
  • [inout] conn: Connection object.

  • [in] err: The error code.

  • [inout] context: The value passed to gatt_db_discovery_start()