diff --git a/src/device.c b/src/device.c
index 620bbd5..5dc1cd0 100644
--- a/src/device.c
+++ b/src/device.c
return device->db;
}
+bool btd_device_set_gatt_db(struct btd_device *device, struct gatt_db *db)
+{
+ struct gatt_db *clone;
+
+ if (!device)
+ return false;
+
+ clone = gatt_db_clone(db);
+ if (clone)
+ return false;
+
+ gatt_db_unregister(device->db, device->db_id);
+ gatt_db_unref(device->db);
+
+ device->db = clone;
+ device->db_id = gatt_db_register(device->db, gatt_service_added,
+ gatt_service_removed, device, NULL);
+
+ return true;
+}
+
struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device)
{
if (!device)
diff --git a/src/device.h b/src/device.h
index a2b7bb1..0794f92 100644
--- a/src/device.h
+++ b/src/device.h
const char *uuid);
GSList *btd_device_get_primaries(struct btd_device *device);
struct gatt_db *btd_device_get_gatt_db(struct btd_device *device);
+bool btd_device_set_gatt_db(struct btd_device *device, struct gatt_db *db);
struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device);
struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device);
bool btd_device_is_initiator(struct btd_device *device);
diff --git a/src/set.c b/src/set.c
index bf35ee4..4ca2f78 100644
--- a/src/set.c
+++ b/src/set.c
#include "src/shared/queue.h"
#include "src/shared/ad.h"
#include "src/shared/crypto.h"
+#include "src/shared/att.h"
+#include "src/shared/gatt-db.h"
#include "log.h"
#include "error.h"
bt_crypto_unref(crypto);
- if (!memcmp(ad->data, res, sizeof(res)))
- device_connect_le(set->device);
+ if (memcmp(ad->data, res, sizeof(res)))
+ return;
+
+ /* Attempt to use existing gatt_db from set if device has never been
+ * connected before.
+ *
+ * If dbs don't really match bt_gatt_client will attempt to rediscover
+ * the ranges that don't match.
+ */
+ if (gatt_db_isempty(btd_device_get_gatt_db(set->device))) {
+ struct btd_device *device;
+
+ device = queue_get_entries(set->devices)->data;
+ btd_device_set_gatt_db(set->device,
+ btd_device_get_gatt_db(device));
+ }
+
+ device_connect_le(set->device);
}
static void foreach_device(struct btd_device *device, void *data)
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index d8d2139..16abcba 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
for (i = 0; i < service->num_handles; i++) {
struct gatt_db_attribute *attr = service->attributes[i];
- /* Only clone values for characteristics since that is
- * cacheable.
+ /* Only clone values for characteristics declaration since that
+ * is considered when calculating the db hash.
*/
if (bt_uuid_len(&attr->uuid) == 2 &&
attr->uuid.value.u16 == GATT_CHARAC_UUID)