linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ 0/7] ATT connection management improvements
@ 2012-02-09 15:56 Claudio Takahasi
  2012-02-09 15:56 ` [PATCH BlueZ 1/7] device: Consolidate ATT connection management Claudio Takahasi
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Claudio Takahasi @ 2012-02-09 15:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

The following patches are cleaning and consolidating ATT connection
management in device.c

Claudio Takahasi (6):
  device: Consolidate ATT connection management
  device: Fix notifying ATTIO drivers when browsing
  attrib-server: Remove GAttrib disconnect callback
  device: Remove GAttrib disconnect callback
  device: Add common ATT connection cleanup function
  GAttrib: Remove unused function

Vinicius Costa Gomes (1):
  device: Fix trying to connect if already connected

 attrib/gattrib.c    |   22 +----
 attrib/gattrib.h    |    3 -
 src/attrib-server.c |   30 ++++--
 src/attrib-server.h |    2 +-
 src/device.c        |  253 ++++++++++++++++++++++++++++-----------------------
 5 files changed, 160 insertions(+), 150 deletions(-)

-- 
1.7.8.4


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH BlueZ 1/7] device: Consolidate ATT connection management
  2012-02-09 15:56 [PATCH BlueZ 0/7] ATT connection management improvements Claudio Takahasi
@ 2012-02-09 15:56 ` Claudio Takahasi
  2012-02-09 15:56 ` [PATCH BlueZ 2/7] device: Fix notifying ATTIO drivers when browsing Claudio Takahasi
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Claudio Takahasi @ 2012-02-09 15:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

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


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH BlueZ 2/7] device: Fix notifying ATTIO drivers when browsing
  2012-02-09 15:56 [PATCH BlueZ 0/7] ATT connection management improvements Claudio Takahasi
  2012-02-09 15:56 ` [PATCH BlueZ 1/7] device: Consolidate ATT connection management Claudio Takahasi
@ 2012-02-09 15:56 ` Claudio Takahasi
  2012-02-09 15:56 ` [PATCH BlueZ 3/7] device: Fix trying to connect if already connected Claudio Takahasi
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Claudio Takahasi @ 2012-02-09 15:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

If disconnection happens during the primary service discovery ATTIO
drivers should not be notified.
---
 src/device.c |   25 ++++++++++++-------------
 1 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/src/device.c b/src/device.c
index f57f090..9c851ea 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1749,6 +1749,9 @@ static void attrib_disconnected(gpointer user_data)
 	int sock, err = 0;
 	socklen_t len;
 
+	if (device->browse)
+		goto done;
+
 	io = g_attrib_get_channel(device->attrib);
 	sock = g_io_channel_unix_get_fd(io);
 	len = sizeof(err);
@@ -1756,21 +1759,19 @@ static void attrib_disconnected(gpointer user_data)
 
 	g_slist_foreach(device->attios, attio_disconnected, NULL);
 
-	attrib_channel_detach(device->attrib, device->attachid);
-	g_attrib_unref(device->attrib);
-	device->attrib = NULL;
-	device->attachid = 0;
-
-	if (device->auto_connect == FALSE)
-		return;
-
-	if (err != ETIMEDOUT)
-		return;
+	if (device->auto_connect == FALSE || err != ETIMEDOUT)
+		goto done;
 
 	device->auto_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,
 						AUTO_CONNECTION_INTERVAL,
 						att_connect, device,
 						att_connect_dispatched);
+
+done:
+	attrib_channel_detach(device->attrib, device->attachid);
+	device->attachid = 0;
+	g_attrib_unref(device->attrib);
+	device->attrib = NULL;
 }
 
 static void primary_cb(GSList *services, guint8 status, gpointer user_data)
@@ -1801,9 +1802,7 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 		device->attachid = 0;
 		g_attrib_unref(device->attrib);
 		device->attrib = NULL;
-	} else
-		g_attrib_set_disconnect_function(device->attrib,
-						attrib_disconnected, device);
+	}
 
 	g_slist_free(uuids);
 
-- 
1.7.8.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH BlueZ 3/7] device: Fix trying to connect if already connected
  2012-02-09 15:56 [PATCH BlueZ 0/7] ATT connection management improvements Claudio Takahasi
  2012-02-09 15:56 ` [PATCH BlueZ 1/7] device: Consolidate ATT connection management Claudio Takahasi
  2012-02-09 15:56 ` [PATCH BlueZ 2/7] device: Fix notifying ATTIO drivers when browsing Claudio Takahasi
@ 2012-02-09 15:56 ` Claudio Takahasi
  2012-02-09 15:56 ` [PATCH BlueZ 4/7] attrib-server: Remove GAttrib disconnect callback Claudio Takahasi
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Claudio Takahasi @ 2012-02-09 15:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

From: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>

---
 src/device.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/device.c b/src/device.c
index 9c851ea..2502906 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1966,9 +1966,15 @@ int device_browse_primary(struct btd_device *device, DBusConnection *conn,
 
 	req = g_new0(struct browse_req, 1);
 	req->device = btd_device_ref(device);
-
 	adapter_get_address(adapter, &src);
 
+	device->browse = req;
+
+	if (device->attrib) {
+		gatt_discover_primary(device->attrib, NULL, primary_cb, req);
+		goto done;
+	}
+
 	sec_level = secure ? BT_IO_SEC_HIGH : BT_IO_SEC_LOW;
 
 	attcb = g_new0(struct att_callbacks, 1);
@@ -1990,11 +1996,10 @@ int device_browse_primary(struct btd_device *device, DBusConnection *conn,
 		return -EIO;
 	}
 
+done:
 	if (conn)
 		req->conn = dbus_connection_ref(conn);
 
-	device->browse = req;
-
 	if (msg) {
 		const char *sender = dbus_message_get_sender(msg);
 
-- 
1.7.8.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH BlueZ 4/7] attrib-server: Remove GAttrib disconnect callback
  2012-02-09 15:56 [PATCH BlueZ 0/7] ATT connection management improvements Claudio Takahasi
                   ` (2 preceding siblings ...)
  2012-02-09 15:56 ` [PATCH BlueZ 3/7] device: Fix trying to connect if already connected Claudio Takahasi
@ 2012-02-09 15:56 ` Claudio Takahasi
  2012-02-09 15:56 ` [PATCH BlueZ 5/7] device: " Claudio Takahasi
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Claudio Takahasi @ 2012-02-09 15:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch replaces the usage of GAttrib disconnection callback by
GIOChannel watch to track ATTIO channel disconnection aiming to achieve
less dependencies between attrib server, device and GAttrib.
---
 src/attrib-server.c |   30 +++++++++++++++++++-----------
 src/attrib-server.h |    2 +-
 src/device.c        |    2 +-
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/src/attrib-server.c b/src/attrib-server.c
index 93a7b4f..5137bdc 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -75,6 +75,7 @@ struct gatt_channel {
 	guint id;
 	gboolean encrypted;
 	struct gatt_server *server;
+	guint cleanup_id;
 };
 
 struct group_elem {
@@ -107,8 +108,11 @@ static void attrib_free(void *data)
 
 static void channel_free(struct gatt_channel *channel)
 {
-	g_attrib_unref(channel->attrib);
 
+	if (channel->cleanup_id)
+		g_source_remove(channel->cleanup_id);
+
+	g_attrib_unref(channel->attrib);
 	g_free(channel);
 }
 
@@ -859,15 +863,21 @@ static uint16_t mtu_exchange(struct gatt_channel *channel, uint16_t mtu,
 	return enc_mtu_resp(old_mtu, pdu, len);
 }
 
-static void channel_disconnect(void *user_data)
+static void channel_remove(struct gatt_channel *channel)
 {
-	struct gatt_channel *channel = user_data;
-
 	channel->server->clients = g_slist_remove(channel->server->clients,
 								channel);
 	channel_free(channel);
 }
 
+static gboolean channel_watch_cb(GIOChannel *io, GIOCondition cond,
+						gpointer user_data)
+{
+	channel_remove(user_data);
+
+	return FALSE;
+}
+
 static void channel_handler(const uint8_t *ipdu, uint16_t len,
 							gpointer user_data)
 {
@@ -992,7 +1002,7 @@ done:
 							NULL, NULL, NULL);
 }
 
-guint attrib_channel_attach(GAttrib *attrib, gboolean out)
+guint attrib_channel_attach(GAttrib *attrib)
 {
 	struct gatt_server *server;
 	struct btd_device *device;
@@ -1050,9 +1060,8 @@ guint attrib_channel_attach(GAttrib *attrib, gboolean out)
 	channel->id = g_attrib_register(channel->attrib, GATTRIB_ALL_REQS,
 					channel_handler, channel, NULL);
 
-	if (out == FALSE)
-		g_attrib_set_disconnect_function(channel->attrib,
-						channel_disconnect, channel);
+	channel->cleanup_id = g_io_add_watch(io, G_IO_HUP, channel_watch_cb,
+								channel);
 
 	server->clients = g_slist_append(server->clients, channel);
 
@@ -1099,8 +1108,7 @@ gboolean attrib_channel_detach(GAttrib *attrib, guint id)
 	channel = l->data;
 
 	g_attrib_unregister(channel->attrib, channel->id);
-
-	channel_disconnect(channel);
+	channel_remove(channel);
 
 	return TRUE;
 }
@@ -1115,7 +1123,7 @@ static void connect_event(GIOChannel *io, GError *gerr, void *user_data)
 	}
 
 	attrib = g_attrib_new(io);
-	attrib_channel_attach(attrib, FALSE);
+	attrib_channel_attach(attrib);
 	g_io_channel_unref(io);
 	g_attrib_unref(attrib);
 }
diff --git a/src/attrib-server.h b/src/attrib-server.h
index fb4637c..7af0cfa 100644
--- a/src/attrib-server.h
+++ b/src/attrib-server.h
@@ -36,5 +36,5 @@ int attrib_gap_set(struct btd_adapter *adapter, uint16_t uuid,
 uint32_t attrib_create_sdp(struct btd_adapter *adapter, uint16_t handle,
 							const char *name);
 void attrib_free_sdp(uint32_t sdp_handle);
-guint attrib_channel_attach(GAttrib *attrib, gboolean out);
+guint attrib_channel_attach(GAttrib *attrib);
 gboolean attrib_channel_detach(GAttrib *attrib, guint id);
diff --git a/src/device.c b/src/device.c
index 2502906..288d327 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1835,7 +1835,7 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 	}
 
 	attrib = g_attrib_new(io);
-	device->attachid = attrib_channel_attach(attrib, TRUE);
+	device->attachid = attrib_channel_attach(attrib);
 	if (device->attachid == 0)
 		error("Attribute server attach failure!");
 
-- 
1.7.8.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH BlueZ 5/7] device: Remove GAttrib disconnect callback
  2012-02-09 15:56 [PATCH BlueZ 0/7] ATT connection management improvements Claudio Takahasi
                   ` (3 preceding siblings ...)
  2012-02-09 15:56 ` [PATCH BlueZ 4/7] attrib-server: Remove GAttrib disconnect callback Claudio Takahasi
@ 2012-02-09 15:56 ` Claudio Takahasi
  2012-02-09 15:56 ` [PATCH BlueZ 6/7] device: Add common ATT connection cleanup function Claudio Takahasi
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Claudio Takahasi @ 2012-02-09 15:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch replaces the usage of GAttrib disconnection callback by
GIOChannel watch to track ATT channel disconnection. Connection
management is being centralized in device to allow multi-profile
implementations.
---
 src/device.c |   29 +++++++++++++++++++++++------
 1 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/src/device.c b/src/device.c
index 288d327..f588e3c 100644
--- a/src/device.c
+++ b/src/device.c
@@ -168,6 +168,7 @@ struct btd_device {
 	gint		ref;
 
 	GIOChannel      *att_io;
+	guint		cleanup_id;
 };
 
 static uint16_t uuid_list[] = {
@@ -210,7 +211,12 @@ static void browse_request_cancel(struct browse_req *req)
 
 	bt_cancel_discovery(&src, &device->bdaddr);
 
-	if (device->att_io != NULL) {
+	if (device->cleanup_id) {
+		g_source_remove(device->cleanup_id);
+		device->cleanup_id = 0;
+	}
+
+	if (device->att_io) {
 		g_io_channel_shutdown(device->att_io, FALSE, NULL);
 		g_io_channel_unref(device->att_io);
 		device->att_io = NULL;
@@ -239,6 +245,9 @@ static void device_free(gpointer user_data)
 	g_slist_free_full(device->attios, g_free);
 	g_slist_free_full(device->attios_offline, g_free);
 
+	if (device->cleanup_id)
+		g_source_remove(device->cleanup_id);
+
 	g_attrib_unref(device->attrib);
 
 	if (device->tmp_records)
@@ -1742,17 +1751,16 @@ static void att_connect_dispatched(gpointer user_data)
 
 static gboolean att_connect(gpointer user_data);
 
-static void attrib_disconnected(gpointer user_data)
+static gboolean attrib_disconnected_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
 {
 	struct btd_device *device = user_data;
-	GIOChannel *io;
 	int sock, err = 0;
 	socklen_t len;
 
 	if (device->browse)
 		goto done;
 
-	io = g_attrib_get_channel(device->attrib);
 	sock = g_io_channel_unix_get_fd(io);
 	len = sizeof(err);
 	getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len);
@@ -1772,6 +1780,10 @@ done:
 	device->attachid = 0;
 	g_attrib_unref(device->attrib);
 	device->attrib = NULL;
+
+	device->cleanup_id = 0;
+
+	return FALSE;
 }
 
 static void primary_cb(GSList *services, guint8 status, gpointer user_data)
@@ -1799,6 +1811,8 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 
 	if (device->attios == NULL && device->attios_offline == NULL) {
 		attrib_channel_detach(device->attrib, device->attachid);
+		g_source_remove(device->cleanup_id);
+		device->cleanup_id = 0;
 		device->attachid = 0;
 		g_attrib_unref(device->attrib);
 		device->attrib = NULL;
@@ -1840,8 +1854,8 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 		error("Attribute server attach failure!");
 
 	device->attrib = attrib;
-	g_attrib_set_disconnect_function(device->attrib,
-					attrib_disconnected, device);
+	device->cleanup_id = g_io_add_watch(io, G_IO_HUP,
+					attrib_disconnected_cb, device);
 
 	if (attcb->success)
 		attcb->success(user_data);
@@ -2966,6 +2980,9 @@ gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)
 		device->attachid = 0;
 	}
 
+	g_source_remove(device->cleanup_id);
+	device->cleanup_id = 0;
+
 	if (device->attrib) {
 		g_attrib_unref(device->attrib);
 		device->attrib = NULL;
-- 
1.7.8.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH BlueZ 6/7] device: Add common ATT connection cleanup function
  2012-02-09 15:56 [PATCH BlueZ 0/7] ATT connection management improvements Claudio Takahasi
                   ` (4 preceding siblings ...)
  2012-02-09 15:56 ` [PATCH BlueZ 5/7] device: " Claudio Takahasi
@ 2012-02-09 15:56 ` Claudio Takahasi
  2012-02-09 15:56 ` [PATCH BlueZ 7/7] GAttrib: Remove unused function Claudio Takahasi
  2012-02-14 12:13 ` [PATCH BlueZ 0/7] ATT connection management improvements Johan Hedberg
  7 siblings, 0 replies; 9+ messages in thread
From: Claudio Takahasi @ 2012-02-09 15:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/device.c |   81 +++++++++++++++++++++------------------------------------
 1 files changed, 30 insertions(+), 51 deletions(-)

diff --git a/src/device.c b/src/device.c
index f588e3c..558c4c0 100644
--- a/src/device.c
+++ b/src/device.c
@@ -198,6 +198,30 @@ static void browse_request_free(struct browse_req *req)
 	g_free(req);
 }
 
+static void att_cleanup(struct btd_device *device)
+{
+	if (device->attachid) {
+		attrib_channel_detach(device->attrib, device->attachid);
+		device->attachid = 0;
+	}
+
+	if (device->cleanup_id) {
+		g_source_remove(device->cleanup_id);
+		device->cleanup_id = 0;
+	}
+
+	if (device->att_io) {
+		g_io_channel_shutdown(device->att_io, FALSE, NULL);
+		g_io_channel_unref(device->att_io);
+		device->att_io = NULL;
+	}
+
+	if (device->attrib) {
+		g_attrib_unref(device->attrib);
+		device->attrib = NULL;
+	}
+}
+
 static void browse_request_cancel(struct browse_req *req)
 {
 	struct btd_device *device = req->device;
@@ -211,16 +235,7 @@ static void browse_request_cancel(struct browse_req *req)
 
 	bt_cancel_discovery(&src, &device->bdaddr);
 
-	if (device->cleanup_id) {
-		g_source_remove(device->cleanup_id);
-		device->cleanup_id = 0;
-	}
-
-	if (device->att_io) {
-		g_io_channel_shutdown(device->att_io, FALSE, NULL);
-		g_io_channel_unref(device->att_io);
-		device->att_io = NULL;
-	}
+	att_cleanup(device);
 
 	device->browse = NULL;
 	browse_request_free(req);
@@ -245,10 +260,7 @@ static void device_free(gpointer user_data)
 	g_slist_free_full(device->attios, g_free);
 	g_slist_free_full(device->attios_offline, g_free);
 
-	if (device->cleanup_id)
-		g_source_remove(device->cleanup_id);
-
-	g_attrib_unref(device->attrib);
+	att_cleanup(device);
 
 	if (device->tmp_records)
 		sdp_list_free(device->tmp_records,
@@ -263,11 +275,6 @@ static void device_free(gpointer user_data)
 	if (device->auto_id)
 		g_source_remove(device->auto_id);
 
-	if (device->att_io) {
-		g_io_channel_shutdown(device->att_io, FALSE, NULL);
-		g_io_channel_unref(device->att_io);
-	}
-
 	DBG("%p", device);
 
 	g_free(device->authr);
@@ -1776,12 +1783,7 @@ static gboolean attrib_disconnected_cb(GIOChannel *io, GIOCondition cond,
 						att_connect_dispatched);
 
 done:
-	attrib_channel_detach(device->attrib, device->attachid);
-	device->attachid = 0;
-	g_attrib_unref(device->attrib);
-	device->attrib = NULL;
-
-	device->cleanup_id = 0;
+	att_cleanup(device);
 
 	return FALSE;
 }
@@ -1809,14 +1811,8 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 	device_register_services(req->conn, device, g_slist_copy(services), -1);
 	device_probe_drivers(device, uuids);
 
-	if (device->attios == NULL && device->attios_offline == NULL) {
-		attrib_channel_detach(device->attrib, device->attachid);
-		g_source_remove(device->cleanup_id);
-		device->cleanup_id = 0;
-		device->attachid = 0;
-		g_attrib_unref(device->attrib);
-		device->attrib = NULL;
-	}
+	if (device->attios == NULL && device->attios_offline == NULL)
+		att_cleanup(device);
 
 	g_slist_free(uuids);
 
@@ -2975,24 +2971,7 @@ gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)
 	if (device->attios != NULL || device->attios_offline != NULL)
 		return TRUE;
 
-	if (device->attachid > 0) {
-		attrib_channel_detach(device->attrib, device->attachid);
-		device->attachid = 0;
-	}
-
-	g_source_remove(device->cleanup_id);
-	device->cleanup_id = 0;
-
-	if (device->attrib) {
-		g_attrib_unref(device->attrib);
-		device->attrib = NULL;
-	}
-
-	if (device->att_io) {
-		g_io_channel_shutdown(device->att_io, FALSE, NULL);
-		g_io_channel_unref(device->att_io);
-		device->att_io = NULL;
-	}
+	att_cleanup(device);
 
 	return TRUE;
 }
-- 
1.7.8.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH BlueZ 7/7] GAttrib: Remove unused function
  2012-02-09 15:56 [PATCH BlueZ 0/7] ATT connection management improvements Claudio Takahasi
                   ` (5 preceding siblings ...)
  2012-02-09 15:56 ` [PATCH BlueZ 6/7] device: Add common ATT connection cleanup function Claudio Takahasi
@ 2012-02-09 15:56 ` Claudio Takahasi
  2012-02-14 12:13 ` [PATCH BlueZ 0/7] ATT connection management improvements Johan Hedberg
  7 siblings, 0 replies; 9+ messages in thread
From: Claudio Takahasi @ 2012-02-09 15:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

GAttrib disconnection tracking is being moved to device.c
---
 attrib/gattrib.c |   22 +---------------------
 attrib/gattrib.h |    3 ---
 2 files changed, 1 insertions(+), 24 deletions(-)

diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index 12a9fcf..8a1e97b 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -51,9 +51,7 @@ struct _GAttrib {
 	guint next_cmd_id;
 	guint next_evt_id;
 	GDestroyNotify destroy;
-	GAttribDisconnectFunc disconnect;
 	gpointer destroy_user_data;
-	gpointer disc_user_data;
 };
 
 struct command {
@@ -232,18 +230,6 @@ GIOChannel *g_attrib_get_channel(GAttrib *attrib)
 	return attrib->io;
 }
 
-gboolean g_attrib_set_disconnect_function(GAttrib *attrib,
-		GAttribDisconnectFunc disconnect, gpointer user_data)
-{
-	if (attrib == NULL)
-		return FALSE;
-
-	attrib->disconnect = disconnect;
-	attrib->disc_user_data = user_data;
-
-	return TRUE;
-}
-
 gboolean g_attrib_set_destroy_function(GAttrib *attrib,
 		GDestroyNotify destroy, gpointer user_data)
 {
@@ -274,12 +260,8 @@ static gboolean can_write_data(GIOChannel *io, GIOCondition cond,
 	gsize len;
 	GIOStatus iostat;
 
-	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
-		if (attrib->disconnect)
-			attrib->disconnect(attrib->disc_user_data);
-
+	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
 		return FALSE;
-	}
 
 	cmd = g_queue_peek_head(attrib->queue);
 	if (cmd == NULL)
@@ -338,8 +320,6 @@ static gboolean received_data(GIOChannel *io, GIOCondition cond, gpointer data)
 
 	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
 		attrib->read_watch = 0;
-		if (attrib->disconnect)
-			attrib->disconnect(attrib->disc_user_data);
 		return FALSE;
 	}
 
diff --git a/attrib/gattrib.h b/attrib/gattrib.h
index 47c0d60..f73b741 100644
--- a/attrib/gattrib.h
+++ b/attrib/gattrib.h
@@ -47,9 +47,6 @@ void g_attrib_unref(GAttrib *attrib);
 
 GIOChannel *g_attrib_get_channel(GAttrib *attrib);
 
-gboolean g_attrib_set_disconnect_function(GAttrib *attrib,
-		GAttribDisconnectFunc disconnect, gpointer user_data);
-
 gboolean g_attrib_set_destroy_function(GAttrib *attrib,
 		GDestroyNotify destroy, gpointer user_data);
 
-- 
1.7.8.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH BlueZ 0/7] ATT connection management improvements
  2012-02-09 15:56 [PATCH BlueZ 0/7] ATT connection management improvements Claudio Takahasi
                   ` (6 preceding siblings ...)
  2012-02-09 15:56 ` [PATCH BlueZ 7/7] GAttrib: Remove unused function Claudio Takahasi
@ 2012-02-14 12:13 ` Johan Hedberg
  7 siblings, 0 replies; 9+ messages in thread
From: Johan Hedberg @ 2012-02-14 12:13 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth

Hi Claudio,

On Thu, Feb 09, 2012, Claudio Takahasi wrote:
> The following patches are cleaning and consolidating ATT connection
> management in device.c
> 
> Claudio Takahasi (6):
>   device: Consolidate ATT connection management
>   device: Fix notifying ATTIO drivers when browsing
>   attrib-server: Remove GAttrib disconnect callback
>   device: Remove GAttrib disconnect callback
>   device: Add common ATT connection cleanup function
>   GAttrib: Remove unused function
> 
> Vinicius Costa Gomes (1):
>   device: Fix trying to connect if already connected
> 
>  attrib/gattrib.c    |   22 +----
>  attrib/gattrib.h    |    3 -
>  src/attrib-server.c |   30 ++++--
>  src/attrib-server.h |    2 +-
>  src/device.c        |  253 ++++++++++++++++++++++++++++-----------------------
>  5 files changed, 160 insertions(+), 150 deletions(-)

All patches have been applied. Thanks.

Johan

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-02-14 12:13 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-09 15:56 [PATCH BlueZ 0/7] ATT connection management improvements Claudio Takahasi
2012-02-09 15:56 ` [PATCH BlueZ 1/7] device: Consolidate ATT connection management Claudio Takahasi
2012-02-09 15:56 ` [PATCH BlueZ 2/7] device: Fix notifying ATTIO drivers when browsing Claudio Takahasi
2012-02-09 15:56 ` [PATCH BlueZ 3/7] device: Fix trying to connect if already connected Claudio Takahasi
2012-02-09 15:56 ` [PATCH BlueZ 4/7] attrib-server: Remove GAttrib disconnect callback Claudio Takahasi
2012-02-09 15:56 ` [PATCH BlueZ 5/7] device: " Claudio Takahasi
2012-02-09 15:56 ` [PATCH BlueZ 6/7] device: Add common ATT connection cleanup function Claudio Takahasi
2012-02-09 15:56 ` [PATCH BlueZ 7/7] GAttrib: Remove unused function Claudio Takahasi
2012-02-14 12:13 ` [PATCH BlueZ 0/7] ATT connection management improvements Johan Hedberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).