Diff between 2f440ad7b5e069056c692b3d1bacffb414d015cd and 6184bc59116330f866fd2bfb476f892054fc4e25

Changed Files

File Additions Deletions Status
plugins/gatt-example.c +2 -1 modified
src/adapter.c +2 -1 modified
src/attrib-server.c +27 -14 modified
src/attrib-server.h +1 -0 modified
src/device.c +8 -2 modified

Full Patch

diff --git a/plugins/gatt-example.c b/plugins/gatt-example.c
index 334f74a..955d9fa 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 52fb78a..b3622cb 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 59dddf6..260e64a 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -787,7 +787,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);
@@ -921,16 +920,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);
 
@@ -944,8 +941,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)
@@ -956,16 +952,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 dd463f0..5d70589 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
@@ -1685,6 +1686,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;
@@ -1707,11 +1709,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,