[PATCH v2 BlueZ 1/2] shared/gatt-db: Remove services with match function

Subsystems: the rest

STALE3375d

2 messages, 1 author, 2017-05-10 · open the first message on its own page

[PATCH v2 BlueZ 1/2] shared/gatt-db: Remove services with match function

From: Marcin Kraglak <hidden>
Date: 2017-05-10 18:29:16

Allow remove services using match callback.
---
 src/shared/gatt-db.c | 41 +++++++++++++++++++++++++++++++++++++++++
 src/shared/gatt-db.h |  7 +++++++
 2 files changed, 48 insertions(+)
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index 8ef6f3b..ded7561 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -408,6 +408,47 @@ bool gatt_db_remove_service(struct gatt_db *db,
 	return true;
 }
 
+struct remove_services_data {
+	gatt_db_attribute_match_cb_t func;
+	void *user_data;
+};
+
+static bool remove_services_match(const void *data, const void *match_data)
+{
+	const struct remove_services_data *remove_svc_data = match_data;
+	const struct gatt_db_service *service = data;
+	struct gatt_db_attribute *attrib = service->attributes[0];
+
+	return remove_svc_data->func(attrib, remove_svc_data->user_data);
+}
+
+bool gatt_db_remove_services(struct gatt_db *db,
+					gatt_db_attribute_match_cb_t func,
+					void *user_data)
+{
+	if (!db)
+		return false;
+
+	if (func) {
+		struct remove_services_data remove_services_data = {
+			.func = func,
+			.user_data = user_data,
+		};
+
+		queue_remove_all(db->services, remove_services_match,
+						&remove_services_data,
+						gatt_db_service_destroy);
+	} else {
+		queue_remove_all(db->services, NULL, NULL,
+						gatt_db_service_destroy);
+	}
+
+	if (gatt_db_isempty(db))
+		db->next_handle = 0;
+
+	return true;
+}
+
 bool gatt_db_clear(struct gatt_db *db)
 {
 	return gatt_db_clear_range(db, 1, UINT16_MAX);
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index 134ec63..4e049cd 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
@@ -38,6 +38,13 @@ struct gatt_db_attribute *gatt_db_add_service(struct gatt_db *db,
 
 bool gatt_db_remove_service(struct gatt_db *db,
 					struct gatt_db_attribute *attrib);
+
+typedef bool (*gatt_db_attribute_match_cb_t)(struct gatt_db_attribute *attrib,
+							void *user_data);
+
+bool gatt_db_remove_services(struct gatt_db *db,
+					gatt_db_attribute_match_cb_t func,
+					void *user_data);
 bool gatt_db_clear(struct gatt_db *db);
 bool gatt_db_clear_range(struct gatt_db *db, uint16_t start_handle,
 							uint16_t end_handle);
-- 
2.4.3

[PATCH v2 BlueZ 2/2] shared/gatt-client: Validate cached services

From: Marcin Kraglak <hidden>
Date: 2017-05-10 18:29:17

Remove services that were not found in current discovery.
---
 src/shared/gatt-client.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index 0134721..a919d32 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -316,6 +316,7 @@ struct discovery_op {
 	struct queue *pending_svcs;
 	struct queue *pending_chrcs;
 	struct queue *svcs;
+	struct queue *found_svcs;
 	struct queue *ext_prop_desc;
 	struct gatt_db_attribute *cur_svc;
 	bool success;
@@ -332,13 +333,31 @@ static void discovery_op_free(struct discovery_op *op)
 	queue_destroy(op->pending_svcs, NULL);
 	queue_destroy(op->pending_chrcs, free);
 	queue_destroy(op->svcs, NULL);
+	queue_destroy(op->found_svcs, NULL);
 	queue_destroy(op->ext_prop_desc, NULL);
 	free(op);
 }
 
+static bool validate_svc_cb(struct gatt_db_attribute *attrib, void *user_data)
+{
+	struct discovery_op *op = user_data;
+	uint16_t start_h;
+
+	gatt_db_attribute_get_service_data(attrib, &start_h, NULL, NULL, NULL);
+
+	if (op->start > start_h || op->end < start_h)
+		return false;
+
+	return (queue_find(op->found_svcs, NULL, attrib) == NULL);
+}
+
 static void discovery_op_complete(struct discovery_op *op, bool success,
 								uint8_t err)
 {
+	struct bt_gatt_client *client = op->client;
+
+	gatt_db_remove_services(client->db, validate_svc_cb, op);
+
 	/* Reset remaining range */
 	if (op->last != UINT16_MAX)
 		gatt_db_clear_range(op->client->db, op->last + 1, UINT16_MAX);
@@ -358,6 +377,7 @@ static struct discovery_op *discovery_op_create(struct bt_gatt_client *client,
 	op->pending_svcs = queue_new();
 	op->pending_chrcs = queue_new();
 	op->svcs = queue_new();
+	op->found_svcs = queue_new();
 	op->ext_prop_desc = queue_new();
 	op->client = client;
 	op->complete_func = complete_func;
@@ -988,6 +1008,8 @@ static void discover_secondary_cb(bool success, uint8_t att_ecode,
 		if (!gatt_db_service_get_active(attr))
 			queue_push_tail(op->pending_svcs, attr);
 
+		queue_push_tail(op->found_svcs, attr);
+
 		/* Update last handle */
 		if (end > op->last)
 			op->last = end;
@@ -1101,6 +1123,8 @@ static void discover_primary_cb(bool success, uint8_t att_ecode,
 		if (!gatt_db_service_get_active(attr))
 			queue_push_tail(op->pending_svcs, attr);
 
+		queue_push_tail(op->found_svcs, attr);
+
 		/* Update last handle */
 		if (end > op->last)
 			op->last = end;
-- 
2.4.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help