[PATCH BlueZ 2/4] shared/gatt-client: Take fd in bt_gatt_client_new

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

 



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

This simplify the instance creation and also drop automatically the
reference in case of disconnection.
---
 src/shared/gatt-client.c | 52 +++++++++++++++++++++++++++++++++++++-----------
 src/shared/gatt-client.h |  3 ++-
 tools/btgatt-client.c    | 29 ++++++---------------------
 3 files changed, 48 insertions(+), 36 deletions(-)

diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index 782e6b3..d884185 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -104,7 +104,7 @@ struct bt_gatt_client {
 	/* List of registered notification/indication callbacks */
 	struct queue *notify_list;
 	int next_reg_id;
-	unsigned int notify_id, ind_id;
+	unsigned int disc_id, notify_id, ind_id;
 	bool in_notify;
 	bool need_notify_cleanup;
 
@@ -1221,8 +1221,12 @@ static void bt_gatt_client_free(struct bt_gatt_client *client)
 	if (client->debug_destroy)
 		client->debug_destroy(client->debug_data);
 
-	bt_att_unregister(client->att, client->notify_id);
-	bt_att_unregister(client->att, client->ind_id);
+	if (client->att) {
+		bt_att_unregister_disconnect(client->att, client->disc_id);
+		bt_att_unregister(client->att, client->notify_id);
+		bt_att_unregister(client->att, client->ind_id);
+		bt_att_unref(client->att);
+	}
 
 	queue_destroy(client->svc_chngd_queue, free);
 	queue_destroy(client->long_write_queue, long_write_op_unref);
@@ -1230,21 +1234,38 @@ static void bt_gatt_client_free(struct bt_gatt_client *client)
 
 	gatt_client_clear_services(client);
 
-	bt_att_unref(client->att);
 	free(client);
 }
 
-struct bt_gatt_client *bt_gatt_client_new(struct bt_att *att, uint16_t mtu)
+static void att_disconnect_cb(void *user_data)
 {
-	struct bt_gatt_client *client;
+	struct bt_gatt_client *client = user_data;
 
-	if (!att)
-		return NULL;
+	bt_att_unref(client->att);
+	client->att = NULL;
+}
+
+struct bt_gatt_client *bt_gatt_client_new(int fd, uint16_t mtu)
+{
+	struct bt_gatt_client *client;
 
 	client = new0(struct bt_gatt_client, 1);
 	if (!client)
 		return NULL;
 
+	client->att = bt_att_new(fd);
+	if (!client->att)
+		goto fail;
+
+	if (!bt_att_set_close_on_unref(client->att, true))
+		goto fail;
+
+	client->disc_id = bt_att_register_disconnect(client->att,
+							att_disconnect_cb,
+							client, NULL);
+	if (!client->disc_id)
+		goto fail;
+
 	client->long_write_queue = queue_new();
 	if (!client->long_write_queue)
 		goto fail;
@@ -1257,18 +1278,17 @@ struct bt_gatt_client *bt_gatt_client_new(struct bt_att *att, uint16_t mtu)
 	if (!client->notify_list)
 		goto fail;
 
-	client->notify_id = bt_att_register(att, BT_ATT_OP_HANDLE_VAL_NOT,
+	client->notify_id = bt_att_register(client->att,
+						BT_ATT_OP_HANDLE_VAL_NOT,
 						notify_cb, client, NULL);
 	if (!client->notify_id)
 		goto fail;
 
-	client->ind_id = bt_att_register(att, BT_ATT_OP_HANDLE_VAL_IND,
+	client->ind_id = bt_att_register(client->att, BT_ATT_OP_HANDLE_VAL_IND,
 						notify_cb, client, NULL);
 	if (!client->ind_id)
 		goto fail;
 
-	client->att = bt_att_ref(att);
-
 	gatt_client_init(client, mtu);
 
 	return bt_gatt_client_ref(client);
@@ -1278,6 +1298,14 @@ fail:
 	return NULL;
 }
 
+struct bt_att *bt_gatt_client_get_att(struct bt_gatt_client *client)
+{
+	if (!client)
+		return NULL;
+
+	return client->att;
+}
+
 struct bt_gatt_client *bt_gatt_client_ref(struct bt_gatt_client *client)
 {
 	if (!client)
diff --git a/src/shared/gatt-client.h b/src/shared/gatt-client.h
index 6807f6b..4e8da29 100644
--- a/src/shared/gatt-client.h
+++ b/src/shared/gatt-client.h
@@ -38,7 +38,8 @@
 
 struct bt_gatt_client;
 
-struct bt_gatt_client *bt_gatt_client_new(struct bt_att *att, uint16_t mtu);
+struct bt_gatt_client *bt_gatt_client_new(int fd, uint16_t mtu);
+struct bt_att *bt_gatt_client_get_att(struct bt_gatt_client *client);
 
 struct bt_gatt_client *bt_gatt_client_ref(struct bt_gatt_client *client);
 void bt_gatt_client_unref(struct bt_gatt_client *client);
diff --git a/tools/btgatt-client.c b/tools/btgatt-client.c
index d900e08..95d395d 100644
--- a/tools/btgatt-client.c
+++ b/tools/btgatt-client.c
@@ -107,33 +107,19 @@ static struct client *client_create(int fd, uint16_t mtu)
 		return NULL;
 	}
 
-	att = bt_att_new(fd);
-	if (!att) {
-		fprintf(stderr, "Failed to initialze ATT transport layer\n");
-		bt_att_unref(att);
+	cli->fd = fd;
+	cli->gatt = bt_gatt_client_new(fd, mtu);
+	if (!cli->gatt) {
+		fprintf(stderr, "Failed to create GATT client\n");
 		free(cli);
 		return NULL;
 	}
 
-	if (!bt_att_set_close_on_unref(att, true)) {
-		fprintf(stderr, "Failed to set up ATT transport layer\n");
-		bt_att_unref(att);
-		free(cli);
-		return NULL;
-	}
+	att = bt_gatt_client_get_att(cli->gatt);
 
 	if (!bt_att_register_disconnect(att, att_disconnect_cb, NULL, NULL)) {
 		fprintf(stderr, "Failed to set ATT disconnect handler\n");
-		bt_att_unref(att);
-		free(cli);
-		return NULL;
-	}
-
-	cli->fd = fd;
-	cli->gatt = bt_gatt_client_new(att, mtu);
-	if (!cli->gatt) {
-		fprintf(stderr, "Failed to create GATT client\n");
-		bt_att_unref(att);
+		bt_gatt_client_unref(cli->gatt);
 		free(cli);
 		return NULL;
 	}
@@ -148,9 +134,6 @@ static struct client *client_create(int fd, uint16_t mtu)
 	bt_gatt_client_set_service_changed(cli->gatt, service_changed_cb, cli,
 									NULL);
 
-	/* bt_gatt_client already holds a reference */
-	bt_att_unref(att);
-
 	return cli;
 }
 
-- 
1.9.3

--
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