Diff between ed4a34270a9301fa6a53d4a4f4526c4b3eead4e7 and df2cebf11c6d6be17d5862884aade789dde78555

Changed Files

File Additions Deletions Status
obexd/src/bluetooth.c +59 -73 modified
obexd/src/dbus.h +2 -1 modified
obexd/src/manager.c +49 -30 modified

Full Patch

diff --git a/obexd/src/bluetooth.c b/obexd/src/bluetooth.c
index 37d7b99..06dc29b 100644
--- a/obexd/src/bluetooth.c
+++ b/obexd/src/bluetooth.c
@@ -46,112 +46,98 @@
 #include "bluetooth.h"
 #include "obex.h"
 #include "dbus.h"
+#include "btio.h"
 
 #define BT_RX_MTU 32767
 #define BT_TX_MTU 32767
 
 static GSList *servers = NULL;
 
-static gboolean connect_event(GIOChannel *io, GIOCondition cond, gpointer user_data)
+static void connect_event(GIOChannel *io, GError *err, gpointer user_data)
 {
-	struct sockaddr_rc raddr;
-	socklen_t alen;
 	struct server *server = user_data;
-	gchar address[18];
-	gint err, sk, nsk;
+	gint sk;
 
-	sk = g_io_channel_unix_get_fd(io);
-	alen = sizeof(raddr);
-	nsk = accept(sk, (struct sockaddr *) &raddr, &alen);
-	if (nsk < 0)
-		return TRUE;
-
-	alen = sizeof(raddr);
-	if (getpeername(nsk, (struct sockaddr *) &raddr, &alen) < 0) {
-		err = errno;
-		error("getpeername(): %s(%d)", strerror(err), err);
-		close(nsk);
-		return TRUE;
+	if (err) {
+		error("%s", err->message);
+		return;
 	}
 
-	ba2str(&raddr.rc_bdaddr, address);
-	info("New connection from: %s, channel %u, fd %d", address,
-			raddr.rc_channel, nsk);
-
-	if (server->services != OBEX_OPP) {
-		if (request_service_authorization(server, nsk) < 0)
-			close(nsk);
-
-		return TRUE;
-	}
+	sk = g_io_channel_unix_get_fd(io);
 
-	if (obex_session_start(nsk, server) < 0)
-		close(nsk);
+	if (obex_session_start(sk, server) == 0)
+		return;
 
-	return TRUE;
+	g_io_channel_shutdown(io, TRUE, NULL);
 }
 
-static gint server_start(struct server *server)
+static void confirm_event(GIOChannel *io, gpointer user_data)
 {
-	struct sockaddr_rc laddr;
-	int err, sk, arg;
-
-	sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-	if (sk < 0) {
-		err = errno;
-		error("socket(): %s(%d)", strerror(err), err);
-		return -err;
+	struct server *server = user_data;
+	GError *err = NULL;
+	char address[18];
+	guint8 channel;
+
+	bt_io_get(io, BT_IO_RFCOMM, &err,
+			BT_IO_OPT_DEST, address,
+			BT_IO_OPT_CHANNEL, &channel,
+			BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", err->message);
+		g_error_free(err);
+		goto drop;
 	}
 
-	arg = fcntl(sk, F_GETFL);
-	if (arg < 0) {
-		err = errno;
-		goto failed;
-	}
+	info("New connection from: %s, channel %u", address, channel);
+	g_io_channel_set_close_on_unref(io, FALSE);
 
-	arg |= O_NONBLOCK;
-	if (fcntl(sk, F_SETFL, arg) < 0) {
-		err = errno;
-		goto failed;
-	}
+	if (server->services != OBEX_OPP) {
+		if (request_service_authorization(server, io, address) < 0)
+			goto drop;
 
-	if (server->secure) {
-		int lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT;
+		return;
+	}
 
-		if (setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
-			err = errno;
-			goto failed;
-		}
+	if (!bt_io_accept(io, connect_event, server, NULL, &err)) {
+		error("%s", err->message);
+		g_error_free(err);
+		goto drop;
 	}
 
-	memset(&laddr, 0, sizeof(laddr));
-	laddr.rc_family = AF_BLUETOOTH;
-	bacpy(&laddr.rc_bdaddr, BDADDR_ANY);
-	laddr.rc_channel = server->channel;
+	return;
 
-	if (bind(sk, (struct sockaddr *) &laddr, sizeof(laddr)) < 0) {
-		err = errno;
-		goto failed;
-	}
+drop:
+	g_io_channel_shutdown(io, TRUE, NULL);
+}
 
-	if (listen(sk, 10) < 0) {
-		err = errno;
+static gint server_start(struct server *server)
+{
+	GError *err = NULL;
+
+	/* Listen */
+	if (server->secure)
+		server->io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_event,
+					server, NULL, &err,
+					BT_IO_OPT_CHANNEL, server->channel,
+					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+					BT_IO_OPT_INVALID);
+	else
+		server->io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_event,
+					server, NULL, &err,
+					BT_IO_OPT_CHANNEL, server->channel,
+					BT_IO_OPT_INVALID);
+	if (!server->io)
 		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);
+	error("Bluetooth server register failed: ", err->message);
+	g_error_free(err);
 
-	return -err;
+	return -EINVAL;
 }
 
 static gint server_stop(struct server *server)
diff --git a/obexd/src/dbus.h b/obexd/src/dbus.h
index cf89972..457fe06 100644
--- a/obexd/src/dbus.h
+++ b/obexd/src/dbus.h
@@ -41,7 +41,8 @@ void unregister_transfer(guint32 id);
 
 void register_record(struct server *server, gpointer user_data);
 
-gint request_service_authorization(struct server *server, gint nsk);
+gint request_service_authorization(struct server *server, GIOChannel *io,
+					const char *address);
 
 void register_session(guint32 id, struct obex_session *os);
 
diff --git a/obexd/src/manager.c b/obexd/src/manager.c
index e3524dd..c465d48 100644
--- a/obexd/src/manager.c
+++ b/obexd/src/manager.c
@@ -42,6 +42,7 @@
 #include "obex.h"
 #include "dbus.h"
 #include "logging.h"
+#include "btio.h"
 
 static const gchar *opp_record = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>	\
 <record>									\
@@ -232,10 +233,10 @@ static struct agent *agent = NULL;
 
 struct pending_request {
 	struct server *server;
-	gchar address[18];
 	gchar *adapter_path;
+	char address[18];
 	guint watch;
-	gint nsk;
+	GIOChannel *io;
 };
 
 struct adapter_any {
@@ -998,11 +999,32 @@ static void service_cancel(struct pending_request *pending)
 	g_dbus_send_message(system_conn, msg);
 }
 
+static void connect_event(GIOChannel *io, GError *err, gpointer user_data)
+{
+	struct server *server = user_data;
+	gint sk;
+
+	if (err) {
+		error("%s", err->message);
+		return;
+	}
+
+	sk = g_io_channel_unix_get_fd(io);
+
+	if (obex_session_start(sk, server) == 0)
+		return;
+
+	g_io_channel_shutdown(io, TRUE, NULL);
+}
+
 static void service_reply(DBusPendingCall *call, gpointer user_data)
 {
 	struct pending_request *pending = user_data;
+	GIOChannel *io = pending->io;
+	struct server *server = pending->server;
 	DBusMessage *reply = dbus_pending_call_steal_reply(call);
 	DBusError derr;
+	GError *err = NULL;
 
 	dbus_error_init(&derr);
 	if (dbus_set_error_from_message(&derr, reply)) {
@@ -1013,14 +1035,17 @@ static void service_reply(DBusPendingCall *call, gpointer user_data)
 			service_cancel(pending);
 
 		dbus_error_free(&derr);
-		close(pending->nsk);
+		g_io_channel_shutdown(io, TRUE, NULL);
 		goto done;
 	}
 
 	debug("RequestAuthorization succeeded");
 
-	if (obex_session_start(pending->nsk, pending->server) < 0)
-		close(pending->nsk);
+	if (!bt_io_accept(io, connect_event, server, NULL, &err)) {
+		error("%s", err->message);
+		g_error_free(err);
+		g_io_channel_shutdown(io, TRUE, NULL);
+	}
 
 done:
 	if (pending->watch)
@@ -1048,7 +1073,6 @@ static void find_adapter_reply(DBusPendingCall *call, gpointer user_data)
 	DBusMessage *reply = dbus_pending_call_steal_reply(call);
 	DBusMessage *msg;
 	DBusPendingCall *pcall;
-	GIOChannel *io;
 	const char *paddr = pending->address;
 	const char *path;
 	DBusError derr;
@@ -1092,50 +1116,45 @@ static void find_adapter_reply(DBusPendingCall *call, gpointer user_data)
 	dbus_pending_call_unref(pcall);
 
 	/* Catches errors before authorization response comes */
-	io = g_io_channel_unix_new(pending->nsk);
-	pending->watch = g_io_add_watch_full(io, G_PRIORITY_DEFAULT,
+	pending->watch = g_io_add_watch_full(pending->io, G_PRIORITY_DEFAULT,
 					G_IO_HUP | G_IO_ERR | G_IO_NVAL,
 					service_error, pending, NULL);
-	g_io_channel_unref(io);
+	g_io_channel_unref(pending->io);
 
 	return;
 
 failed:
 	g_free(pending->adapter_path);
-	close(pending->nsk);
+	g_io_channel_shutdown(pending->io, TRUE, NULL);
+	g_io_channel_unref(pending->io);
 	g_free(pending);
 }
 
-gint request_service_authorization(struct server *server, gint nsk)
+gint request_service_authorization(struct server *server, GIOChannel *io,
+					const char *address)
 {
-	struct sockaddr_rc src, dst;
-	socklen_t addrlen;
-	gchar address[18];
-	const gchar *paddr = address;
 	struct pending_request *pending;
+	char source[18];
+	GError *err = NULL;
 
 	if (system_conn == NULL || any->path == NULL)
 		return -1;
 
-	memset(&src, 0, sizeof(src));
-	memset(&dst, 0, sizeof(dst));
-	addrlen = sizeof(src);
-
-	if (getsockname(nsk, (struct sockaddr *) &src, &addrlen) < 0)
-		return -1;
-
-	ba2str(&src.rc_bdaddr, address);
-
-	if (getpeername(nsk, (struct sockaddr *) &dst, &addrlen) < 0)
-		return -1;
+	bt_io_get(io, BT_IO_RFCOMM, &err,
+			BT_IO_OPT_SOURCE, source,
+			BT_IO_OPT_INVALID);
+	if (err) {
+		error("%s", err->message);
+		g_error_free(err);
+		return -EINVAL;
+	}
 
 	pending = g_new0(struct pending_request, 1);
 	pending->server = server;
-	pending->nsk = nsk;
-
-	ba2str(&dst.rc_bdaddr, pending->address);
+	pending->io = g_io_channel_ref(io);
+	memcpy(pending->address, address, sizeof(pending->address));
 
-	find_adapter(paddr, find_adapter_reply, pending);
+	find_adapter(source, find_adapter_reply, pending);
 
 	return 0;
 }