| /** @file |
| * @brief Generic Attribute Profile handling. |
| */ |
| |
| /* |
| * Copyright (c) 2015-2016 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| #ifndef ZEPHYR_INCLUDE_BLUETOOTH_GATT_H_ |
| #define ZEPHYR_INCLUDE_BLUETOOTH_GATT_H_ |
| |
| /** |
| * @brief Generic Attribute Profile (GATT) |
| * @defgroup bt_gatt Generic Attribute Profile (GATT) |
| * @ingroup bluetooth |
| * @{ |
| */ |
| |
| #include <stddef.h> |
| #include <sys/slist.h> |
| #include <sys/types.h> |
| #include <sys/util.h> |
| #include <bluetooth/conn.h> |
| #include <bluetooth/uuid.h> |
| #include <bluetooth/att.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** GATT attribute permission bit field values */ |
| enum { |
| /** No operations supported, e.g. for notify-only */ |
| BT_GATT_PERM_NONE = 0, |
| |
| /** Attribute read permission. */ |
| BT_GATT_PERM_READ = BIT(0), |
| |
| /** Attribute write permission. */ |
| BT_GATT_PERM_WRITE = BIT(1), |
| |
| /** @brief Attribute read permission with encryption. |
| * |
| * If set, requires encryption for read access. |
| */ |
| BT_GATT_PERM_READ_ENCRYPT = BIT(2), |
| |
| /** @brief Attribute write permission with encryption. |
| * |
| * If set, requires encryption for write access. |
| */ |
| BT_GATT_PERM_WRITE_ENCRYPT = BIT(3), |
| |
| /** @brief Attribute read permission with authentication. |
| * |
| * If set, requires encryption using authenticated link-key for read |
| * access. |
| */ |
| BT_GATT_PERM_READ_AUTHEN = BIT(4), |
| |
| /** @brief Attribute write permission with authentication. |
| * |
| * If set, requires encryption using authenticated link-key for write |
| * access. |
| */ |
| BT_GATT_PERM_WRITE_AUTHEN = BIT(5), |
| |
| /** @brief Attribute prepare write permission. |
| * |
| * If set, allows prepare writes with use of BT_GATT_WRITE_FLAG_PREPARE |
| * passed to write callback. |
| */ |
| BT_GATT_PERM_PREPARE_WRITE = BIT(6), |
| }; |
| |
| /** @def BT_GATT_ERR |
| * @brief Construct error return value for attribute read and write callbacks. |
| * |
| * @param _att_err ATT error code |
| * |
| * @return Appropriate error code for the attribute callbacks. |
| */ |
| #define BT_GATT_ERR(_att_err) (-(_att_err)) |
| |
| /** GATT attribute write flags */ |
| enum { |
| /** @brief Attribute prepare write flag |
| * |
| * If set, write callback should only check if the device is |
| * authorized but no data shall be written. |
| */ |
| BT_GATT_WRITE_FLAG_PREPARE = BIT(0), |
| |
| /** @brief Attribute write command flag |
| * |
| * If set, indicates that write operation is a command (Write without |
| * response) which doesn't generate any response. |
| */ |
| BT_GATT_WRITE_FLAG_CMD = BIT(1), |
| }; |
| |
| /** @brief GATT Attribute structure. */ |
| struct bt_gatt_attr { |
| /** Attribute UUID */ |
| const struct bt_uuid *uuid; |
| |
| /** @brief Attribute read callback |
| * |
| * The callback can also be used locally to read the contents of the |
| * attribute in which case no connection will be set. |
| * |
| * @param conn The connection that is requesting to read |
| * @param attr The attribute that's being read |
| * @param buf Buffer to place the read result in |
| * @param len Length of data to read |
| * @param offset Offset to start reading from |
| * |
| * @return Number fo bytes read, or in case of an error |
| * BT_GATT_ERR() with a specific ATT error code. |
| */ |
| ssize_t (*read)(struct bt_conn *conn, const struct bt_gatt_attr *attr, |
| void *buf, uint16_t len, uint16_t offset); |
| |
| /** @brief Attribute write callback |
| * |
| * @param conn The connection that is requesting to write |
| * @param attr The attribute that's being written |
| * @param buf Buffer with the data to write |
| * @param len Number of bytes in the buffer |
| * @param offset Offset to start writing from |
| * @param flags Flags (BT_GATT_WRITE_*) |
| * |
| * @return Number of bytes written, or in case of an error |
| * BT_GATT_ERR() with a specific ATT error code. |
| */ |
| ssize_t (*write)(struct bt_conn *conn, const struct bt_gatt_attr *attr, |
| const void *buf, uint16_t len, uint16_t offset, |
| uint8_t flags); |
| |
| /** Attribute user data */ |
| void *user_data; |
| /** Attribute handle */ |
| uint16_t handle; |
| /** Attribute permissions */ |
| uint8_t perm; |
| }; |
| |
| /** @brief GATT Service structure */ |
| struct bt_gatt_service_static { |
| /** Service Attributes */ |
| const struct bt_gatt_attr *attrs; |
| /** Service Attribute count */ |
| size_t attr_count; |
| }; |
| |
| /** @brief GATT Service structure */ |
| struct bt_gatt_service { |
| /** Service Attributes */ |
| struct bt_gatt_attr *attrs; |
| /** Service Attribute count */ |
| size_t attr_count; |
| |
| sys_snode_t node; |
| }; |
| |
| /** @brief Service Attribute Value. */ |
| struct bt_gatt_service_val { |
| /** Service UUID. */ |
| const struct bt_uuid *uuid; |
| /** Service end handle. */ |
| uint16_t end_handle; |
| }; |
| |
| /** @brief Include Attribute Value. */ |
| struct bt_gatt_include { |
| /** Service UUID. */ |
| const struct bt_uuid *uuid; |
| /** Service start handle. */ |
| uint16_t start_handle; |
| /** Service end handle. */ |
| uint16_t end_handle; |
| }; |
| |
| /** @brief GATT callback structure. */ |
| struct bt_gatt_cb { |
| /** @brief The maximum ATT MTU on a connection has changed. |
| * |
| * This callback notifies the application that the maximum TX or RX |
| * ATT MTU has increased. |
| * |
| * @param conn Connection object. |
| * @param tx Updated TX ATT MTU. |
| * @param rx Updated RX ATT MTU. |
| */ |
| void (*att_mtu_updated)(struct bt_conn *conn, uint16_t tx, uint16_t rx); |
| |
| sys_snode_t node; |
| }; |
| |
| /** Characteristic Properties Bit field values */ |
| |
| /** @def BT_GATT_CHRC_BROADCAST |
| * @brief Characteristic broadcast property. |
| * |
| * If set, permits broadcasts of the Characteristic Value using Server |
| * Characteristic Configuration Descriptor. |
| */ |
| #define BT_GATT_CHRC_BROADCAST 0x01 |
| /** @def BT_GATT_CHRC_READ |
| * @brief Characteristic read property. |
| * |
| * If set, permits reads of the Characteristic Value. |
| */ |
| #define BT_GATT_CHRC_READ 0x02 |
| /** @def BT_GATT_CHRC_WRITE_WITHOUT_RESP |
| * @brief Characteristic write without response property. |
| * |
| * If set, permits write of the Characteristic Value without response. |
| */ |
| #define BT_GATT_CHRC_WRITE_WITHOUT_RESP 0x04 |
| /** @def BT_GATT_CHRC_WRITE |
| * @brief Characteristic write with response property. |
| * |
| * If set, permits write of the Characteristic Value with response. |
| */ |
| #define BT_GATT_CHRC_WRITE 0x08 |
| /** @def BT_GATT_CHRC_NOTIFY |
| * @brief Characteristic notify property. |
| * |
| * If set, permits notifications of a Characteristic Value without |
| * acknowledgment. |
| */ |
| #define BT_GATT_CHRC_NOTIFY 0x10 |
| /** @def BT_GATT_CHRC_INDICATE |
| * @brief Characteristic indicate property. |
| * |
| * If set, permits indications of a Characteristic Value with acknowledgment. |
| */ |
| #define BT_GATT_CHRC_INDICATE 0x20 |
| /** @def BT_GATT_CHRC_AUTH |
| * @brief Characteristic Authenticated Signed Writes property. |
| * |
| * If set, permits signed writes to the Characteristic Value. |
| */ |
| #define BT_GATT_CHRC_AUTH 0x40 |
| /** @def BT_GATT_CHRC_EXT_PROP |
| * @brief Characteristic Extended Properties property. |
| * |
| * If set, additional characteristic properties are defined in the |
| * Characteristic Extended Properties Descriptor. |
| */ |
| #define BT_GATT_CHRC_EXT_PROP 0x80 |
| |
| /** @brief Characteristic Attribute Value. */ |
| struct bt_gatt_chrc { |
| /** Characteristic UUID. */ |
| const struct bt_uuid *uuid; |
| /** Characteristic Value handle. */ |
| uint16_t value_handle; |
| /** Characteristic properties. */ |
| uint8_t properties; |
| }; |
| |
| /** Characteristic Extended Properties Bit field values */ |
| #define BT_GATT_CEP_RELIABLE_WRITE 0x0001 |
| #define BT_GATT_CEP_WRITABLE_AUX 0x0002 |
| |
| /** @brief Characteristic Extended Properties Attribute Value. */ |
| struct bt_gatt_cep { |
| /** Characteristic Extended properties */ |
| uint16_t properties; |
| }; |
| |
| /** Client Characteristic Configuration Values */ |
| |
| /** @def BT_GATT_CCC_NOTIFY |
| * @brief Client Characteristic Configuration Notification. |
| * |
| * If set, changes to Characteristic Value shall be notified. |
| */ |
| #define BT_GATT_CCC_NOTIFY 0x0001 |
| /** @def BT_GATT_CCC_INDICATE |
| * @brief Client Characteristic Configuration Indication. |
| * |
| * If set, changes to Characteristic Value shall be indicated. |
| */ |
| #define BT_GATT_CCC_INDICATE 0x0002 |
| |
| /** Client Characteristic Configuration Attribute Value */ |
| struct bt_gatt_ccc { |
| /** Client Characteristic Configuration flags */ |
| uint16_t flags; |
| }; |
| |
| /** Server Characteristic Configuration Values */ |
| |
| /** @def BT_GATT_SCC_BROADCAST |
| * @brief Server Characteristic Configuration Broadcast |
| * |
| * If set, the characteristic value shall be broadcast in the advertising data |
| * when the server is advertising. |
| */ |
| #define BT_GATT_SCC_BROADCAST 0x0001 |
| |
| /** Server Characterestic Configuration Attribute Value */ |
| struct bt_gatt_scc { |
| /** Server Characteristic Configuration flags */ |
| uint16_t flags; |
| }; |
| |
| /** @brief GATT Characteristic Presentation Format Attribute Value. */ |
| struct bt_gatt_cpf { |
| /** Format of the value of the characteristic */ |
| uint8_t format; |
| /** Exponent field to determine how the value of this characteristic is |
| * further formatted |
| */ |
| int8_t exponent; |
| /** Unit of the characteristic */ |
| uint16_t unit; |
| /** Name space of the description */ |
| uint8_t name_space; |
| /** Description of the characteristic as defined in a higher layer profile */ |
| uint16_t description; |
| }; |
| |
| /** |
| * @defgroup bt_gatt_server GATT Server APIs |
| * @ingroup bt_gatt |
| * @{ |
| */ |
| |
| /** @brief Register GATT callbacks. |
| * |
| * Register callbacks to monitor the state of GATT. |
| * |
| * @param cb Callback struct. |
| */ |
| void bt_gatt_cb_register(struct bt_gatt_cb *cb); |
| |
| /** @brief Register GATT service. |
| * |
| * Register GATT service. Applications can make use of |
| * macros such as BT_GATT_PRIMARY_SERVICE, BT_GATT_CHARACTERISTIC, |
| * BT_GATT_DESCRIPTOR, etc. |
| * |
| * When using @kconfig{CONFIG_BT_SETTINGS} then all services that should have |
| * bond configuration loaded, i.e. CCC values, must be registered before |
| * calling @ref settings_load. |
| * |
| * When using @kconfig{CONFIG_BT_GATT_CACHING} and @kconfig{CONFIG_BT_SETTINGS} |
| * then all services that should be included in the GATT Database Hash |
| * calculation should be added before calling @ref settings_load. |
| * All services registered after settings_load will trigger a new database hash |
| * calculation and a new hash stored. |
| * |
| * @param svc Service containing the available attributes |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_service_register(struct bt_gatt_service *svc); |
| |
| /** @brief Unregister GATT service. |
| * * |
| * @param svc Service to be unregistered. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_service_unregister(struct bt_gatt_service *svc); |
| |
| enum { |
| BT_GATT_ITER_STOP = 0, |
| BT_GATT_ITER_CONTINUE, |
| }; |
| |
| /** @typedef bt_gatt_attr_func_t |
| * @brief Attribute iterator callback. |
| * |
| * @param attr Attribute found. |
| * @param handle Attribute handle found. |
| * @param user_data Data given. |
| * |
| * @return BT_GATT_ITER_CONTINUE if should continue to the next attribute. |
| * @return BT_GATT_ITER_STOP to stop. |
| */ |
| typedef uint8_t (*bt_gatt_attr_func_t)(const struct bt_gatt_attr *attr, |
| uint16_t handle, |
| void *user_data); |
| |
| /** @brief Attribute iterator by type. |
| * |
| * Iterate attributes in the given range matching given UUID and/or data. |
| * |
| * @param start_handle Start handle. |
| * @param end_handle End handle. |
| * @param uuid UUID to match, passing NULL skips UUID matching. |
| * @param attr_data Attribute data to match, passing NULL skips data matching. |
| * @param num_matches Number matches, passing 0 makes it unlimited. |
| * @param func Callback function. |
| * @param user_data Data to pass to the callback. |
| */ |
| void bt_gatt_foreach_attr_type(uint16_t start_handle, uint16_t end_handle, |
| const struct bt_uuid *uuid, |
| const void *attr_data, uint16_t num_matches, |
| bt_gatt_attr_func_t func, |
| void *user_data); |
| |
| /** @brief Attribute iterator. |
| * |
| * Iterate attributes in the given range. |
| * |
| * @param start_handle Start handle. |
| * @param end_handle End handle. |
| * @param func Callback function. |
| * @param user_data Data to pass to the callback. |
| */ |
| static inline void bt_gatt_foreach_attr(uint16_t start_handle, uint16_t end_handle, |
| bt_gatt_attr_func_t func, |
| void *user_data) |
| { |
| bt_gatt_foreach_attr_type(start_handle, end_handle, NULL, NULL, 0, func, |
| user_data); |
| } |
| |
| /** @brief Iterate to the next attribute |
| * |
| * Iterate to the next attribute following a given attribute. |
| * |
| * @param attr Current Attribute. |
| * |
| * @return The next attribute or NULL if it cannot be found. |
| */ |
| struct bt_gatt_attr *bt_gatt_attr_next(const struct bt_gatt_attr *attr); |
| |
| /** @brief Find Attribute by UUID. |
| * |
| * Find the attribute with the matching UUID. |
| * To limit the search to a service set the attr to the service attributes and |
| * the attr_count to the service attribute count . |
| * |
| * @param attr Pointer to an attribute that serves as the starting point |
| * for the search of a match for the UUID. |
| * Passing NULL will search the entire range. |
| * @param attr_count The number of attributes from the starting point to |
| * search for a match for the UUID. |
| * Set to 0 to search until the end. |
| * @param uuid UUID to match. |
| */ |
| struct bt_gatt_attr *bt_gatt_find_by_uuid(const struct bt_gatt_attr *attr, |
| uint16_t attr_count, |
| const struct bt_uuid *uuid); |
| |
| /** @brief Get Attribute handle. |
| * |
| * @param attr Attribute object. |
| * |
| * @return Handle of the corresponding attribute or zero if the attribute |
| * could not be found. |
| */ |
| uint16_t bt_gatt_attr_get_handle(const struct bt_gatt_attr *attr); |
| |
| /** @brief Get the handle of the characteristic value descriptor. |
| * |
| * @param attr A Characteristic Attribute. |
| * |
| * @note The user_data of the attribute must of type @ref bt_gatt_chrc. |
| * |
| * @return the handle of the corresponding Characteristic Value. The value will |
| * be zero (the invalid handle) if @p attr was not a characteristic |
| * attribute. |
| */ |
| uint16_t bt_gatt_attr_value_handle(const struct bt_gatt_attr *attr); |
| |
| /** @brief Generic Read Attribute value helper. |
| * |
| * Read attribute value from local database storing the result into buffer. |
| * |
| * @param conn Connection object. |
| * @param attr Attribute to read. |
| * @param buf Buffer to store the value. |
| * @param buf_len Buffer length. |
| * @param offset Start offset. |
| * @param value Attribute value. |
| * @param value_len Length of the attribute value. |
| * |
| * @return number of bytes read in case of success or negative values in |
| * case of error. |
| */ |
| ssize_t bt_gatt_attr_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, |
| void *buf, uint16_t buf_len, uint16_t offset, |
| const void *value, uint16_t value_len); |
| |
| /** @brief Read Service Attribute helper. |
| * |
| * Read service attribute value from local database storing the result into |
| * buffer after encoding it. |
| * @note Only use this with attributes which user_data is a bt_uuid. |
| * |
| * @param conn Connection object. |
| * @param attr Attribute to read. |
| * @param buf Buffer to store the value read. |
| * @param len Buffer length. |
| * @param offset Start offset. |
| * |
| * @return number of bytes read in case of success or negative values in |
| * case of error. |
| */ |
| ssize_t bt_gatt_attr_read_service(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, |
| void *buf, uint16_t len, uint16_t offset); |
| |
| /** @def BT_GATT_SERVICE_DEFINE |
| * @brief Statically define and register a service. |
| * |
| * Helper macro to statically define and register a service. |
| * |
| * @param _name Service name. |
| */ |
| #define BT_GATT_SERVICE_DEFINE(_name, ...) \ |
| const struct bt_gatt_attr attr_##_name[] = { __VA_ARGS__ }; \ |
| const STRUCT_SECTION_ITERABLE(bt_gatt_service_static, _name) = \ |
| BT_GATT_SERVICE(attr_##_name) |
| |
| #define _BT_GATT_ATTRS_ARRAY_DEFINE(n, _instances, _attrs_def) \ |
| static struct bt_gatt_attr attrs_##n[] = _attrs_def(_instances[n]); |
| |
| #define _BT_GATT_SERVICE_ARRAY_ITEM(_n, _) BT_GATT_SERVICE(attrs_##_n), |
| |
| /** @def BT_GATT_SERVICE_INSTANCE_DEFINE |
| * @brief Statically define service structure array. |
| * |
| * Helper macro to statically define service structure array. Each element |
| * of the array is linked to the service attribute array which is also |
| * defined in this scope using _attrs_def macro. |
| * |
| * @param _name Name of service structure array. |
| * @param _instances Array of instances to pass as user context to the |
| * attribute callbacks. |
| * @param _instance_num Number of elements in instance array. |
| * @param _attrs_def Macro provided by the user that defines attribute |
| * array for the serivce. This macro should accept single |
| * parameter which is the instance context. |
| */ |
| #define BT_GATT_SERVICE_INSTANCE_DEFINE( \ |
| _name, _instances, _instance_num, _attrs_def) \ |
| BUILD_ASSERT(ARRAY_SIZE(_instances) == _instance_num, \ |
| "The number of array elements does not match its size"); \ |
| UTIL_EVAL(UTIL_REPEAT( \ |
| _instance_num, _BT_GATT_ATTRS_ARRAY_DEFINE, _instances, \ |
| _attrs_def)) \ |
| static struct bt_gatt_service _name[] = { \ |
| UTIL_LISTIFY(_instance_num, _BT_GATT_SERVICE_ARRAY_ITEM) \ |
| } |
| |
| /** @def BT_GATT_SERVICE |
| * @brief Service Structure Declaration Macro. |
| * |
| * Helper macro to declare a service structure. |
| * |
| * @param _attrs Service attributes. |
| */ |
| #define BT_GATT_SERVICE(_attrs) \ |
| { \ |
| .attrs = _attrs, \ |
| .attr_count = ARRAY_SIZE(_attrs), \ |
| } |
| |
| /** @def BT_GATT_PRIMARY_SERVICE |
| * @brief Primary Service Declaration Macro. |
| * |
| * Helper macro to declare a primary service attribute. |
| * |
| * @param _service Service attribute value. |
| */ |
| #define BT_GATT_PRIMARY_SERVICE(_service) \ |
| BT_GATT_ATTRIBUTE(BT_UUID_GATT_PRIMARY, BT_GATT_PERM_READ, \ |
| bt_gatt_attr_read_service, NULL, _service) |
| |
| /** @def BT_GATT_SECONDARY_SERVICE |
| * @brief Secondary Service Declaration Macro. |
| * |
| * Helper macro to declare a secondary service attribute. |
| * |
| * @param _service Service attribute value. |
| */ |
| #define BT_GATT_SECONDARY_SERVICE(_service) \ |
| BT_GATT_ATTRIBUTE(BT_UUID_GATT_SECONDARY, BT_GATT_PERM_READ, \ |
| bt_gatt_attr_read_service, NULL, _service) |
| |
| /** @brief Read Include Attribute helper. |
| * |
| * Read include service attribute value from local database storing the result |
| * into buffer after encoding it. |
| * @note Only use this with attributes which user_data is a bt_gatt_include. |
| * |
| * @param conn Connection object. |
| * @param attr Attribute to read. |
| * @param buf Buffer to store the value read. |
| * @param len Buffer length. |
| * @param offset Start offset. |
| * |
| * @return number of bytes read in case of success or negative values in |
| * case of error. |
| */ |
| ssize_t bt_gatt_attr_read_included(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, |
| void *buf, uint16_t len, uint16_t offset); |
| |
| /** @def BT_GATT_INCLUDE_SERVICE |
| * @brief Include Service Declaration Macro. |
| * |
| * Helper macro to declare database internal include service attribute. |
| * |
| * @param _service_incl the first service attribute of service to include |
| */ |
| #define BT_GATT_INCLUDE_SERVICE(_service_incl) \ |
| BT_GATT_ATTRIBUTE(BT_UUID_GATT_INCLUDE, BT_GATT_PERM_READ, \ |
| bt_gatt_attr_read_included, NULL, _service_incl) |
| |
| /** @brief Read Characteristic Attribute helper. |
| * |
| * Read characteristic attribute value from local database storing the result |
| * into buffer after encoding it. |
| * @note Only use this with attributes which user_data is a bt_gatt_chrc. |
| * |
| * @param conn Connection object. |
| * @param attr Attribute to read. |
| * @param buf Buffer to store the value read. |
| * @param len Buffer length. |
| * @param offset Start offset. |
| * |
| * @return number of bytes read in case of success or negative values in |
| * case of error. |
| */ |
| ssize_t bt_gatt_attr_read_chrc(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, void *buf, |
| uint16_t len, uint16_t offset); |
| |
| #define BT_GATT_CHRC_INIT(_uuid, _handle, _props) \ |
| { \ |
| .uuid = _uuid, \ |
| .value_handle = _handle, \ |
| .properties = _props, \ |
| } |
| |
| /** @def BT_GATT_CHARACTERISTIC |
| * @brief Characteristic and Value Declaration Macro. |
| * |
| * Helper macro to declare a characteristic attribute along with its |
| * attribute value. |
| * |
| * @param _uuid Characteristic attribute uuid. |
| * @param _props Characteristic attribute properties. |
| * @param _perm Characteristic Attribute access permissions. |
| * @param _read Characteristic Attribute read callback. |
| * @param _write Characteristic Attribute write callback. |
| * @param _user_data Characteristic Attribute user data. |
| */ |
| #define BT_GATT_CHARACTERISTIC(_uuid, _props, _perm, _read, _write, _user_data) \ |
| BT_GATT_ATTRIBUTE(BT_UUID_GATT_CHRC, BT_GATT_PERM_READ, \ |
| bt_gatt_attr_read_chrc, NULL, \ |
| ((struct bt_gatt_chrc[]) { \ |
| BT_GATT_CHRC_INIT(_uuid, 0U, _props), \ |
| })), \ |
| BT_GATT_ATTRIBUTE(_uuid, _perm, _read, _write, _user_data) |
| |
| #if defined(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING) |
| #define BT_GATT_CCC_MAX (CONFIG_BT_MAX_CONN) |
| #elif defined(CONFIG_BT_CONN) |
| #define BT_GATT_CCC_MAX (CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN) |
| #else |
| #define BT_GATT_CCC_MAX 0 |
| #endif |
| |
| /** @brief GATT CCC configuration entry. */ |
| struct bt_gatt_ccc_cfg { |
| /** Local identity, BT_ID_DEFAULT in most cases. */ |
| uint8_t id; |
| /** Remote peer address. */ |
| bt_addr_le_t peer; |
| /** Configuration value. */ |
| uint16_t value; |
| }; |
| |
| /** Internal representation of CCC value */ |
| struct _bt_gatt_ccc { |
| /** Configuration for each connection */ |
| struct bt_gatt_ccc_cfg cfg[BT_GATT_CCC_MAX]; |
| |
| /** Highest value of all connected peer's subscriptions */ |
| uint16_t value; |
| |
| /** @brief CCC attribute changed callback |
| * |
| * @param attr The attribute that's changed value |
| * @param value New value |
| */ |
| void (*cfg_changed)(const struct bt_gatt_attr *attr, uint16_t value); |
| |
| /** @brief CCC attribute write validation callback |
| * |
| * @param conn The connection that is requesting to write |
| * @param attr The attribute that's being written |
| * @param value CCC value to write |
| * |
| * @return Number of bytes to write, or in case of an error |
| * BT_GATT_ERR() with a specific error code. |
| */ |
| ssize_t (*cfg_write)(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, uint16_t value); |
| |
| /** @brief CCC attribute match handler |
| * |
| * Indicate if it is OK to send a notification or indication |
| * to the subscriber. |
| * |
| * @param conn The connection that is being checked |
| * @param attr The attribute that's being checked |
| * |
| * @return true if application has approved notification/indication, |
| * false if application does not approve. |
| */ |
| bool (*cfg_match)(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr); |
| }; |
| |
| /** @brief Read Client Characteristic Configuration Attribute helper. |
| * |
| * Read CCC attribute value from local database storing the result into buffer |
| * after encoding it. |
| * |
| * @note Only use this with attributes which user_data is a _bt_gatt_ccc. |
| * |
| * @param conn Connection object. |
| * @param attr Attribute to read. |
| * @param buf Buffer to store the value read. |
| * @param len Buffer length. |
| * @param offset Start offset. |
| * |
| * @return number of bytes read in case of success or negative values in |
| * case of error. |
| */ |
| ssize_t bt_gatt_attr_read_ccc(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, void *buf, |
| uint16_t len, uint16_t offset); |
| |
| /** @brief Write Client Characteristic Configuration Attribute helper. |
| * |
| * Write value in the buffer into CCC attribute. |
| * |
| * @note Only use this with attributes which user_data is a _bt_gatt_ccc. |
| * |
| * @param conn Connection object. |
| * @param attr Attribute to read. |
| * @param buf Buffer to store the value read. |
| * @param len Buffer length. |
| * @param offset Start offset. |
| * @param flags Write flags. |
| * |
| * @return number of bytes written in case of success or negative values in |
| * case of error. |
| */ |
| ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, const void *buf, |
| uint16_t len, uint16_t offset, uint8_t flags); |
| |
| |
| /** @def BT_GATT_CCC_INITIALIZER |
| * @brief Initialize Client Characteristic Configuration Declaration Macro. |
| * |
| * Helper macro to initialize a Managed CCC attribute value. |
| * |
| * @param _changed Configuration changed callback. |
| * @param _write Configuration write callback. |
| * @param _match Configuration match callback. |
| */ |
| #define BT_GATT_CCC_INITIALIZER(_changed, _write, _match) \ |
| { \ |
| .cfg = {}, \ |
| .cfg_changed = _changed, \ |
| .cfg_write = _write, \ |
| .cfg_match = _match, \ |
| } |
| |
| /** @def BT_GATT_CCC_MANAGED |
| * @brief Managed Client Characteristic Configuration Declaration Macro. |
| * |
| * Helper macro to declare a Managed CCC attribute. |
| * |
| * @param _ccc CCC attribute user data, shall point to a _bt_gatt_ccc. |
| * @param _perm CCC access permissions. |
| */ |
| #define BT_GATT_CCC_MANAGED(_ccc, _perm) \ |
| BT_GATT_ATTRIBUTE(BT_UUID_GATT_CCC, _perm, \ |
| bt_gatt_attr_read_ccc, bt_gatt_attr_write_ccc, \ |
| _ccc) |
| |
| /** @def BT_GATT_CCC |
| * @brief Client Characteristic Configuration Declaration Macro. |
| * |
| * Helper macro to declare a CCC attribute. |
| * |
| * @param _changed Configuration changed callback. |
| * @param _perm CCC access permissions. |
| */ |
| #define BT_GATT_CCC(_changed, _perm) \ |
| BT_GATT_CCC_MANAGED(((struct _bt_gatt_ccc[]) \ |
| {BT_GATT_CCC_INITIALIZER(_changed, NULL, NULL)}), _perm) |
| |
| /** @brief Read Characteristic Extended Properties Attribute helper |
| * |
| * Read CEP attribute value from local database storing the result into buffer |
| * after encoding it. |
| * |
| * @note Only use this with attributes which user_data is a bt_gatt_cep. |
| * |
| * @param conn Connection object |
| * @param attr Attribute to read |
| * @param buf Buffer to store the value read |
| * @param len Buffer length |
| * @param offset Start offset |
| * |
| * @return number of bytes read in case of success or negative values in |
| * case of error. |
| */ |
| ssize_t bt_gatt_attr_read_cep(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, void *buf, |
| uint16_t len, uint16_t offset); |
| |
| /** @def BT_GATT_CEP |
| * @brief Characteristic Extended Properties Declaration Macro. |
| * |
| * Helper macro to declare a CEP attribute. |
| * |
| * @param _value Pointer to a struct bt_gatt_cep. |
| */ |
| #define BT_GATT_CEP(_value) \ |
| BT_GATT_DESCRIPTOR(BT_UUID_GATT_CEP, BT_GATT_PERM_READ, \ |
| bt_gatt_attr_read_cep, NULL, (void *)_value) |
| |
| /** @brief Read Characteristic User Description Descriptor Attribute helper |
| * |
| * Read CUD attribute value from local database storing the result into buffer |
| * after encoding it. |
| * |
| * @note Only use this with attributes which user_data is a NULL-terminated C |
| * string. |
| * |
| * @param conn Connection object |
| * @param attr Attribute to read |
| * @param buf Buffer to store the value read |
| * @param len Buffer length |
| * @param offset Start offset |
| * |
| * @return number of bytes read in case of success or negative values in |
| * case of error. |
| */ |
| ssize_t bt_gatt_attr_read_cud(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, void *buf, |
| uint16_t len, uint16_t offset); |
| |
| /** @def BT_GATT_CUD |
| * @brief Characteristic User Format Descriptor Declaration Macro. |
| * |
| * Helper macro to declare a CUD attribute. |
| * |
| * @param _value User description NULL-terminated C string. |
| * @param _perm Descriptor attribute access permissions. |
| */ |
| #define BT_GATT_CUD(_value, _perm) \ |
| BT_GATT_DESCRIPTOR(BT_UUID_GATT_CUD, _perm, bt_gatt_attr_read_cud, \ |
| NULL, (void *)_value) |
| |
| /** @brief Read Characteristic Presentation format Descriptor Attribute helper |
| * |
| * Read CPF attribute value from local database storing the result into buffer |
| * after encoding it. |
| * |
| * @note Only use this with attributes which user_data is a bt_gatt_pf. |
| * |
| * @param conn Connection object |
| * @param attr Attribute to read |
| * @param buf Buffer to store the value read |
| * @param len Buffer length |
| * @param offset Start offset |
| * |
| * @return number of bytes read in case of success or negative values in |
| * case of error. |
| */ |
| ssize_t bt_gatt_attr_read_cpf(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, void *buf, |
| uint16_t len, uint16_t offset); |
| |
| /** @def BT_GATT_CPF |
| * @brief Characteristic Presentation Format Descriptor Declaration Macro. |
| * |
| * Helper macro to declare a CPF attribute. |
| * |
| * @param _value Pointer to a struct bt_gatt_cpf. |
| */ |
| #define BT_GATT_CPF(_value) \ |
| BT_GATT_DESCRIPTOR(BT_UUID_GATT_CPF, BT_GATT_PERM_READ, \ |
| bt_gatt_attr_read_cpf, NULL, (void *)_value) |
| |
| /** @def BT_GATT_DESCRIPTOR |
| * @brief Descriptor Declaration Macro. |
| * |
| * Helper macro to declare a descriptor attribute. |
| * |
| * @param _uuid Descriptor attribute uuid. |
| * @param _perm Descriptor attribute access permissions. |
| * @param _read Descriptor attribute read callback. |
| * @param _write Descriptor attribute write callback. |
| * @param _user_data Descriptor attribute user data. |
| */ |
| #define BT_GATT_DESCRIPTOR(_uuid, _perm, _read, _write, _user_data) \ |
| BT_GATT_ATTRIBUTE(_uuid, _perm, _read, _write, _user_data) |
| |
| /** @def BT_GATT_ATTRIBUTE |
| * @brief Attribute Declaration Macro. |
| * |
| * Helper macro to declare an attribute. |
| * |
| * @param _uuid Attribute uuid. |
| * @param _perm Attribute access permissions. |
| * @param _read Attribute read callback. |
| * @param _write Attribute write callback. |
| * @param _user_data Attribute user data. |
| */ |
| #define BT_GATT_ATTRIBUTE(_uuid, _perm, _read, _write, _user_data) \ |
| { \ |
| .uuid = _uuid, \ |
| .read = _read, \ |
| .write = _write, \ |
| .user_data = _user_data, \ |
| .handle = 0, \ |
| .perm = _perm, \ |
| } |
| |
| /** @brief Notification complete result callback. |
| * |
| * @param conn Connection object. |
| * @param user_data Data passed in by the user. |
| */ |
| typedef void (*bt_gatt_complete_func_t) (struct bt_conn *conn, void *user_data); |
| |
| struct bt_gatt_notify_params { |
| /** @brief Notification Attribute UUID type |
| * |
| * Optional, use to search for an attribute with matching UUID when |
| * the attribute object pointer is not known. |
| */ |
| const struct bt_uuid *uuid; |
| /** @brief Notification Attribute object |
| * |
| * Optional if uuid is provided, in this case it will be used as start |
| * range to search for the attribute with the given UUID. |
| */ |
| const struct bt_gatt_attr *attr; |
| /** Notification Value data */ |
| const void *data; |
| /** Notification Value length */ |
| uint16_t len; |
| /** Notification Value callback */ |
| bt_gatt_complete_func_t func; |
| /** Notification Value callback user data */ |
| void *user_data; |
| }; |
| |
| /** @brief Notify attribute value change. |
| * |
| * This function works in the same way as @ref bt_gatt_notify. |
| * With the addition that after sending the notification the |
| * callback function will be called. |
| * |
| * The callback is run from System Workqueue context. |
| * When called from the System Workqueue context this API will not wait for |
| * resources for the callback but instead return an error. |
| * The number of pending callbacks can be increased with the |
| * @kconfig{CONFIG_BT_CONN_TX_MAX} option. |
| * |
| * Alternatively it is possible to notify by UUID by setting it on the |
| * parameters, when using this method the attribute if provided is used as the |
| * start range when looking up for possible matches. |
| * |
| * @param conn Connection object. |
| * @param params Notification parameters. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_notify_cb(struct bt_conn *conn, |
| struct bt_gatt_notify_params *params); |
| |
| /** @brief Notify multiple attribute value change. |
| * |
| * This function works in the same way as @ref bt_gatt_notify_cb. |
| * |
| * @param conn Connection object. |
| * @param num_params Number of notification parameters. |
| * @param params Array of notification parameters. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_notify_multiple(struct bt_conn *conn, uint16_t num_params, |
| struct bt_gatt_notify_params *params); |
| |
| /** @brief Notify attribute value change. |
| * |
| * Send notification of attribute value change, if connection is NULL notify |
| * all peer that have notification enabled via CCC otherwise do a direct |
| * notification only the given connection. |
| * |
| * The attribute object on the parameters can be the so called Characteristic |
| * Declaration, which is usually declared with BT_GATT_CHARACTERISTIC followed |
| * by BT_GATT_CCC, or the Characteristic Value Declaration which is |
| * automatically created after the Characteristic Declaration when using |
| * BT_GATT_CHARACTERISTIC. |
| * |
| * @param conn Connection object. |
| * @param attr Characteristic or Characteristic Value attribute. |
| * @param data Pointer to Attribute data. |
| * @param len Attribute value length. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| static inline int bt_gatt_notify(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, |
| const void *data, uint16_t len) |
| { |
| struct bt_gatt_notify_params params; |
| |
| memset(¶ms, 0, sizeof(params)); |
| |
| params.attr = attr; |
| params.data = data; |
| params.len = len; |
| |
| return bt_gatt_notify_cb(conn, ¶ms); |
| } |
| |
| /** @brief Notify attribute value change by UUID. |
| * |
| * Send notification of attribute value change, if connection is NULL notify |
| * all peer that have notification enabled via CCC otherwise do a direct |
| * notification only on the given connection. |
| * |
| * The attribute object is the starting point for the search of the UUID. |
| * |
| * @param conn Connection object. |
| * @param uuid The UUID. If the server contains multiple services with the same |
| * UUID, then the first occurrence, starting from the attr given, |
| * is used. |
| * @param attr Pointer to an attribute that serves as the starting point for |
| * the search of a match for the UUID. |
| * @param data Pointer to Attribute data. |
| * @param len Attribute value length. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| static inline int bt_gatt_notify_uuid(struct bt_conn *conn, |
| const struct bt_uuid *uuid, |
| const struct bt_gatt_attr *attr, |
| const void *data, uint16_t len) |
| { |
| struct bt_gatt_notify_params params; |
| |
| memset(¶ms, 0, sizeof(params)); |
| |
| params.uuid = uuid; |
| params.attr = attr; |
| params.data = data; |
| params.len = len; |
| |
| return bt_gatt_notify_cb(conn, ¶ms); |
| } |
| |
| /* Forward declaration of the bt_gatt_indicate_params structure */ |
| struct bt_gatt_indicate_params; |
| |
| /** @typedef bt_gatt_indicate_func_t |
| * @brief Indication complete result callback. |
| * |
| * @param conn Connection object. |
| * @param params Indication params object. |
| * @param err ATT error code |
| */ |
| typedef void (*bt_gatt_indicate_func_t)(struct bt_conn *conn, |
| struct bt_gatt_indicate_params *params, |
| uint8_t err); |
| |
| typedef void (*bt_gatt_indicate_params_destroy_t)( |
| struct bt_gatt_indicate_params *params); |
| |
| /** @brief GATT Indicate Value parameters */ |
| struct bt_gatt_indicate_params { |
| /** @brief Indicate Attribute UUID type |
| * |
| * Optional, use to search for an attribute with matching UUID when |
| * the attribute object pointer is not known. |
| */ |
| const struct bt_uuid *uuid; |
| /** @brief Indicate Attribute object |
| * |
| * Optional if uuid is provided, in this case it will be used as start |
| * range to search for the attribute with the given UUID. |
| */ |
| const struct bt_gatt_attr *attr; |
| /** Indicate Value callback */ |
| bt_gatt_indicate_func_t func; |
| /** Indicate operation complete callback */ |
| bt_gatt_indicate_params_destroy_t destroy; |
| /** Indicate Value data*/ |
| const void *data; |
| /** Indicate Value length*/ |
| uint16_t len; |
| /** Private reference counter */ |
| uint8_t _ref; |
| }; |
| |
| /** @brief Indicate attribute value change. |
| * |
| * Send an indication of attribute value change. if connection is NULL |
| * indicate all peer that have notification enabled via CCC otherwise do a |
| * direct indication only the given connection. |
| * |
| * The attribute object on the parameters can be the so called Characteristic |
| * Declaration, which is usually declared with BT_GATT_CHARACTERISTIC followed |
| * by BT_GATT_CCC, or the Characteristic Value Declaration which is |
| * automatically created after the Characteristic Declaration when using |
| * BT_GATT_CHARACTERISTIC. |
| * |
| * Alternatively it is possible to indicate by UUID by setting it on the |
| * parameters, when using this method the attribute if provided is used as the |
| * start range when looking up for possible matches. |
| * |
| * @note This procedure is asynchronous therefore the parameters need to |
| * remains valid while it is active. The procedure is active until |
| * the destroy callback is run. |
| * |
| * @param conn Connection object. |
| * @param params Indicate parameters. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_indicate(struct bt_conn *conn, |
| struct bt_gatt_indicate_params *params); |
| |
| |
| /** @brief Check if connection have subscribed to attribute |
| * |
| * Check if connection has subscribed to attribute value change. |
| * |
| * The attribute object can be the so called Characteristic Declaration, |
| * which is usually declared with BT_GATT_CHARACTERISTIC followed |
| * by BT_GATT_CCC, or the Characteristic Value Declaration which is |
| * automatically created after the Characteristic Declaration when using |
| * BT_GATT_CHARACTERISTIC, or the Client Characteristic Configuration |
| * Descriptor (CCCD) which is created by BT_GATT_CCC. |
| * |
| * @param conn Connection object. |
| * @param attr Attribute object. |
| * @param ccc_value The subscription type, either notifications or indications. |
| * |
| * @return true if the attribute object has been subscribed. |
| */ |
| bool bt_gatt_is_subscribed(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, uint16_t ccc_value); |
| |
| /** @brief Get ATT MTU for a connection |
| * |
| * Get negotiated ATT connection MTU, note that this does not equal the largest |
| * amount of attribute data that can be transferred within a single packet. |
| * |
| * @param conn Connection object. |
| * |
| * @return MTU in bytes |
| */ |
| uint16_t bt_gatt_get_mtu(struct bt_conn *conn); |
| |
| /** @} */ |
| |
| /** |
| * @defgroup bt_gatt_client GATT Client APIs |
| * @ingroup bt_gatt |
| * @{ |
| */ |
| |
| /** @brief GATT Exchange MTU parameters */ |
| struct bt_gatt_exchange_params { |
| /** Response callback */ |
| void (*func)(struct bt_conn *conn, uint8_t err, |
| struct bt_gatt_exchange_params *params); |
| }; |
| |
| /** @brief Exchange MTU |
| * |
| * This client procedure can be used to set the MTU to the maximum possible |
| * size the buffers can hold. |
| * |
| * @note Shall only be used once per connection. |
| * |
| * @param conn Connection object. |
| * @param params Exchange MTU parameters. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_exchange_mtu(struct bt_conn *conn, |
| struct bt_gatt_exchange_params *params); |
| |
| struct bt_gatt_discover_params; |
| |
| /** @typedef bt_gatt_discover_func_t |
| * @brief Discover attribute callback function. |
| * |
| * @param conn Connection object. |
| * @param attr Attribute found, or NULL if not found. |
| * @param params Discovery parameters given. |
| * |
| * If discovery procedure has completed this callback will be called with |
| * attr set to NULL. This will not happen if procedure was stopped by returning |
| * BT_GATT_ITER_STOP. |
| * |
| * The attribute object as well as its UUID and value objects are temporary and |
| * must be copied to in order to cache its information. |
| * Only the following fields of the attribute contains valid information: |
| * - uuid UUID representing the type of attribute. |
| * - handle Handle in the remote database. |
| * - user_data The value of the attribute. |
| * Will be NULL when discovering descriptors |
| * |
| * To be able to read the value of the discovered attribute the user_data |
| * must be cast to an appropriate type. |
| * - @ref bt_gatt_service_val when UUID is @ref BT_UUID_GATT_PRIMARY or |
| * @ref BT_UUID_GATT_SECONDARY. |
| * - @ref bt_gatt_include when UUID is @ref BT_UUID_GATT_INCLUDE. |
| * - @ref bt_gatt_chrc when UUID is @ref BT_UUID_GATT_CHRC. |
| * |
| * @return BT_GATT_ITER_CONTINUE to continue discovery procedure. |
| * @return BT_GATT_ITER_STOP to stop discovery procedure. |
| */ |
| typedef uint8_t (*bt_gatt_discover_func_t)(struct bt_conn *conn, |
| const struct bt_gatt_attr *attr, |
| struct bt_gatt_discover_params *params); |
| |
| /** GATT Discover types */ |
| enum { |
| /** Discover Primary Services. */ |
| BT_GATT_DISCOVER_PRIMARY, |
| /** Discover Secondary Services. */ |
| BT_GATT_DISCOVER_SECONDARY, |
| /** Discover Included Services. */ |
| BT_GATT_DISCOVER_INCLUDE, |
| /** @brief Discover Characteristic Values. |
| * |
| * Discover Characteristic Value and its properties. |
| */ |
| BT_GATT_DISCOVER_CHARACTERISTIC, |
| /** @brief Discover Descriptors. |
| * |
| * Discover Attributes which are not services or characteristics. |
| * |
| * @note The use of this type of discover is not recommended for |
| * discovering in ranges across multiple services/characteristics |
| * as it may incur in extra round trips. |
| */ |
| BT_GATT_DISCOVER_DESCRIPTOR, |
| /** @brief Discover Attributes. |
| * |
| * Discover Attributes of any type. |
| * |
| * @note The use of this type of discover is not recommended for |
| * discovering in ranges across multiple services/characteristics |
| * as it may incur in more round trips. |
| */ |
| BT_GATT_DISCOVER_ATTRIBUTE, |
| /** @brief Discover standard characteristic descriptor values. |
| * |
| * Discover standard characterestic descriptor values and their |
| * properties. |
| * Supported descriptors: |
| * - Characteristic Extended Properties |
| * - Client Characteristic Configuration |
| * - Server Characteristic Configuration |
| * - Characteristic Presentation Format |
| */ |
| BT_GATT_DISCOVER_STD_CHAR_DESC, |
| }; |
| |
| /** @brief GATT Discover Attributes parameters */ |
| struct bt_gatt_discover_params { |
| /** Discover UUID type */ |
| const struct bt_uuid *uuid; |
| /** Discover attribute callback */ |
| bt_gatt_discover_func_t func; |
| union { |
| struct { |
| /** Include service attribute declaration handle */ |
| uint16_t attr_handle; |
| /** Included service start handle */ |
| uint16_t start_handle; |
| /** Included service end handle */ |
| uint16_t end_handle; |
| } _included; |
| /** Discover start handle */ |
| uint16_t start_handle; |
| }; |
| /** Discover end handle */ |
| uint16_t end_handle; |
| /** Discover type */ |
| uint8_t type; |
| #if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC) |
| /** Only for stack-internal use, used for automatic discovery. */ |
| struct bt_gatt_subscribe_params *sub_params; |
| #endif /* defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC) */ |
| }; |
| |
| /** @brief GATT Discover function |
| * |
| * This procedure is used by a client to discover attributes on a server. |
| * |
| * Primary Service Discovery: Procedure allows to discover specific Primary |
| * Service based on UUID. |
| * Include Service Discovery: Procedure allows to discover all Include Services |
| * within specified range. |
| * Characteristic Discovery: Procedure allows to discover all characteristics |
| * within specified handle range as well as |
| * discover characteristics with specified UUID. |
| * Descriptors Discovery: Procedure allows to discover all characteristic |
| * descriptors within specified range. |
| * |
| * For each attribute found the callback is called which can then decide |
| * whether to continue discovering or stop. |
| * |
| * @note This procedure is asynchronous therefore the parameters need to |
| * remains valid while it is active. |
| * |
| * @param conn Connection object. |
| * @param params Discover parameters. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_discover(struct bt_conn *conn, |
| struct bt_gatt_discover_params *params); |
| |
| struct bt_gatt_read_params; |
| |
| /** @typedef bt_gatt_read_func_t |
| * @brief Read callback function |
| * |
| * @param conn Connection object. |
| * @param err ATT error code. |
| * @param params Read parameters used. |
| * @param data Attribute value data. NULL means read has completed. |
| * @param length Attribute value length. |
| * |
| * @return BT_GATT_ITER_CONTINUE if should continue to the next attribute. |
| * @return BT_GATT_ITER_STOP to stop. |
| */ |
| typedef uint8_t (*bt_gatt_read_func_t)(struct bt_conn *conn, uint8_t err, |
| struct bt_gatt_read_params *params, |
| const void *data, uint16_t length); |
| |
| /** @brief GATT Read parameters */ |
| struct bt_gatt_read_params { |
| /** Read attribute callback. */ |
| bt_gatt_read_func_t func; |
| /** If equals to 1 single.handle and single.offset are used. |
| * If greater than 1 multiple.handles are used. |
| * If equals to 0 by_uuid is used for Read Using Characteristic UUID. |
| */ |
| size_t handle_count; |
| union { |
| struct { |
| /** Attribute handle. */ |
| uint16_t handle; |
| /** Attribute data offset. */ |
| uint16_t offset; |
| } single; |
| struct { |
| /** Attribute handles to read with Read Multiple |
| * Characteristic Values. |
| */ |
| uint16_t *handles; |
| /** If true use Read Multiple Variable Length |
| * Characteristic Values procedure. |
| * The values of the set of attributes may be of |
| * variable or unknown length. |
| * If false use Read Multiple Characteristic Values |
| * procedure. |
| * The values of the set of attributes must be of a |
| * known fixed length, with the exception of the last |
| * value that can have a variable length. |
| */ |
| bool variable; |
| } multiple; |
| struct { |
| /** First requested handle number. */ |
| uint16_t start_handle; |
| /** Last requested handle number. */ |
| uint16_t end_handle; |
| /** 2 or 16 octet UUID. */ |
| const struct bt_uuid *uuid; |
| } by_uuid; |
| }; |
| }; |
| |
| /** @brief Read Attribute Value by handle |
| * |
| * This procedure read the attribute value and return it to the callback. |
| * |
| * When reading attributes by UUID the callback can be called multiple times |
| * depending on how many instances of given the UUID exists with the |
| * start_handle being updated for each instance. |
| * |
| * If an instance does contain a long value which cannot be read entirely the |
| * caller will need to read the remaining data separately using the handle and |
| * offset. |
| * |
| * @note This procedure is asynchronous therefore the parameters need to |
| * remains valid while it is active. |
| * |
| * @param conn Connection object. |
| * @param params Read parameters. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_read(struct bt_conn *conn, struct bt_gatt_read_params *params); |
| |
| struct bt_gatt_write_params; |
| |
| /** @typedef bt_gatt_write_func_t |
| * @brief Write callback function |
| * |
| * @param conn Connection object. |
| * @param err ATT error code. |
| * @param params Write parameters used. |
| */ |
| typedef void (*bt_gatt_write_func_t)(struct bt_conn *conn, uint8_t err, |
| struct bt_gatt_write_params *params); |
| |
| /** @brief GATT Write parameters */ |
| struct bt_gatt_write_params { |
| /** Response callback */ |
| bt_gatt_write_func_t func; |
| /** Attribute handle */ |
| uint16_t handle; |
| /** Attribute data offset */ |
| uint16_t offset; |
| /** Data to be written */ |
| const void *data; |
| /** Length of the data */ |
| uint16_t length; |
| }; |
| |
| /** @brief Write Attribute Value by handle |
| * |
| * This procedure write the attribute value and return the result in the |
| * callback. |
| * |
| * @note This procedure is asynchronous therefore the parameters need to |
| * remains valid while it is active. |
| * |
| * @param conn Connection object. |
| * @param params Write parameters. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params); |
| |
| /** @brief Write Attribute Value by handle without response with callback. |
| * |
| * This function works in the same way as @ref bt_gatt_write_without_response. |
| * With the addition that after sending the write the callback function will be |
| * called. |
| * |
| * The callback is run from System Workqueue context. |
| * When called from the System Workqueue context this API will not wait for |
| * resources for the callback but instead return an error. |
| * The number of pending callbacks can be increased with the |
| * @kconfig{CONFIG_BT_CONN_TX_MAX} option. |
| |
| * |
| * @note By using a callback it also disable the internal flow control |
| * which would prevent sending multiple commands without waiting for |
| * their transmissions to complete, so if that is required the caller |
| * shall not submit more data until the callback is called. |
| * |
| * @param conn Connection object. |
| * @param handle Attribute handle. |
| * @param data Data to be written. |
| * @param length Data length. |
| * @param sign Whether to sign data |
| * @param func Transmission complete callback. |
| * @param user_data User data to be passed back to callback. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_write_without_response_cb(struct bt_conn *conn, uint16_t handle, |
| const void *data, uint16_t length, |
| bool sign, bt_gatt_complete_func_t func, |
| void *user_data); |
| |
| /** @brief Write Attribute Value by handle without response |
| * |
| * This procedure write the attribute value without requiring an |
| * acknowledgment that the write was successfully performed |
| * |
| * @param conn Connection object. |
| * @param handle Attribute handle. |
| * @param data Data to be written. |
| * @param length Data length. |
| * @param sign Whether to sign data |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| static inline int bt_gatt_write_without_response(struct bt_conn *conn, |
| uint16_t handle, const void *data, |
| uint16_t length, bool sign) |
| { |
| return bt_gatt_write_without_response_cb(conn, handle, data, length, |
| sign, NULL, NULL); |
| } |
| |
| struct bt_gatt_subscribe_params; |
| |
| /** @typedef bt_gatt_notify_func_t |
| * @brief Notification callback function |
| * |
| * In the case of an empty notification, the @p data pointer will be non-NULL |
| * while the @p length will be 0, which is due to the special case where |
| * a @p data NULL pointer means unsubscribed. |
| * |
| * @param conn Connection object. May be NULL, indicating that the peer is |
| * being unpaired |
| * @param params Subscription parameters. |
| * @param data Attribute value data. If NULL then subscription was removed. |
| * @param length Attribute value length. |
| * |
| * @return BT_GATT_ITER_CONTINUE to continue receiving value notifications. |
| * BT_GATT_ITER_STOP to unsubscribe from value notifications. |
| */ |
| typedef uint8_t (*bt_gatt_notify_func_t)(struct bt_conn *conn, |
| struct bt_gatt_subscribe_params *params, |
| const void *data, uint16_t length); |
| |
| /** Subscription flags */ |
| enum { |
| /** @brief Persistence flag |
| * |
| * If set, indicates that the subscription is not saved |
| * on the GATT server side. Therefore, upon disconnection, |
| * the subscription will be automatically removed |
| * from the client's subscriptions list and |
| * when the client reconnects, it will have to |
| * issue a new subscription. |
| */ |
| BT_GATT_SUBSCRIBE_FLAG_VOLATILE, |
| |
| /** @brief No resubscribe flag |
| * |
| * By default when BT_GATT_SUBSCRIBE_FLAG_VOLATILE is unset, the |
| * subscription will be automatically renewed when the client |
| * reconnects, as a workaround for GATT servers that do not persist |
| * subscriptions. |
| * |
| * This flag will disable the automatic resubscription. It is useful |
| * if the application layer knows that the GATT server remembers |
| * subscriptions from previous connections and wants to avoid renewing |
| * the subscriptions. |
| */ |
| BT_GATT_SUBSCRIBE_FLAG_NO_RESUB, |
| |
| /** @brief Write pending flag |
| * |
| * If set, indicates write operation is pending waiting remote end to |
| * respond. |
| */ |
| BT_GATT_SUBSCRIBE_FLAG_WRITE_PENDING, |
| |
| BT_GATT_SUBSCRIBE_NUM_FLAGS |
| }; |
| |
| /** @brief GATT Subscribe parameters */ |
| struct bt_gatt_subscribe_params { |
| /** Notification value callback */ |
| bt_gatt_notify_func_t notify; |
| /** Subscribe CCC write request response callback */ |
| bt_gatt_write_func_t write; |
| /** Subscribe value handle */ |
| uint16_t value_handle; |
| /** Subscribe CCC handle */ |
| uint16_t ccc_handle; |
| #if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC) |
| /** Subscribe End handle (for automatic discovery) */ |
| uint16_t end_handle; |
| /** Discover parameters used when ccc_handle = 0 */ |
| struct bt_gatt_discover_params *disc_params; |
| #endif /* CONFIG_BT_GATT_AUTO_DISCOVER_CCC */ |
| /** Subscribe value */ |
| uint16_t value; |
| /** Subscription flags */ |
| ATOMIC_DEFINE(flags, BT_GATT_SUBSCRIBE_NUM_FLAGS); |
| |
| sys_snode_t node; |
| }; |
| |
| /** @brief Subscribe Attribute Value Notification |
| * |
| * This procedure subscribe to value notification using the Client |
| * Characteristic Configuration handle. |
| * If notification received subscribe value callback is called to return |
| * notified value. One may then decide whether to unsubscribe directly from |
| * this callback. Notification callback with NULL data will not be called if |
| * subscription was removed by this method. |
| * |
| * @note Notifications are asynchronous therefore the parameters need to |
| * remain valid while subscribed. |
| * |
| * @param conn Connection object. |
| * @param params Subscribe parameters. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_subscribe(struct bt_conn *conn, |
| struct bt_gatt_subscribe_params *params); |
| |
| /** @brief Resubscribe Attribute Value Notification subscription |
| * |
| * Resubscribe to Attribute Value Notification when already subscribed from a |
| * previous connection. The GATT server will remember subscription from |
| * previous connections when bonded, so resubscribing can be done without |
| * performing a new subscribe procedure after a power cycle. |
| * |
| * @note Notifications are asynchronous therefore the parameters need to |
| * remain valid while subscribed. |
| * |
| * @param id Local identity (in most cases BT_ID_DEFAULT). |
| * @param peer Remote address. |
| * @param params Subscribe parameters. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_resubscribe(uint8_t id, const bt_addr_le_t *peer, |
| struct bt_gatt_subscribe_params *params); |
| |
| /** @brief Unsubscribe Attribute Value Notification |
| * |
| * This procedure unsubscribe to value notification using the Client |
| * Characteristic Configuration handle. Notification callback with NULL data |
| * will be called if subscription was removed by this call, until then the |
| * parameters cannot be reused. |
| * |
| * @param conn Connection object. |
| * @param params Subscribe parameters. |
| * |
| * @return 0 in case of success or negative value in case of error. |
| */ |
| int bt_gatt_unsubscribe(struct bt_conn *conn, |
| struct bt_gatt_subscribe_params *params); |
| |
| /** @brief Cancel GATT pending request |
| * |
| * @param conn Connection object. |
| * @param params Requested params address. |
| */ |
| void bt_gatt_cancel(struct bt_conn *conn, void *params); |
| |
| /** @} */ |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| /** |
| * @} |
| */ |
| |
| #endif /* ZEPHYR_INCLUDE_BLUETOOTH_GATT_H_ */ |