[PATCH BlueZ 1/7] device: Consolidate ATT connection management

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

 



This patch centralizes the connection management for ATT channels
grouping the common code. Based on the result of the ATT connection
result, error or success callback is called.
---
 src/device.c |  151 ++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 88 insertions(+), 63 deletions(-)

diff --git a/src/device.c b/src/device.c
index 3f4ac76..f57f090 100644
--- a/src/device.c
+++ b/src/device.c
@@ -116,6 +116,15 @@ struct attio_data {
 	gpointer user_data;
 };
 
+typedef void (*attio_error_cb) (const GError *gerr, gpointer user_data);
+typedef void (*attio_success_cb) (gpointer user_data);
+
+struct att_callbacks {
+	attio_error_cb error;		/* Callback for error */
+	attio_success_cb success;	/* Callback for success */
+	gpointer user_data;
+};
+
 struct btd_device {
 	bdaddr_t	bdaddr;
 	addr_type_t	type;
@@ -1810,7 +1819,8 @@ done:
 
 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 {
-	struct btd_device *device = user_data;
+	struct att_callbacks *attcb = user_data;
+	struct btd_device *device = attcb->user_data;
 	GAttrib *attrib;
 
 	g_io_channel_unref(device->att_io);
@@ -1819,14 +1829,10 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 	if (gerr) {
 		DBG("%s", gerr->message);
 
-		if (device->auto_connect)
-			device->auto_id = g_timeout_add_seconds_full(
-						G_PRIORITY_DEFAULT_IDLE,
-						AUTO_CONNECTION_INTERVAL,
-						att_connect, device,
-						att_connect_dispatched);
+		if (attcb->error)
+			attcb->error(gerr, user_data);
 
-		return;
+		goto done;
 	}
 
 	attrib = g_attrib_new(io);
@@ -1834,19 +1840,48 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 	if (device->attachid == 0)
 		error("Attribute server attach failure!");
 
-	if (device->attios) {
-		device->attrib = attrib;
-		g_attrib_set_disconnect_function(device->attrib,
-						attrib_disconnected, device);
-		g_slist_foreach(device->attios, attio_connected,
-							device->attrib);
-	}
+	device->attrib = attrib;
+	g_attrib_set_disconnect_function(device->attrib,
+					attrib_disconnected, device);
+
+	if (attcb->success)
+		attcb->success(user_data);
+done:
+	g_free(attcb);
+}
+
+static void att_error_cb(const GError *gerr, gpointer user_data)
+{
+	struct att_callbacks *attcb = user_data;
+	struct btd_device *device = attcb->user_data;
+
+	if (device->auto_connect == FALSE)
+		return;
+
+	device->auto_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,
+						AUTO_CONNECTION_INTERVAL,
+						att_connect, device,
+						att_connect_dispatched);
+
+	DBG("Enabling automatic connections");
+}
+
+static void att_success_cb(gpointer user_data)
+{
+	struct att_callbacks *attcb = user_data;
+	struct btd_device *device = attcb->user_data;
+
+	if (device->attios == NULL)
+		return;
+
+	g_slist_foreach(device->attios, attio_connected, device->attrib);
 }
 
 static gboolean att_connect(gpointer user_data)
 {
 	struct btd_device *device = user_data;
 	struct btd_adapter *adapter = device->adapter;
+	struct att_callbacks *attcb;
 	GIOChannel *io;
 	GError *gerr = NULL;
 	char addr[18];
@@ -1857,9 +1892,14 @@ static gboolean att_connect(gpointer user_data)
 
 	DBG("Connection attempt to: %s", addr);
 
+	attcb = g_new0(struct att_callbacks, 1);
+	attcb->error = att_error_cb;
+	attcb->success = att_success_cb;
+	attcb->user_data = device;
+
 	if (device_is_bredr(device)) {
 		io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
-					device, NULL, &gerr,
+					attcb, NULL, &gerr,
 					BT_IO_OPT_SOURCE_BDADDR, &sba,
 					BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
 					BT_IO_OPT_PSM, ATT_PSM,
@@ -1867,7 +1907,7 @@ static gboolean att_connect(gpointer user_data)
 					BT_IO_OPT_INVALID);
 	} else {
 		io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
-					device, NULL, &gerr,
+					attcb, NULL, &gerr,
 					BT_IO_OPT_SOURCE_BDADDR, &sba,
 					BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
 					BT_IO_OPT_CID, ATT_CID,
@@ -1878,6 +1918,7 @@ static gboolean att_connect(gpointer user_data)
 	if (io == NULL) {
 		error("ATT bt_io_connect(%s): %s", addr, gerr->message);
 		g_error_free(gerr);
+		g_free(attcb);
 		return FALSE;
 	}
 
@@ -1886,41 +1927,37 @@ static gboolean att_connect(gpointer user_data)
 	return FALSE;
 }
 
-static void browse_primary_connect_cb(GIOChannel *io, GError *gerr,
-							gpointer user_data)
+static void att_browse_error_cb(const GError *gerr, gpointer user_data)
 {
-	struct btd_device *device = user_data;
+	struct att_callbacks *attcb = user_data;
+	struct btd_device *device = attcb->user_data;
 	struct browse_req *req = device->browse;
 
-	g_io_channel_unref(device->att_io);
-	device->att_io = NULL;
-
-	if (gerr) {
+	if (req->msg) {
 		DBusMessage *reply;
 
-		DBG("%s", gerr->message);
-
 		reply = btd_error_failed(req->msg, gerr->message);
 		g_dbus_send_message(req->conn, reply);
-
-		device->browse = NULL;
-		browse_request_free(req);
-
-		return;
 	}
 
-	device->attrib = g_attrib_new(io);
-	device->attachid = attrib_channel_attach(device->attrib, TRUE);
-	if (device->attachid == 0)
-		error("Attribute server attach failure!");
+	device->browse = NULL;
+	browse_request_free(req);
+}
 
-	gatt_discover_primary(device->attrib, NULL, primary_cb, req);
+static void att_browse_cb(gpointer user_data)
+{
+	struct att_callbacks *attcb = user_data;
+	struct btd_device *device = attcb->user_data;
+
+	gatt_discover_primary(device->attrib, NULL, primary_cb,
+							device->browse);
 }
 
 int device_browse_primary(struct btd_device *device, DBusConnection *conn,
 				DBusMessage *msg, gboolean secure)
 {
 	struct btd_adapter *adapter = device->adapter;
+	struct att_callbacks *attcb;
 	struct browse_req *req;
 	BtIOSecLevel sec_level;
 	bdaddr_t src;
@@ -1935,8 +1972,13 @@ int device_browse_primary(struct btd_device *device, DBusConnection *conn,
 
 	sec_level = secure ? BT_IO_SEC_HIGH : BT_IO_SEC_LOW;
 
-	device->att_io = bt_io_connect(BT_IO_L2CAP, browse_primary_connect_cb,
-				device, NULL, NULL,
+	attcb = g_new0(struct att_callbacks, 1);
+	attcb->error = att_browse_error_cb;
+	attcb->success = att_browse_cb;
+	attcb->user_data = device;
+
+	device->att_io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
+				attcb, NULL, NULL,
 				BT_IO_OPT_SOURCE_BDADDR, &src,
 				BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
 				BT_IO_OPT_CID, ATT_CID,
@@ -1945,6 +1987,7 @@ int device_browse_primary(struct btd_device *device, DBusConnection *conn,
 
 	if (device->att_io == NULL) {
 		browse_request_free(req);
+		g_free(attcb);
 		return -EIO;
 	}
 
@@ -2308,29 +2351,6 @@ static void create_bond_req_exit(DBusConnection *conn, void *user_data)
 	}
 }
 
-static void bonding_connect_cb(GIOChannel *io, GError *gerr,
-							gpointer user_data)
-{
-	struct btd_device *device = user_data;
-
-	g_io_channel_unref(device->att_io);
-	device->att_io = NULL;
-
-	if (gerr) {
-		DBusMessage *reply = btd_error_failed(device->bonding->msg,
-								gerr->message);
-
-		g_dbus_send_message(device->bonding->conn, reply);
-		DBG("%s", gerr->message);
-		return;
-	}
-
-	device->attrib = g_attrib_new(io);
-	device->attachid = attrib_channel_attach(device->attrib, TRUE);
-	if (device->attachid == 0)
-		error("Attribute server attach failure!");
-}
-
 DBusMessage *device_create_bonding(struct btd_device *device,
 					DBusConnection *conn,
 					DBusMessage *msg,
@@ -2348,13 +2368,17 @@ DBusMessage *device_create_bonding(struct btd_device *device,
 		return btd_error_already_exists(msg);
 
 	if (device_is_le(device)) {
+		struct att_callbacks *attcb;
 		GError *gerr = NULL;
 		bdaddr_t sba;
 
 		adapter_get_address(adapter, &sba);
 
-		device->att_io = bt_io_connect(BT_IO_L2CAP, bonding_connect_cb,
-					device, NULL, &gerr,
+		attcb = g_new0(struct att_callbacks, 1);
+		attcb->user_data = device;
+
+		device->att_io = bt_io_connect(BT_IO_L2CAP, att_connect_cb,
+					attcb, NULL, &gerr,
 					BT_IO_OPT_SOURCE_BDADDR, &sba,
 					BT_IO_OPT_DEST_BDADDR,&device->bdaddr,
 					BT_IO_OPT_CID, ATT_CID,
@@ -2367,6 +2391,7 @@ DBusMessage *device_create_bonding(struct btd_device *device,
 
 			error("Bonding bt_io_connect(): %s", gerr->message);
 			g_error_free(gerr);
+			g_free(attcb);
 			return reply;
 		}
 	}
-- 
1.7.8.4

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