Bluetooth: Gatt: Automatic discover of CCC when subscribing
Added a feature that allows an application to request automatic discovery of the CCCD handle when subscriping to a characteristic. In order to preserver RAM, the application is expected to provide the discovery parameters, and it's up to the application whether or not it wants to reuse the discovery parameters or use one for each characteristic. Signed-off-by: Emil Gydesen <emil_gydesen@bose.com>
This commit is contained in:
parent
820d17110d
commit
5b59c002f6
5 changed files with 98 additions and 0 deletions
|
@ -1145,6 +1145,10 @@ struct bt_gatt_discover_params {
|
|||
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
|
||||
|
@ -1400,6 +1404,12 @@ struct bt_gatt_subscribe_params {
|
|||
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 */
|
||||
|
|
|
@ -137,6 +137,13 @@ config BT_GATT_READ_MULTIPLE
|
|||
This option enables support for the GATT Read Multiple Characteristic
|
||||
Values procedure.
|
||||
|
||||
config BT_GATT_AUTO_DISCOVER_CCC
|
||||
bool "Support to automatic discover the CCC handles of characteristics"
|
||||
depends on BT_GATT_CLIENT
|
||||
help
|
||||
This option enables support for GATT to initiate discovery for CCC
|
||||
handles if the CCC handle is unknown by the application.
|
||||
|
||||
config BT_GAP_AUTO_UPDATE_CONN_PARAMS
|
||||
bool "Automatic Update of Connection Parameters"
|
||||
default y
|
||||
|
|
|
@ -3893,6 +3893,62 @@ static int gatt_write_ccc(struct bt_conn *conn, uint16_t handle, uint16_t value,
|
|||
return gatt_send(conn, buf, func, params, NULL);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC)
|
||||
static uint8_t gatt_ccc_discover_cb(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr,
|
||||
struct bt_gatt_discover_params *params)
|
||||
{
|
||||
struct bt_gatt_subscribe_params *sub_params = params->sub_params;
|
||||
|
||||
if (!attr) {
|
||||
memset(params, 0, sizeof(*params));
|
||||
sub_params->notify(conn, sub_params, NULL, 0);
|
||||
return BT_GATT_ITER_STOP;
|
||||
}
|
||||
|
||||
if (params->type == BT_GATT_DISCOVER_DESCRIPTOR) {
|
||||
memset(params, 0, sizeof(*params));
|
||||
sub_params->ccc_handle = attr->handle;
|
||||
|
||||
if (bt_gatt_subscribe(conn, sub_params)) {
|
||||
sub_params->notify(conn, sub_params, NULL, 0);
|
||||
}
|
||||
/* else if no error occurred, then `bt_gatt_subscribe` will
|
||||
* call the notify function once subscribed.
|
||||
*/
|
||||
|
||||
return BT_GATT_ITER_STOP;
|
||||
}
|
||||
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
|
||||
static int gatt_ccc_discover(struct bt_conn *conn,
|
||||
struct bt_gatt_subscribe_params *params)
|
||||
{
|
||||
int err;
|
||||
static struct bt_uuid_16 ccc_uuid = BT_UUID_INIT_16(0);
|
||||
|
||||
memcpy(&ccc_uuid, BT_UUID_GATT_CCC, sizeof(ccc_uuid));
|
||||
memset(params->disc_params, 0, sizeof(*params->disc_params));
|
||||
|
||||
params->disc_params->sub_params = params;
|
||||
params->disc_params->uuid = &ccc_uuid.uuid;
|
||||
params->disc_params->type = BT_GATT_DISCOVER_DESCRIPTOR;
|
||||
params->disc_params->start_handle = params->value_handle;
|
||||
params->disc_params->end_handle = params->end_handle;
|
||||
params->disc_params->func = gatt_ccc_discover_cb;
|
||||
|
||||
err = bt_gatt_discover(conn, params->disc_params);
|
||||
if (err) {
|
||||
BT_DBG("CCC Discovery failed (err %d)", err);
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif /* CONFIG_BT_GATT_AUTO_DISCOVER_CCC */
|
||||
|
||||
int bt_gatt_subscribe(struct bt_conn *conn,
|
||||
struct bt_gatt_subscribe_params *params)
|
||||
{
|
||||
|
@ -3903,7 +3959,13 @@ int bt_gatt_subscribe(struct bt_conn *conn,
|
|||
__ASSERT(conn, "invalid parameters\n");
|
||||
__ASSERT(params && params->notify, "invalid parameters\n");
|
||||
__ASSERT(params->value, "invalid parameters\n");
|
||||
#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC)
|
||||
__ASSERT(params->ccc_handle ||
|
||||
(params->end_handle && params->disc_params),
|
||||
"invalid parameters\n");
|
||||
#else
|
||||
__ASSERT(params->ccc_handle, "invalid parameters\n");
|
||||
#endif
|
||||
|
||||
if (conn->state != BT_CONN_CONNECTED) {
|
||||
return -ENOTCONN;
|
||||
|
@ -3933,6 +3995,14 @@ int bt_gatt_subscribe(struct bt_conn *conn,
|
|||
if (!has_subscription) {
|
||||
int err;
|
||||
|
||||
#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC)
|
||||
if (!params->ccc_handle) {
|
||||
err = gatt_ccc_discover(conn, params);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
err = gatt_write_ccc(conn, params->ccc_handle, params->value,
|
||||
gatt_write_ccc_rsp, params);
|
||||
if (err) {
|
||||
|
|
|
@ -561,6 +561,16 @@ static int cmd_subscribe(const struct shell *shell, size_t argc, char *argv[])
|
|||
subscribe_params.value = BT_GATT_CCC_NOTIFY;
|
||||
subscribe_params.notify = notify_func;
|
||||
|
||||
#if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC)
|
||||
if (subscribe_params.ccc_handle == 0) {
|
||||
static struct bt_gatt_discover_params disc_params;
|
||||
|
||||
subscribe_params.disc_params = &disc_params;
|
||||
subscribe_params.end_handle = 0xFFFF;
|
||||
}
|
||||
#endif /* CONFIG_BT_GATT_AUTO_DISCOVER_CCC */
|
||||
|
||||
|
||||
if (argc > 3 && !strcmp(argv[3], "ind")) {
|
||||
subscribe_params.value = BT_GATT_CCC_INDICATE;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ CONFIG_BT_GATT_HRS=y
|
|||
CONFIG_BT_WHITELIST=y
|
||||
CONFIG_BT_REMOTE_INFO=y
|
||||
CONFIG_BT_REMOTE_VERSION=y
|
||||
CONFIG_BT_GATT_AUTO_DISCOVER_CCC=y
|
||||
|
||||
CONFIG_BT_SETTINGS=y
|
||||
CONFIG_FLASH=y
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue