Bluetooth: GATT: Allow application to add subscription.
Allow the application to add subscription without resubscribing. This is needed for persistent bonds that can go to deep sleep and turn of the RAM or power-cycle. In this case the application as a GATT client must have a way to add the subscription callbacks back to the stack before the GATT server sends notifications. This should preferable be able to be done before even connecting since the notifications can arrive immediately after connecting to the peer. The stack cannot persist this on it's own since it must remember the function pointers for the callback functions. Storing these in persistent storage would not be compatible with a Device Firmware Upgrade (DFU) solution. Fixes: #21798 Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
parent
ae5489085f
commit
76119c526e
2 changed files with 78 additions and 0 deletions
|
@ -2522,6 +2522,37 @@ static struct gatt_sub *gatt_sub_add(struct bt_conn *conn)
|
|||
return sub;
|
||||
}
|
||||
|
||||
static struct gatt_sub *gatt_sub_find_by_addr(uint8_t id,
|
||||
const bt_addr_le_t *addr)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(subscriptions); i++) {
|
||||
struct gatt_sub *sub = &subscriptions[i];
|
||||
|
||||
if (id == sub->id && !bt_addr_le_cmp(&sub->peer, addr)) {
|
||||
return sub;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct gatt_sub *gatt_sub_add_by_addr(uint8_t id,
|
||||
const bt_addr_le_t *addr)
|
||||
{
|
||||
struct gatt_sub *sub;
|
||||
|
||||
sub = gatt_sub_find_by_addr(id, addr);
|
||||
if (!sub) {
|
||||
sub = gatt_sub_find(NULL);
|
||||
if (sub) {
|
||||
bt_addr_le_copy(&sub->peer, addr);
|
||||
sub->id = id;
|
||||
}
|
||||
}
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
void bt_gatt_notification(struct bt_conn *conn, uint16_t handle,
|
||||
const void *data, uint16_t length)
|
||||
{
|
||||
|
@ -4075,6 +4106,34 @@ int bt_gatt_subscribe(struct bt_conn *conn,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int bt_gatt_resubscribe(uint8_t id, const bt_addr_le_t *peer,
|
||||
struct bt_gatt_subscribe_params *params)
|
||||
{
|
||||
struct gatt_sub *sub;
|
||||
struct bt_gatt_subscribe_params *tmp;
|
||||
|
||||
__ASSERT(params && params->notify, "invalid parameters\n");
|
||||
__ASSERT(params->value, "invalid parameters\n");
|
||||
__ASSERT(params->ccc_handle, "invalid parameters\n");
|
||||
|
||||
sub = gatt_sub_add_by_addr(id, peer);
|
||||
if (!sub) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Lookup existing subscriptions */
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, tmp, node) {
|
||||
/* Fail if entry already exists */
|
||||
if (tmp == params) {
|
||||
gatt_sub_remove(NULL, sub, NULL, NULL);
|
||||
return -EALREADY;
|
||||
}
|
||||
}
|
||||
|
||||
sys_slist_prepend(&sub->list, ¶ms->node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_gatt_unsubscribe(struct bt_conn *conn,
|
||||
struct bt_gatt_subscribe_params *params)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue