Skip to content
Permalink
Browse files

Bluetooth: gatt: Fix DB corruption when adding/removing service

Fix an issue in the gatt_register routine where removing a service and
adding it again would cause the database to have non-ascending
orderdered handles numbers and lead to an incomplete service discovery.

Fix: Go through the database and look for a place where to insert
the new service.

Signed-off-by: Arthur Crepin-Leblond <arthur.crepin@proglove.de>
  • Loading branch information...
arthur-proglove authored and jhedberg committed Jun 4, 2019
1 parent b0e58d6 commit ba894d8b0ac63c179683be38c9726e226d7e8f3e
Showing with 29 additions and 3 deletions.
  1. +29 −3 subsys/bluetooth/host/gatt.c
@@ -534,20 +534,46 @@ static const struct bt_gatt_attr *find_attr(uint16_t handle)
return attr;
}

static void gatt_insert(struct bt_gatt_service *svc, u16_t last_handle)
{
struct bt_gatt_service *tmp, *prev = NULL;

if (last_handle == 0 || svc->attrs[0].handle > last_handle) {
sys_slist_append(&db, &svc->node);
return;
}

/* DB shall always have its service in ascending order */
SYS_SLIST_FOR_EACH_CONTAINER(&db, tmp, node) {
if (tmp->attrs[0].handle > svc->attrs[0].handle) {
if (prev) {
sys_slist_insert(&db, &prev->node, &svc->node);
} else {
sys_slist_prepend(&db, &svc->node);
}
return;
}

prev = tmp;
}
}

static int gatt_register(struct bt_gatt_service *svc)
{
struct bt_gatt_service *last;
u16_t handle;
u16_t handle, last_handle;
struct bt_gatt_attr *attrs = svc->attrs;
u16_t count = svc->attr_count;

if (sys_slist_is_empty(&db)) {
handle = last_static_handle;
handle = 0;
last_handle = 0;
goto populate;
}

last = SYS_SLIST_PEEK_TAIL_CONTAINER(&db, last, node);
handle = last->attrs[last->attr_count - 1].handle;
last_handle = handle;

populate:
/* Populate the handles and append them to the list */
@@ -570,7 +596,7 @@ static int gatt_register(struct bt_gatt_service *svc)
attrs->perm);
}

sys_slist_append(&db, &svc->node);
gatt_insert(svc, last_handle);

return 0;
}

0 comments on commit ba894d8

Please sign in to comment.
You can’t perform that action at this time.