Diff between 649cd5a7c52629d2a5716a9bbd459e3b57326d1d and cb856533b9c096464b093a219be305d8e3b6e406

Changed Files

File Additions Deletions Status
obexd/src/bluetooth.c +73 -42 modified
obexd/src/bluetooth.h +2 -1 modified
obexd/src/manager.c +3 -1 modified
obexd/src/obex.h +3 -0 modified

Full Patch

diff --git a/obexd/src/bluetooth.c b/obexd/src/bluetooth.c
index 8c3f564..0a27a00 100644
--- a/obexd/src/bluetooth.c
+++ b/obexd/src/bluetooth.c
@@ -48,17 +48,6 @@
 
 static GSList *servers = NULL;
 
-void bluetooth_servers_foreach(GFunc func, gpointer user_data)
-{
-	struct server *server;
-	GSList *l;
-
-	for (l = servers; l; l = l->next) {
-		server = l->data;
-		func(server, user_data);
-	}
-}
-
 static gboolean connect_event(GIOChannel *io, GIOCondition cond, gpointer user_data)
 {
 	struct sockaddr_rc raddr;
@@ -98,25 +87,9 @@ static gboolean connect_event(GIOChannel *io, GIOCondition cond, gpointer user_d
 	return TRUE;
 }
 
-static void server_destroyed(gpointer user_data)
-{
-	struct server *server = user_data;
-
-	error("Server destroyed");
-
-	servers = g_slist_remove(servers, server);
-
-	server_free(server);
-}
-
-static gint server_register(guint16 service, const gchar *name, guint8 channel,
-			const gchar *folder, gboolean secure,
-			gboolean auto_accept, const gchar *capability)
+static gint server_start(struct server *server)
 {
 	struct sockaddr_rc laddr;
-	GIOChannel *io;
-	struct server *server;
-	uint32_t handle;
 	int err, sk, arg;
 
 	sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
@@ -138,7 +111,7 @@ static gint server_register(guint16 service, const gchar *name, guint8 channel,
 		goto failed;
 	}
 
-	if (secure) {
+	if (server->secure) {
 		int lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
 
 		if (setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
@@ -150,7 +123,7 @@ static gint server_register(guint16 service, const gchar *name, guint8 channel,
 	memset(&laddr, 0, sizeof(laddr));
 	laddr.rc_family = AF_BLUETOOTH;
 	bacpy(&laddr.rc_bdaddr, BDADDR_ANY);
-	laddr.rc_channel = channel;
+	laddr.rc_channel = server->channel;
 
 	if (bind(sk, (struct sockaddr *) &laddr, sizeof(laddr)) < 0) {
 		err = errno;
@@ -162,6 +135,45 @@ static gint server_register(guint16 service, const gchar *name, guint8 channel,
 		goto failed;
 	}
 
+	server->io = g_io_channel_unix_new(sk);
+	g_io_channel_set_close_on_unref(server->io, TRUE);
+	server->watch = g_io_add_watch(server->io,
+			G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+			connect_event, server);
+
+	return 0;
+
+failed:
+	error("Bluetooth server register failed: %s(%d)", strerror(err), err);
+	close(sk);
+
+	return -err;
+}
+
+static gint server_stop(struct server *server)
+{
+	if (!server->io)
+		return -EINVAL;
+
+	if (server->watch) {
+		g_source_remove(server->watch);
+		server->watch = 0;
+	}
+
+	g_io_channel_unref(server->io);
+	server->io = NULL;
+
+	return 0;
+}
+
+static gint server_register(guint16 service, const gchar *name, guint8 channel,
+			const gchar *folder, gboolean secure,
+			gboolean auto_accept, const gchar *capability)
+{
+	struct server *server;
+	uint32_t handle;
+	int err;
+
 	server = g_malloc0(sizeof(struct server));
 	server->services = service;
 	server->name = g_strdup(name);
@@ -170,25 +182,19 @@ static gint server_register(guint16 service, const gchar *name, guint8 channel,
 	server->capability = g_strdup(capability);
 	server->channel = channel;
 	server->handle = handle;
+	server->secure = secure;
 
-	io = g_io_channel_unix_new(sk);
-	g_io_channel_set_close_on_unref(io, TRUE);
-	g_io_add_watch_full(io, G_PRIORITY_DEFAULT,
-			G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-			connect_event, server, server_destroyed);
-	g_io_channel_unref(io);
+	err = server_start(server);
+	if (err < 0) {
+		server_free(server);
+		return err;
+	}
 
 	servers = g_slist_append(servers, server);
 
 	register_record(server, NULL);
 
 	return 0;
-
-failed:
-	error("Bluetooth server register failed: %s(%d)", strerror(err), err);
-	close(sk);
-
-	return -err;
 }
 
 gint bluetooth_init(guint service, const gchar *name, const gchar *folder,
@@ -203,3 +209,28 @@ void bluetooth_exit(void)
 {
 	return;
 }
+
+void bluetooth_start(void)
+{
+	GSList *l;
+
+	for (l = servers; l; l = l->next) {
+		struct server *server = l->data;
+
+		if (server_start(server) < 0)
+			continue;
+
+		register_record(server, NULL);
+	}
+}
+
+void bluetooth_stop(void)
+{
+	GSList *l;
+
+	for (l = servers; l; l = l->next) {
+		struct server *server = l->data;
+
+		server_stop(server);
+	}
+}
diff --git a/obexd/src/bluetooth.h b/obexd/src/bluetooth.h
index 587f9ff..ad110a1 100644
--- a/obexd/src/bluetooth.h
+++ b/obexd/src/bluetooth.h
@@ -31,4 +31,5 @@ gint bluetooth_init(guint service, const gchar *name, const gchar *folder,
 			guint8 channel, gboolean secure, gboolean auto_accept,
 			const gchar *capability);
 void bluetooth_exit(void);
-void bluetooth_servers_foreach(GFunc func, gpointer user_data);
+void bluetooth_start(void);
+void bluetooth_stop(void);
diff --git a/obexd/src/manager.c b/obexd/src/manager.c
index c479fb3..adcadb3 100644
--- a/obexd/src/manager.c
+++ b/obexd/src/manager.c
@@ -568,6 +568,7 @@ static void find_adapter_reply(DBusPendingCall *call, gpointer user_data)
 		error("Replied with an error: %s, %s",
 				derr.name, derr.message);
 		dbus_error_free(&derr);
+		bluetooth_stop();
 		goto done;
 	}
 
@@ -615,13 +616,14 @@ static gboolean find_adapter_any(gpointer user_data)
 static void name_acquired(DBusConnection *conn, void *user_data)
 {
 	find_adapter_any(NULL);
-	bluetooth_servers_foreach(register_record, NULL);
+	bluetooth_start();
 }
 
 static void name_released(DBusConnection *conn, void *user_data)
 {
 	g_free(any->path);
 	any->path = NULL;
+	bluetooth_stop();
 }
 
 gboolean manager_init(void)
diff --git a/obexd/src/obex.h b/obexd/src/obex.h
index b9c1d67..56a5f37 100644
--- a/obexd/src/obex.h
+++ b/obexd/src/obex.h
@@ -53,6 +53,9 @@ struct server {
 	guint32		handle;
 	uint8_t		channel;
 	gchar		*devnode;
+	gboolean	secure;
+	GIOChannel	*io;
+	guint		watch;
 };
 
 struct obex_session {