[PATCH BlueZ 2/2] shared/gatt-client: Forward events from parent to clones

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>

Some events such as ready and service changed shall be forward to clones
since the clones may have set callbacks as well.
---
 src/shared/gatt-client.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index 8fa66ae..0c7bd97 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -55,6 +55,9 @@ struct bt_gatt_client {
 	struct bt_att *att;
 	int ref_count;
 
+	struct bt_gatt_client *parent;
+	struct queue *clones;
+
 	bt_gatt_client_callback_t ready_callback;
 	bt_gatt_client_destroy_func_t ready_destroy;
 	void *ready_data;
@@ -1013,12 +1016,23 @@ done:
 static void notify_client_ready(struct bt_gatt_client *client, bool success,
 							uint8_t att_ecode)
 {
+	const struct queue_entry *entry;
+
 	if (!client->ready_callback || client->ready)
 		return;
 
 	bt_gatt_client_ref(client);
 	client->ready = success;
 	client->ready_callback(success, att_ecode, client->ready_data);
+
+	/* Notify clones */
+	for (entry = queue_get_entries(client->clones); entry;
+							entry = entry->next) {
+		struct bt_gatt_client *clone = entry->data;
+
+		notify_client_ready(clone, success, att_ecode);
+	}
+
 	bt_gatt_client_unref(client);
 }
 
@@ -1332,6 +1346,7 @@ static void service_changed_complete(struct discovery_op *op, bool success,
 	struct service_changed_op *next_sc_op;
 	uint16_t start_handle = op->start;
 	uint16_t end_handle = op->end;
+	const struct queue_entry *entry;
 
 	client->in_svc_chngd = false;
 
@@ -1348,6 +1363,16 @@ static void service_changed_complete(struct discovery_op *op, bool success,
 		client->svc_chngd_callback(start_handle, end_handle,
 							client->svc_chngd_data);
 
+	/* Notify clones */
+	for (entry = queue_get_entries(client->clones); entry;
+							entry = entry->next) {
+		struct bt_gatt_client *clone = entry->data;
+
+		if (clone->svc_chngd_callback)
+			clone->svc_chngd_callback(start_handle, end_handle,
+							clone->svc_chngd_data);
+	}
+
 	/* Process any queued events */
 	next_sc_op = queue_pop_head(client->svc_chngd_queue);
 	if (next_sc_op) {
@@ -1634,11 +1659,17 @@ static void bt_gatt_client_free(struct bt_gatt_client *client)
 
 	gatt_db_unref(client->db);
 
+	queue_destroy(client->clones, NULL);
 	queue_destroy(client->svc_chngd_queue, free);
 	queue_destroy(client->long_write_queue, request_unref);
 	queue_destroy(client->notify_chrcs, notify_chrc_free);
 	queue_destroy(client->pending_requests, request_unref);
 
+	if (client->parent) {
+		queue_remove(client->parent->clones, client);
+		bt_gatt_client_unref(client->parent);
+	}
+
 	free(client);
 }
 
@@ -1670,6 +1701,7 @@ static struct bt_gatt_client *gatt_client_new(struct gatt_db *db,
 	if (!client->disc_id)
 		goto fail;
 
+	client->clones = queue_new();
 	client->long_write_queue = queue_new();
 	client->svc_chngd_queue = queue_new();
 	client->notify_list = queue_new();
@@ -1729,6 +1761,12 @@ struct bt_gatt_client *bt_gatt_client_clone(struct bt_gatt_client *client)
 	if (!clone)
 		return NULL;
 
+	queue_push_tail(client->clones, clone);
+
+	/* Reference the parent since the clones depend on it to propagate
+	 * service changed and ready callbacks.
+	 */
+	clone->parent = bt_gatt_client_ref(client);
 	clone->ready = client->ready;
 
 	return bt_gatt_client_ref(clone);
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux