Bluetooth: GATT: introduce volatile subscription flag

Some application protocol required non-persistente subscription
across connection even in bonded case.
Flag BT_GATT_SUBSCRIBE_FLAG_VOLATILE specify if subscription
must be remove during disonnection.

Change-Id: I1bc2bbbb4bc86f58905e44a7eb267ca0871f2fdb
Signed-off-by: Jonathan Gelie <jonathanx.gelie@intel.com>
This commit is contained in:
Jonathan Gelie 2017-02-02 16:13:58 +01:00 committed by Luiz Augusto von Dentz
commit b3ac77becd
3 changed files with 38 additions and 34 deletions

View file

@ -1218,8 +1218,10 @@ static void remove_subscriptions(struct bt_conn *conn)
continue;
}
/* Remove subscription */
gatt_subscription_remove(conn, prev, params);
if (params->flags & BT_GATT_SUBSCRIBE_FLAG_VOLATILE) {
/* Remove subscription */
gatt_subscription_remove(conn, prev, params);
}
}
}

View file

@ -960,6 +960,20 @@ 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 {
/** 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 = BIT(0),
};
/** @brief GATT Subscribe parameters */
struct bt_gatt_subscribe_params {
struct bt_att_req _req;
@ -972,6 +986,8 @@ struct bt_gatt_subscribe_params {
uint16_t ccc_handle;
/** Subscribe value */
uint16_t value;
/** Subscription flags */
uint8_t flags;
sys_snode_t node;
};

View file

@ -722,6 +722,17 @@ void bt_gatt_notification(struct bt_conn *conn, uint16_t handle,
}
}
static void update_subscription(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params)
{
if (params->_peer.type == BT_ADDR_LE_PUBLIC) {
return;
}
/* Update address */
bt_addr_le_copy(&params->_peer, &conn->le.dst);
}
static void gatt_subscription_remove(struct bt_conn *conn, sys_snode_t *prev,
struct bt_gatt_subscribe_params *params)
{
@ -747,8 +758,13 @@ static void remove_subscriptions(struct bt_conn *conn)
continue;
}
/* Remove subscription */
gatt_subscription_remove(conn, prev, params);
if (!bt_addr_le_is_bonded(&conn->le.dst) ||
(params->flags & BT_GATT_SUBSCRIBE_FLAG_VOLATILE)) {
/* Remove subscription */
gatt_subscription_remove(conn, prev, params);
} else {
update_subscription(conn, params);
}
}
}
@ -1812,30 +1828,6 @@ static void add_subscriptions(struct bt_conn *conn)
}
}
static void update_subscriptions(struct bt_conn *conn)
{
sys_snode_t *node;
/* Update existing subscriptions */
SYS_SLIST_FOR_EACH_NODE(&subscriptions, node) {
struct bt_gatt_subscribe_params *params;
params = CONTAINER_OF(node, struct bt_gatt_subscribe_params,
node);
if (params->_peer.type == BT_ADDR_LE_PUBLIC) {
continue;
}
if (bt_conn_addr_le_cmp(conn, &params->_peer)) {
continue;
}
/* Update address */
bt_addr_le_copy(&params->_peer, &conn->le.dst);
}
}
#endif /* CONFIG_BLUETOOTH_GATT_CLIENT */
void bt_gatt_connected(struct bt_conn *conn)
@ -1853,12 +1845,6 @@ void bt_gatt_disconnected(struct bt_conn *conn)
bt_gatt_foreach_attr(0x0001, 0xffff, disconnected_cb, conn);
#if defined(CONFIG_BLUETOOTH_GATT_CLIENT)
/* If bonded don't remove subscriptions */
if (bt_addr_le_is_bonded(&conn->le.dst)) {
update_subscriptions(conn);
return;
}
remove_subscriptions(conn);
#endif /* CONFIG_BLUETOOTH_GATT_CLIENT */
}