linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ 1/4] Attrib server integration for outgoing connections
@ 2011-09-19 13:19 Claudio Takahasi
  2011-09-19 13:20 ` [PATCH BlueZ 2/4] Fix the attrib server trying to handle responses Claudio Takahasi
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Claudio Takahasi @ 2011-09-19 13:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

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

We need support for attaching a client connection to the attribute
server because the server that we are connected may want to do
something similar to a reverse service discovery, and we need to be
able to receive indications and notifications.
---
 plugins/gatt-example.c |    3 ++-
 src/adapter.c          |    3 ++-
 src/attrib-server.c    |   41 +++++++++++++++++++++++++++--------------
 src/attrib-server.h    |    1 +
 src/device.c           |   10 ++++++++--
 5 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/plugins/gatt-example.c b/plugins/gatt-example.c
index f86e76d..7436488 100644
--- a/plugins/gatt-example.c
+++ b/plugins/gatt-example.c
@@ -32,8 +32,9 @@
 #include "plugin.h"
 #include "hcid.h"
 #include "log.h"
-#include "attrib-server.h"
+#include "gattrib.h"
 #include "att.h"
+#include "attrib-server.h"
 
 /* FIXME: Not defined by SIG? UUID128? */
 #define OPCODES_SUPPORTED_UUID          0xA001
diff --git a/src/adapter.c b/src/adapter.c
index 628db60..af8c273 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -55,8 +55,9 @@
 #include "glib-helper.h"
 #include "agent.h"
 #include "storage.h"
-#include "attrib-server.h"
+#include "gattrib.h"
 #include "att.h"
+#include "attrib-server.h"
 #include "eir.h"
 
 /* Flags Descriptions */
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 5c86085..6c40681 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -780,7 +780,6 @@ static void channel_disconnect(void *user_data)
 {
 	struct gatt_channel *channel = user_data;
 
-	g_attrib_unref(channel->attrib);
 	clients = g_slist_remove(clients, channel);
 
 	g_slist_free(channel->notify);
@@ -914,16 +913,14 @@ done:
 							NULL, NULL, NULL);
 }
 
-static void connect_event(GIOChannel *io, GError *err, void *user_data)
+int attrib_channel_attach(GAttrib *attrib, gboolean out)
 {
 	struct gatt_channel *channel;
-	uint16_t cid;
+	GIOChannel *io;
 	GError *gerr = NULL;
+	uint16_t cid;
 
-	if (err) {
-		error("%s", err->message);
-		return;
-	}
+	io = g_attrib_get_channel(attrib);
 
 	channel = g_new0(struct gatt_channel, 1);
 
@@ -937,8 +934,7 @@ static void connect_event(GIOChannel *io, GError *err, void *user_data)
 		error("bt_io_get: %s", gerr->message);
 		g_error_free(gerr);
 		g_free(channel);
-		g_io_channel_shutdown(io, TRUE, NULL);
-		return;
+		return -EIO;
 	}
 
 	if (channel->mtu > ATT_MAX_MTU)
@@ -949,16 +945,33 @@ static void connect_event(GIOChannel *io, GError *err, void *user_data)
 	else
 		channel->le = TRUE;
 
-	channel->attrib = g_attrib_new(io);
-	g_io_channel_unref(io);
 
+	channel->attrib = g_attrib_ref(attrib);
 	channel->id = g_attrib_register(channel->attrib, GATTRIB_ALL_EVENTS,
-				channel_handler, channel, NULL);
+					channel_handler, channel, NULL);
 
-	g_attrib_set_disconnect_function(channel->attrib, channel_disconnect,
-								channel);
+	if (out == FALSE)
+		g_attrib_set_disconnect_function(channel->attrib,
+						channel_disconnect, channel);
 
 	clients = g_slist_append(clients, channel);
+
+	return 0;
+}
+
+static void connect_event(GIOChannel *io, GError *gerr, void *user_data)
+{
+	GAttrib *attrib;
+
+	if (gerr) {
+		error("%s", gerr->message);
+		return;
+	}
+
+	attrib = g_attrib_new(io);
+	attrib_channel_attach(attrib, FALSE);
+	g_io_channel_unref(io);
+	g_attrib_unref(attrib);
 }
 
 static void confirm_event(GIOChannel *io, void *user_data)
diff --git a/src/attrib-server.h b/src/attrib-server.h
index cde6eff..a72347c 100644
--- a/src/attrib-server.h
+++ b/src/attrib-server.h
@@ -31,3 +31,4 @@ int attrib_db_del(uint16_t handle);
 int attrib_gap_set(uint16_t uuid, const uint8_t *value, int len);
 uint32_t attrib_create_sdp(uint16_t handle, const char *name);
 void attrib_free_sdp(uint32_t sdp_handle);
+int attrib_channel_attach(GAttrib *attrib, gboolean out);
diff --git a/src/device.c b/src/device.c
index 3be328d..41e8c35 100644
--- a/src/device.c
+++ b/src/device.c
@@ -60,6 +60,7 @@
 #include "sdp-xml.h"
 #include "storage.h"
 #include "btio.h"
+#include "attrib-server.h"
 #include "attrib/client.h"
 
 #define DISCONNECT_TIMER	2
@@ -1682,6 +1683,7 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 {
 	struct btd_device *device = user_data;
 	struct browse_req *req = device->browse;
+	GAttrib *attrib;
 
 	if (gerr) {
 		DBusMessage *reply;
@@ -1704,11 +1706,15 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 		device->attioid = 0;
 	}
 
+	attrib = g_attrib_new(io);
+	if (attrib_channel_attach(attrib, TRUE) < 0)
+		error("Attribute server attach failure!");
+
 	if (req) {
-		req->attrib = g_attrib_new(io);
+		req->attrib = attrib;
 		gatt_discover_primary(req->attrib, NULL, primary_cb, req);
 	} else if (device->attios) {
-		device->attrib = g_attrib_new(io);
+		device->attrib = attrib;
 		g_attrib_set_disconnect_function(device->attrib,
 						attrib_disconnected, device);
 		g_slist_foreach(device->attios, attio_connected,
-- 
1.7.6.1


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

* [PATCH BlueZ 2/4] Fix the attrib server trying to handle responses
  2011-09-19 13:19 [PATCH BlueZ 1/4] Attrib server integration for outgoing connections Claudio Takahasi
@ 2011-09-19 13:20 ` Claudio Takahasi
  2011-09-19 13:20 ` [PATCH BlueZ 3/4] Add attrib server channel detach Claudio Takahasi
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Claudio Takahasi @ 2011-09-19 13:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

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

The attribute server should only try to handle ATT requests, responses
and events should be handled by the client.
---
 attrib/gattrib.c    |    4 +++-
 attrib/gattrib.h    |    1 +
 src/attrib-server.c |    2 +-
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index 8c15e52..4d901f1 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -346,7 +346,9 @@ static gboolean received_data(GIOChannel *io, GIOCondition cond, gpointer data)
 		struct event *evt = l->data;
 
 		if (evt->expected == buf[0] ||
-					evt->expected == GATTRIB_ALL_EVENTS)
+				evt->expected == GATTRIB_ALL_EVENTS ||
+				(is_response(buf[0]) == FALSE &&
+						evt->expected == GATTRIB_ALL_REQS))
 			evt->func(buf, len, evt->user_data);
 	}
 
diff --git a/attrib/gattrib.h b/attrib/gattrib.h
index 4c49879..47c0d60 100644
--- a/attrib/gattrib.h
+++ b/attrib/gattrib.h
@@ -29,6 +29,7 @@ extern "C" {
 #endif
 
 #define GATTRIB_ALL_EVENTS 0xFF
+#define GATTRIB_ALL_REQS 0xFE
 
 struct _GAttrib;
 typedef struct _GAttrib GAttrib;
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 6c40681..af9c291 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -947,7 +947,7 @@ int attrib_channel_attach(GAttrib *attrib, gboolean out)
 
 
 	channel->attrib = g_attrib_ref(attrib);
-	channel->id = g_attrib_register(channel->attrib, GATTRIB_ALL_EVENTS,
+	channel->id = g_attrib_register(channel->attrib, GATTRIB_ALL_REQS,
 					channel_handler, channel, NULL);
 
 	if (out == FALSE)
-- 
1.7.6.1


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

* [PATCH BlueZ 3/4] Add attrib server channel detach
  2011-09-19 13:19 [PATCH BlueZ 1/4] Attrib server integration for outgoing connections Claudio Takahasi
  2011-09-19 13:20 ` [PATCH BlueZ 2/4] Fix the attrib server trying to handle responses Claudio Takahasi
@ 2011-09-19 13:20 ` Claudio Takahasi
  2011-10-04 17:48   ` Claudio Takahasi
  2011-09-19 13:20 ` [PATCH BlueZ 4/4] Minor cleanup in attrib server channel disconnect Claudio Takahasi
  2011-09-27  9:29 ` [PATCH BlueZ 1/4] Attrib server integration for outgoing connections Johan Hedberg
  3 siblings, 1 reply; 9+ messages in thread
From: Claudio Takahasi @ 2011-09-19 13:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

BlueZ will act as GAP central role, so for outgoing connections the
central is responsible for disconnecting the link. This patch adds
a function allowing the central to detach from the local attribute
server(removing the last GAttrib reference).
---
 src/attrib-server.c |   34 +++++++++++++++++++++++++++++++---
 src/attrib-server.h |    3 ++-
 src/device.c        |   11 ++++++++++-
 3 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/src/attrib-server.c b/src/attrib-server.c
index af9c291..1d96221 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -785,6 +785,7 @@ static void channel_disconnect(void *user_data)
 	g_slist_free(channel->notify);
 	g_slist_free(channel->indicate);
 	g_slist_free_full(channel->configs, g_free);
+	g_attrib_unref(channel->attrib);
 
 	g_free(channel);
 }
@@ -913,7 +914,7 @@ done:
 							NULL, NULL, NULL);
 }
 
-int attrib_channel_attach(GAttrib *attrib, gboolean out)
+guint attrib_channel_attach(GAttrib *attrib, gboolean out)
 {
 	struct gatt_channel *channel;
 	GIOChannel *io;
@@ -934,7 +935,7 @@ int attrib_channel_attach(GAttrib *attrib, gboolean out)
 		error("bt_io_get: %s", gerr->message);
 		g_error_free(gerr);
 		g_free(channel);
-		return -EIO;
+		return 0;
 	}
 
 	if (channel->mtu > ATT_MAX_MTU)
@@ -956,7 +957,34 @@ int attrib_channel_attach(GAttrib *attrib, gboolean out)
 
 	clients = g_slist_append(clients, channel);
 
-	return 0;
+	return channel->id;
+}
+
+static gint channel_id_cmp(gconstpointer data, gconstpointer user_data)
+{
+	const struct gatt_channel *channel = data;
+	guint id = GPOINTER_TO_UINT(user_data);
+
+	return channel->id - id;
+}
+
+gboolean attrib_channel_detach(guint id)
+{
+	struct gatt_channel *channel;
+	GSList *l;
+
+	l = g_slist_find_custom(clients, GUINT_TO_POINTER(id),
+						channel_id_cmp);
+	if (!l)
+		return FALSE;
+
+	channel = l->data;
+
+	g_attrib_unregister(channel->attrib, channel->id);
+
+	channel_disconnect(channel);
+
+	return TRUE;
 }
 
 static void connect_event(GIOChannel *io, GError *gerr, void *user_data)
diff --git a/src/attrib-server.h b/src/attrib-server.h
index a72347c..943096c 100644
--- a/src/attrib-server.h
+++ b/src/attrib-server.h
@@ -31,4 +31,5 @@ int attrib_db_del(uint16_t handle);
 int attrib_gap_set(uint16_t uuid, const uint8_t *value, int len);
 uint32_t attrib_create_sdp(uint16_t handle, const char *name);
 void attrib_free_sdp(uint32_t sdp_handle);
-int attrib_channel_attach(GAttrib *attrib, gboolean out);
+guint attrib_channel_attach(GAttrib *attrib, gboolean out);
+gboolean attrib_channel_detach(guint id);
diff --git a/src/device.c b/src/device.c
index 41e8c35..1a0136b 100644
--- a/src/device.c
+++ b/src/device.c
@@ -137,6 +137,7 @@ struct btd_device {
 	GAttrib		*attrib;
 	GSList		*attios;
 	GSList		*attios_offline;
+	guint		attachid;		/* Attrib server attach */
 	guint		attioid;
 
 	gboolean	connected;
@@ -1623,6 +1624,7 @@ static void attrib_disconnected(gpointer user_data)
 							att_auto_connect,
 							device);
 
+	attrib_channel_detach(device->attachid);
 	g_attrib_unref(device->attrib);
 	device->attrib = NULL;
 }
@@ -1661,6 +1663,7 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 	device_probe_drivers(device, uuids);
 
 	if (device->attios == NULL && device->attios_offline == NULL) {
+		attrib_channel_detach(device->attachid);
 		g_attrib_unref(device->attrib);
 		device->attrib = NULL;
 	} else
@@ -1707,7 +1710,8 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 	}
 
 	attrib = g_attrib_new(io);
-	if (attrib_channel_attach(attrib, TRUE) < 0)
+	device->attachid = attrib_channel_attach(attrib, TRUE);
+	if (device->attachid == 0)
 		error("Attribute server attach failure!");
 
 	if (req) {
@@ -2666,6 +2670,11 @@ gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)
 		device->attioid = 0;
 	}
 
+	if (device->attachid) {
+		attrib_channel_detach(device->attachid);
+		device->attachid = 0;
+	}
+
 	if (device->attrib) {
 		g_attrib_unref(device->attrib);
 		device->attrib = NULL;
-- 
1.7.6.1


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

* [PATCH BlueZ 4/4] Minor cleanup in attrib server channel disconnect
  2011-09-19 13:19 [PATCH BlueZ 1/4] Attrib server integration for outgoing connections Claudio Takahasi
  2011-09-19 13:20 ` [PATCH BlueZ 2/4] Fix the attrib server trying to handle responses Claudio Takahasi
  2011-09-19 13:20 ` [PATCH BlueZ 3/4] Add attrib server channel detach Claudio Takahasi
@ 2011-09-19 13:20 ` Claudio Takahasi
  2011-10-04 17:52   ` Claudio Takahasi
  2011-09-27  9:29 ` [PATCH BlueZ 1/4] Attrib server integration for outgoing connections Johan Hedberg
  3 siblings, 1 reply; 9+ messages in thread
From: Claudio Takahasi @ 2011-09-19 13:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/attrib-server.c |   29 ++++++++++-------------------
 1 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/src/attrib-server.c b/src/attrib-server.c
index 1d96221..9c10467 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -776,12 +776,8 @@ 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_free(struct gatt_channel *channel)
 {
-	struct gatt_channel *channel = user_data;
-
-	clients = g_slist_remove(clients, channel);
-
 	g_slist_free(channel->notify);
 	g_slist_free(channel->indicate);
 	g_slist_free_full(channel->configs, g_free);
@@ -790,6 +786,14 @@ static void channel_disconnect(void *user_data)
 	g_free(channel);
 }
 
+static void channel_disconnect(void *user_data)
+{
+	struct gatt_channel *channel = user_data;
+
+	clients = g_slist_remove(clients, channel);
+	channel_free(channel);
+}
+
 static void channel_handler(const uint8_t *ipdu, uint16_t len,
 							gpointer user_data)
 {
@@ -1174,8 +1178,6 @@ static void attrib_free(void *data)
 
 void attrib_server_exit(void)
 {
-	GSList *l;
-
 	g_slist_free_full(database, attrib_free);
 
 	if (l2cap_io) {
@@ -1188,18 +1190,7 @@ void attrib_server_exit(void)
 		g_io_channel_shutdown(le_io, FALSE, NULL);
 	}
 
-	for (l = clients; l; l = l->next) {
-		struct gatt_channel *channel = l->data;
-
-		g_slist_free(channel->notify);
-		g_slist_free(channel->indicate);
-		g_slist_free_full(channel->configs, g_free);
-
-		g_attrib_unref(channel->attrib);
-		g_free(channel);
-	}
-
-	g_slist_free(clients);
+	g_slist_free_full(clients, (GDestroyNotify) channel_free);
 
 	if (gatt_sdp_handle)
 		remove_record_from_server(gatt_sdp_handle);
-- 
1.7.6.1


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

* Re: [PATCH BlueZ 1/4] Attrib server integration for outgoing connections
  2011-09-19 13:19 [PATCH BlueZ 1/4] Attrib server integration for outgoing connections Claudio Takahasi
                   ` (2 preceding siblings ...)
  2011-09-19 13:20 ` [PATCH BlueZ 4/4] Minor cleanup in attrib server channel disconnect Claudio Takahasi
@ 2011-09-27  9:29 ` Johan Hedberg
  3 siblings, 0 replies; 9+ messages in thread
From: Johan Hedberg @ 2011-09-27  9:29 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth, Vinicius Costa Gomes

Hi Claudio,

On Mon, Sep 19, 2011, Claudio Takahasi wrote:
> We need support for attaching a client connection to the attribute
> server because the server that we are connected may want to do
> something similar to a reverse service discovery, and we need to be
> able to receive indications and notifications.
> ---
>  plugins/gatt-example.c |    3 ++-
>  src/adapter.c          |    3 ++-
>  src/attrib-server.c    |   41 +++++++++++++++++++++++++++--------------
>  src/attrib-server.h    |    1 +
>  src/device.c           |   10 ++++++++--
>  5 files changed, 40 insertions(+), 18 deletions(-)

Patches 1 and 2 have been applied, but 3 and 4 fail to apply.
Please fix those.

Johan

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

* Re: [PATCH BlueZ 3/4] Add attrib server channel detach
  2011-09-19 13:20 ` [PATCH BlueZ 3/4] Add attrib server channel detach Claudio Takahasi
@ 2011-10-04 17:48   ` Claudio Takahasi
  2011-10-04 17:50     ` Claudio Takahasi
  0 siblings, 1 reply; 9+ messages in thread
From: Claudio Takahasi @ 2011-10-04 17:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

Hi Johan,

On Mon, Sep 19, 2011 at 10:20 AM, Claudio Takahasi
<claudio.takahasi@openbossa.org> wrote:
> BlueZ will act as GAP central role, so for outgoing connections the
> central is responsible for disconnecting the link. This patch adds
> a function allowing the central to detach from the local attribute
> server(removing the last GAttrib reference).
> ---
>  src/attrib-server.c |   34 +++++++++++++++++++++++++++++++---
>  src/attrib-server.h |    3 ++-
>  src/device.c        |   11 ++++++++++-
>  3 files changed, 43 insertions(+), 5 deletions(-)
>
> diff --git a/src/attrib-server.c b/src/attrib-server.c
> index af9c291..1d96221 100644
> --- a/src/attrib-server.c
> +++ b/src/attrib-server.c
> @@ -785,6 +785,7 @@ static void channel_disconnect(void *user_data)
>        g_slist_free(channel->notify);
>        g_slist_free(channel->indicate);
>        g_slist_free_full(channel->configs, g_free);
> +       g_attrib_unref(channel->attrib);
>
>        g_free(channel);
>  }
> @@ -913,7 +914,7 @@ done:
>                                                        NULL, NULL, NULL);
>  }
>
> -int attrib_channel_attach(GAttrib *attrib, gboolean out)
> +guint attrib_channel_attach(GAttrib *attrib, gboolean out)
>  {
>        struct gatt_channel *channel;
>        GIOChannel *io;
> @@ -934,7 +935,7 @@ int attrib_channel_attach(GAttrib *attrib, gboolean out)
>                error("bt_io_get: %s", gerr->message);
>                g_error_free(gerr);
>                g_free(channel);
> -               return -EIO;
> +               return 0;
>        }
>
>        if (channel->mtu > ATT_MAX_MTU)
> @@ -956,7 +957,34 @@ int attrib_channel_attach(GAttrib *attrib, gboolean out)
>
>        clients = g_slist_append(clients, channel);
>
> -       return 0;
> +       return channel->id;
> +}
> +
> +static gint channel_id_cmp(gconstpointer data, gconstpointer user_data)
> +{
> +       const struct gatt_channel *channel = data;
> +       guint id = GPOINTER_TO_UINT(user_data);
> +
> +       return channel->id - id;
> +}
> +
> +gboolean attrib_channel_detach(guint id)
> +{
> +       struct gatt_channel *channel;
> +       GSList *l;
> +
> +       l = g_slist_find_custom(clients, GUINT_TO_POINTER(id),
> +                                               channel_id_cmp);
> +       if (!l)
> +               return FALSE;
> +
> +       channel = l->data;
> +
> +       g_attrib_unregister(channel->attrib, channel->id);
> +
> +       channel_disconnect(channel);
> +
> +       return TRUE;
>  }
>
>  static void connect_event(GIOChannel *io, GError *gerr, void *user_data)
> diff --git a/src/attrib-server.h b/src/attrib-server.h
> index a72347c..943096c 100644
> --- a/src/attrib-server.h
> +++ b/src/attrib-server.h
> @@ -31,4 +31,5 @@ int attrib_db_del(uint16_t handle);
>  int attrib_gap_set(uint16_t uuid, const uint8_t *value, int len);
>  uint32_t attrib_create_sdp(uint16_t handle, const char *name);
>  void attrib_free_sdp(uint32_t sdp_handle);
> -int attrib_channel_attach(GAttrib *attrib, gboolean out);
> +guint attrib_channel_attach(GAttrib *attrib, gboolean out);
> +gboolean attrib_channel_detach(guint id);
> diff --git a/src/device.c b/src/device.c
> index 41e8c35..1a0136b 100644
> --- a/src/device.c
> +++ b/src/device.c
> @@ -137,6 +137,7 @@ struct btd_device {
>        GAttrib         *attrib;
>        GSList          *attios;
>        GSList          *attios_offline;
> +       guint           attachid;               /* Attrib server attach */
>        guint           attioid;
>
>        gboolean        connected;
> @@ -1623,6 +1624,7 @@ static void attrib_disconnected(gpointer user_data)
>                                                        att_auto_connect,
>                                                        device);
>
> +       attrib_channel_detach(device->attachid);
>        g_attrib_unref(device->attrib);
>        device->attrib = NULL;
>  }
> @@ -1661,6 +1663,7 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
>        device_probe_drivers(device, uuids);
>
>        if (device->attios == NULL && device->attios_offline == NULL) {
> +               attrib_channel_detach(device->attachid);
>                g_attrib_unref(device->attrib);
>                device->attrib = NULL;
>        } else
> @@ -1707,7 +1710,8 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
>        }
>
>        attrib = g_attrib_new(io);
> -       if (attrib_channel_attach(attrib, TRUE) < 0)
> +       device->attachid = attrib_channel_attach(attrib, TRUE);
> +       if (device->attachid == 0)
>                error("Attribute server attach failure!");
>
>        if (req) {
> @@ -2666,6 +2670,11 @@ gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)
>                device->attioid = 0;
>        }
>
> +       if (device->attachid) {
> +               attrib_channel_detach(device->attachid);
> +               device->attachid = 0;
> +       }
> +
>        if (device->attrib) {
>                g_attrib_unref(device->attrib);
>                device->attrib = NULL;
> --
> 1.7.6.1
>
>

patches 3/4 and 4/4 will be sent again after rebasing.

BR,
Claudio

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

* [PATCH BlueZ 3/4] Add attrib server channel detach
  2011-10-04 17:48   ` Claudio Takahasi
@ 2011-10-04 17:50     ` Claudio Takahasi
  2011-10-05  8:19       ` Johan Hedberg
  0 siblings, 1 reply; 9+ messages in thread
From: Claudio Takahasi @ 2011-10-04 17:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

BlueZ will act as GAP central role, so for outgoing connections the
central is responsible for disconnecting the link. This patch adds
a function allowing the central to detach from the local attribute
server(removing the last GAttrib reference).
---
 src/attrib-server.c |   34 +++++++++++++++++++++++++++++++---
 src/attrib-server.h |    3 ++-
 src/device.c        |   11 ++++++++++-
 3 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/src/attrib-server.c b/src/attrib-server.c
index 5c46e6d..5a50ade 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -792,6 +792,7 @@ static void channel_disconnect(void *user_data)
 	g_slist_free(channel->notify);
 	g_slist_free(channel->indicate);
 	g_slist_free_full(channel->configs, attrib_free);
+	g_attrib_unref(channel->attrib);
 
 	g_free(channel);
 }
@@ -920,7 +921,7 @@ done:
 							NULL, NULL, NULL);
 }
 
-int attrib_channel_attach(GAttrib *attrib, gboolean out)
+guint attrib_channel_attach(GAttrib *attrib, gboolean out)
 {
 	struct gatt_channel *channel;
 	GIOChannel *io;
@@ -941,7 +942,7 @@ int attrib_channel_attach(GAttrib *attrib, gboolean out)
 		error("bt_io_get: %s", gerr->message);
 		g_error_free(gerr);
 		g_free(channel);
-		return -EIO;
+		return 0;
 	}
 
 	if (channel->mtu > ATT_MAX_MTU)
@@ -963,7 +964,34 @@ int attrib_channel_attach(GAttrib *attrib, gboolean out)
 
 	clients = g_slist_append(clients, channel);
 
-	return 0;
+	return channel->id;
+}
+
+static gint channel_id_cmp(gconstpointer data, gconstpointer user_data)
+{
+	const struct gatt_channel *channel = data;
+	guint id = GPOINTER_TO_UINT(user_data);
+
+	return channel->id - id;
+}
+
+gboolean attrib_channel_detach(guint id)
+{
+	struct gatt_channel *channel;
+	GSList *l;
+
+	l = g_slist_find_custom(clients, GUINT_TO_POINTER(id),
+						channel_id_cmp);
+	if (!l)
+		return FALSE;
+
+	channel = l->data;
+
+	g_attrib_unregister(channel->attrib, channel->id);
+
+	channel_disconnect(channel);
+
+	return TRUE;
 }
 
 static void connect_event(GIOChannel *io, GError *gerr, void *user_data)
diff --git a/src/attrib-server.h b/src/attrib-server.h
index a72347c..943096c 100644
--- a/src/attrib-server.h
+++ b/src/attrib-server.h
@@ -31,4 +31,5 @@ int attrib_db_del(uint16_t handle);
 int attrib_gap_set(uint16_t uuid, const uint8_t *value, int len);
 uint32_t attrib_create_sdp(uint16_t handle, const char *name);
 void attrib_free_sdp(uint32_t sdp_handle);
-int attrib_channel_attach(GAttrib *attrib, gboolean out);
+guint attrib_channel_attach(GAttrib *attrib, gboolean out);
+gboolean attrib_channel_detach(guint id);
diff --git a/src/device.c b/src/device.c
index c19e294..45c4a6a 100644
--- a/src/device.c
+++ b/src/device.c
@@ -142,6 +142,7 @@ struct btd_device {
 	GAttrib		*attrib;
 	GSList		*attios;
 	GSList		*attios_offline;
+	guint		attachid;		/* Attrib server attach */
 	guint		attioid;
 
 	gboolean	connected;
@@ -1712,6 +1713,7 @@ static void attrib_disconnected(gpointer user_data)
 							att_auto_connect,
 							device);
 
+	attrib_channel_detach(device->attachid);
 	g_attrib_unref(device->attrib);
 	device->attrib = NULL;
 }
@@ -1749,6 +1751,7 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 	device_probe_drivers(device, uuids);
 
 	if (device->attios == NULL && device->attios_offline == NULL) {
+		attrib_channel_detach(device->attachid);
 		g_attrib_unref(device->attrib);
 		device->attrib = NULL;
 	} else
@@ -1796,7 +1799,8 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 	}
 
 	attrib = g_attrib_new(io);
-	if (attrib_channel_attach(attrib, TRUE) < 0)
+	device->attachid = attrib_channel_attach(attrib, TRUE);
+	if (device->attachid == 0)
 		error("Attribute server attach failure!");
 
 	if (req) {
@@ -2809,6 +2813,11 @@ gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)
 		device->attioid = 0;
 	}
 
+	if (device->attachid) {
+		attrib_channel_detach(device->attachid);
+		device->attachid = 0;
+	}
+
 	if (device->attrib) {
 		g_attrib_unref(device->attrib);
 		device->attrib = NULL;
-- 
1.7.7


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

* [PATCH BlueZ 4/4] Minor cleanup in attrib server channel disconnect
  2011-09-19 13:20 ` [PATCH BlueZ 4/4] Minor cleanup in attrib server channel disconnect Claudio Takahasi
@ 2011-10-04 17:52   ` Claudio Takahasi
  0 siblings, 0 replies; 9+ messages in thread
From: Claudio Takahasi @ 2011-10-04 17:52 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/attrib-server.c |   29 ++++++++++-------------------
 1 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/src/attrib-server.c b/src/attrib-server.c
index 5a50ade..95efd9f 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -783,12 +783,8 @@ static void attrib_free(void *data)
 	g_free(a);
 }
 
-static void channel_disconnect(void *user_data)
+static void channel_free(struct gatt_channel *channel)
 {
-	struct gatt_channel *channel = user_data;
-
-	clients = g_slist_remove(clients, channel);
-
 	g_slist_free(channel->notify);
 	g_slist_free(channel->indicate);
 	g_slist_free_full(channel->configs, attrib_free);
@@ -797,6 +793,14 @@ static void channel_disconnect(void *user_data)
 	g_free(channel);
 }
 
+static void channel_disconnect(void *user_data)
+{
+	struct gatt_channel *channel = user_data;
+
+	clients = g_slist_remove(clients, channel);
+	channel_free(channel);
+}
+
 static void channel_handler(const uint8_t *ipdu, uint16_t len,
 							gpointer user_data)
 {
@@ -1173,8 +1177,6 @@ failed:
 
 void attrib_server_exit(void)
 {
-	GSList *l;
-
 	g_slist_free_full(database, attrib_free);
 
 	if (l2cap_io) {
@@ -1187,18 +1189,7 @@ void attrib_server_exit(void)
 		g_io_channel_shutdown(le_io, FALSE, NULL);
 	}
 
-	for (l = clients; l; l = l->next) {
-		struct gatt_channel *channel = l->data;
-
-		g_slist_free(channel->notify);
-		g_slist_free(channel->indicate);
-		g_slist_free_full(channel->configs, attrib_free);
-
-		g_attrib_unref(channel->attrib);
-		g_free(channel);
-	}
-
-	g_slist_free(clients);
+	g_slist_free_full(clients, (GDestroyNotify) channel_free);
 
 	if (gatt_sdp_handle)
 		remove_record_from_server(gatt_sdp_handle);
-- 
1.7.7


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

* Re: [PATCH BlueZ 3/4] Add attrib server channel detach
  2011-10-04 17:50     ` Claudio Takahasi
@ 2011-10-05  8:19       ` Johan Hedberg
  0 siblings, 0 replies; 9+ messages in thread
From: Johan Hedberg @ 2011-10-05  8:19 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth

Hi Claudio,

On Tue, Oct 04, 2011, Claudio Takahasi wrote:
> BlueZ will act as GAP central role, so for outgoing connections the
> central is responsible for disconnecting the link. This patch adds
> a function allowing the central to detach from the local attribute
> server(removing the last GAttrib reference).
> ---
>  src/attrib-server.c |   34 +++++++++++++++++++++++++++++++---
>  src/attrib-server.h |    3 ++-
>  src/device.c        |   11 ++++++++++-
>  3 files changed, 43 insertions(+), 5 deletions(-)

These two patches have also been applied. Thanks.

Johan

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

end of thread, other threads:[~2011-10-05  8:19 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-19 13:19 [PATCH BlueZ 1/4] Attrib server integration for outgoing connections Claudio Takahasi
2011-09-19 13:20 ` [PATCH BlueZ 2/4] Fix the attrib server trying to handle responses Claudio Takahasi
2011-09-19 13:20 ` [PATCH BlueZ 3/4] Add attrib server channel detach Claudio Takahasi
2011-10-04 17:48   ` Claudio Takahasi
2011-10-04 17:50     ` Claudio Takahasi
2011-10-05  8:19       ` Johan Hedberg
2011-09-19 13:20 ` [PATCH BlueZ 4/4] Minor cleanup in attrib server channel disconnect Claudio Takahasi
2011-10-04 17:52   ` Claudio Takahasi
2011-09-27  9:29 ` [PATCH BlueZ 1/4] Attrib server integration for outgoing connections 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).