Bluetooth: add destroy callback to indication

Adds a `destroy` callback to the `struct bt_gatt_indicate_params` which
is used to signify to the application that the indication operation has
completed and the struct instance can be freed/destroyed.

This is required as the number of indication value callbacks that will
be triggered is not known by the caller when the `conn` parameter is
`NULL`.

Tracking when this callback should be run is mananged by a private
reference counter inside the struct.

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
This commit is contained in:
Jordan Yates 2020-10-20 22:40:41 +10:00 committed by Carles Cufí
commit ffab099eb9
7 changed files with 23 additions and 1 deletions

View file

@ -1013,6 +1013,9 @@ 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 {
/** Notification Attribute UUID type */
@ -1021,10 +1024,14 @@ struct bt_gatt_indicate_params {
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.
@ -1046,7 +1053,8 @@ struct bt_gatt_indicate_params {
* start range when looking up for possible matches.
*
* @note This procedure is asynchronous therefore the parameters need to
* remains valid while it is active.
* remains valid while it is active. The procedure is active until
* the destroy callback is run.
*
* @param conn Connection object.
* @param params Indicate parameters.

View file

@ -356,6 +356,7 @@ void main(void)
ind_params.attr = &vnd_svc.attrs[2];
ind_params.func = indicate_cb;
ind_params.destroy = NULL;
ind_params.data = &indicating;
ind_params.len = sizeof(indicating);

View file

@ -117,6 +117,7 @@ gatt_indicate:
ind_params.attr = &hts_svc.attrs[2];
ind_params.func = indicate_cb;
ind_params.destroy = NULL;
ind_params.data = &htm;
ind_params.len = sizeof(htm);

View file

@ -1900,7 +1900,11 @@ static void gatt_indicate_rsp(struct bt_conn *conn, uint8_t err,
{
struct bt_gatt_indicate_params *params = user_data;
params->_ref--;
params->func(conn, params, err);
if (params->destroy && (params->_ref == 0)) {
params->destroy(params);
}
}
static int gatt_send(struct bt_conn *conn, struct net_buf *buf,
@ -2056,6 +2060,9 @@ static uint8_t notify_cb(const struct bt_gatt_attr *attr, uint16_t handle,
if (data->type == BT_GATT_CCC_INDICATE) {
err = gatt_indicate(conn, data->handle,
data->ind_params);
if (err == 0) {
data->ind_params->_ref++;
}
} else {
err = gatt_notify(conn, data->handle, data->nfy_params);
}
@ -2212,6 +2219,7 @@ int bt_gatt_indicate(struct bt_conn *conn,
}
if (conn) {
params->_ref = 1;
return gatt_indicate(conn, data.handle, params);
}
@ -2219,6 +2227,7 @@ int bt_gatt_indicate(struct bt_conn *conn,
data.type = BT_GATT_CCC_INDICATE;
data.ind_params = params;
params->_ref = 0;
bt_gatt_foreach_attr_type(data.handle, 0xffff, BT_UUID_GATT_CCC, NULL,
1, notify_cb, &data);

View file

@ -168,6 +168,7 @@ void service_b_3_2_value_v6_indicate(void)
*/
ind_params.attr = &service_b_3_2_attrs[2];
ind_params.func = value_v6_indicate_cb;
ind_params.destroy = NULL;
ind_params.data = &value_v6_value;
ind_params.len = sizeof(value_v6_value);

View file

@ -168,6 +168,7 @@ void service_b_3_3_value_v6_indicate(void)
*/
ind_params.attr = &service_b_3_3_attrs[2];
ind_params.func = value_v6_indicate_cb;
ind_params.destroy = NULL;
ind_params.data = &value_v6_value;
ind_params.len = sizeof(value_v6_value);

View file

@ -781,6 +781,7 @@ static uint8_t alloc_value(struct bt_gatt_attr *attr, struct set_value *data)
indicate_params.data = value->data;
indicate_params.len = value->len;
indicate_params.func = indicate_cb;
indicate_params.destroy = NULL;
bt_gatt_indicate(NULL, &indicate_params);
}