Diff between 304d23581b41d11f39f8377bdf4b0e2ecc40bf40 and e114d23e570b8ce8a6d82dc899c6748efe03474a

Changed Files

File Additions Deletions Status
obexd/src/bluetooth.c +4 -6 modified
obexd/src/main.c +31 -53 modified
obexd/src/manager.c +2 -2 modified
obexd/src/obex.c +48 -31 modified
obexd/src/obex.h +5 -5 modified

Full Patch

diff --git a/obexd/src/bluetooth.c b/obexd/src/bluetooth.c
index f0014bd..8c3f564 100644
--- a/obexd/src/bluetooth.c
+++ b/obexd/src/bluetooth.c
@@ -85,17 +85,15 @@ static gboolean connect_event(GIOChannel *io, GIOCondition cond, gpointer user_d
 	info("New connection from: %s, channel %u, fd %d", address,
 			raddr.rc_channel, nsk);
 
-	if (server->service == OBEX_OPP) {
-		if (obex_session_start(nsk, server) < 0)
+	if (server->services != OBEX_OPP) {
+		if (request_service_authorization(server, nsk) < 0)
 			close(nsk);
 
 		return TRUE;
 	}
 
-	if (request_service_authorization(server, nsk) < 0) {
+	if (obex_session_start(nsk, server) < 0)
 		close(nsk);
-		return TRUE;
-	}
 
 	return TRUE;
 }
@@ -165,7 +163,7 @@ static gint server_register(guint16 service, const gchar *name, guint8 channel,
 	}
 
 	server = g_malloc0(sizeof(struct server));
-	server->service = service;
+	server->services = service;
 	server->name = g_strdup(name);
 	server->folder = g_strdup(folder);
 	server->auto_accept = auto_accept;
diff --git a/obexd/src/main.c b/obexd/src/main.c
index 24a002c..4a3ac46 100644
--- a/obexd/src/main.c
+++ b/obexd/src/main.c
@@ -59,17 +59,17 @@
 
 static GMainLoop *main_loop = NULL;
 
-static void tty_init(int service, const gchar *root_path,
-				const gchar *capability, const gchar *devnode)
+static int tty_init(int services, const gchar *root_path,
+			const gchar *capability, const gchar *devnode)
 {
 	struct server *server;
 	struct termios options;
-	gint fd;
+	int fd, ret;
 	glong flags;
 
 	fd = open(devnode, O_RDWR);
 	if (fd < 0)
-		return;
+		return fd;
 
 	flags = fcntl(fd, F_GETFL);
 	fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
@@ -79,52 +79,18 @@ static void tty_init(int service, const gchar *root_path,
 	tcsetattr(fd, TCSANOW, &options);
 
 	server = g_malloc0(sizeof(struct server));
-	server->service = service;
+	server->services = services;
 	server->folder = g_strdup(root_path);
 	server->auto_accept = TRUE;
 	server->capability = g_strdup(capability);
 
-	if (obex_session_start(fd, server) < 0)
+	ret = obex_session_start(fd, server);
+	if (ret < 0) {
+		server_free(server);
 		close(fd);
-
-	return;
-}
-
-static int server_start(int service, const char *root_path,
-			gboolean auto_accept, const gchar *capability,
-							const char *devnode)
-{
-	switch (service) {
-	case OBEX_OPP:
-		bluetooth_init(OBEX_OPP, "Object Push server",
-					root_path, OPP_CHANNEL, FALSE,
-						auto_accept, capability);
-		if (devnode)
-			tty_init(OBEX_OPP, root_path, capability, devnode);
-		break;
-	case OBEX_FTP:
-		bluetooth_init(OBEX_FTP, "File Transfer server",
-					root_path, FTP_CHANNEL, TRUE,
-						auto_accept, capability);
-		if (devnode)
-			tty_init(OBEX_FTP, root_path, capability, devnode);
-		break;
-	case OBEX_PBAP:
-		bluetooth_init(OBEX_PBAP, "Phonebook Access server",
-					root_path, PBAP_CHANNEL, TRUE,
-						auto_accept, capability);
-		break;
-	default:
-		return -EINVAL;
 	}
 
-	return 0;
-}
-
-static void server_stop()
-{
-	/* FIXME: If Bluetooth enabled */
-	bluetooth_exit();
+	return ret;
 }
 
 static void sig_term(int sig)
@@ -172,7 +138,7 @@ int main(int argc, char *argv[])
 	GOptionContext *context;
 	GError *err = NULL;
 	struct sigaction sa;
-	int log_option = LOG_NDELAY | LOG_PID;
+	int log_option = LOG_NDELAY | LOG_PID, services;
 
 #ifdef NEED_THREADS
 	if (g_thread_supported() == FALSE)
@@ -237,16 +203,28 @@ int main(int argc, char *argv[])
 	if (option_capability == NULL)
 		option_capability = g_strdup(DEFAULT_CAP_FILE);
 
-	if (option_opp == TRUE)
-		server_start(OBEX_OPP, option_root, option_autoaccept,
-							NULL, option_devnode);
+	if (option_opp == TRUE) {
+		services |= OBEX_OPP;
+		bluetooth_init(OBEX_OPP, "Object Push server", option_root,
+				OPP_CHANNEL, FALSE, option_autoaccept, NULL);
+	}
 
-	if (option_ftp == TRUE)
-		server_start(OBEX_FTP, option_root, option_autoaccept,
-					option_capability, option_devnode);
+	if (option_ftp == TRUE) {
+		services |= OBEX_FTP;
+		bluetooth_init(OBEX_FTP, "File Transfer server", option_root,
+				FTP_CHANNEL, TRUE, option_autoaccept,
+				option_capability);
+	}
 
-	if (option_pbap == TRUE)
-		server_start(OBEX_PBAP, NULL, FALSE, NULL, NULL);
+	if (option_pbap == TRUE) {
+		services |= OBEX_PBAP;
+		bluetooth_init(OBEX_PBAP, "Phonebook Access server", NULL,
+				PBAP_CHANNEL, TRUE, FALSE, NULL);
+	}
+
+	if (option_devnode)
+		tty_init(services, option_root, option_capability,
+				option_devnode);
 
 	memset(&sa, 0, sizeof(sa));
 	sa.sa_handler = sig_term;
@@ -255,7 +233,7 @@ int main(int argc, char *argv[])
 
 	g_main_loop_run(main_loop);
 
-	server_stop();
+	bluetooth_exit();
 
 	plugin_cleanup();
 
diff --git a/obexd/src/manager.c b/obexd/src/manager.c
index d79c6d8..c479fb3 100644
--- a/obexd/src/manager.c
+++ b/obexd/src/manager.c
@@ -549,7 +549,7 @@ void register_record(gpointer data, gpointer user_data)
 		return;
 	}
 
-	xml = create_xml_record(server->name, server->service, server->channel);
+	xml = create_xml_record(server->name, server->services, server->channel);
 	ret = add_record(any->path, xml, server);
 	g_free(xml);
 }
@@ -579,7 +579,7 @@ static void find_adapter_reply(DBusPendingCall *call, gpointer user_data)
 	for (l = any->servers; l; l = l->next) {
 		server = l->data;
 		xml = create_xml_record(server->name,
-				server->service, server->channel);
+				server->services, server->channel);
 		add_record(path, xml, server);
 		g_free(xml);
 	}
diff --git a/obexd/src/obex.c b/obexd/src/obex.c
index 403e6cc..4768cdf 100644
--- a/obexd/src/obex.c
+++ b/obexd/src/obex.c
@@ -214,19 +214,39 @@ static void cmd_connect(struct obex_session *os,
 	/* connection id will be used to track the sessions, even for OPP */
 	os->cid = ++cid;
 
-	if (os->target == NULL) {
-		register_transfer(os->cid, os);
-		/* OPP doesn't contains target or connection id. */
-		OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
+	while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen)) {
+		if (hi != OBEX_HDR_TARGET || hlen != TARGET_SIZE)
+			continue;
+
+		if (memcmp(hd.bs, FTP_TARGET, TARGET_SIZE) == 0 &&
+				os->server->services & OBEX_FTP) {
+			os->target = FTP_TARGET;
+			os->cmds = &ftp;
+			break;
+		}
+
+		if (memcmp(hd.bs, PBAP_TARGET, TARGET_SIZE) == 0 &&
+				os->server->services & OBEX_PBAP) {
+			os->target = PBAP_TARGET;
+			os->cmds = &pbap;
+			break;
+		}
+
+		error("Connect attempt to a non-supported target");
+		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
 		return;
 	}
 
-	hi = hlen = 0;
-	OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen);
+	if (os->target == NULL) {
+		if (os->server->services & OBEX_OPP) {
+			register_transfer(os->cid, os);
+			/* OPP doesn't contains target or connection id. */
+			OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
+		} else {
+			error("Object Push connect attempt to a non-OPP server");
+			OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
+		}
 
-	if (hi != OBEX_HDR_TARGET || hlen != TARGET_SIZE
-			|| memcmp(os->target, hd.bs, TARGET_SIZE) != 0) {
-		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
 		return;
 	}
 
@@ -234,6 +254,7 @@ static void cmd_connect(struct obex_session *os,
 	emit_session_created(cid);
 
 	/* Append received UUID in WHO header */
+	hd.bs = os->target;
 	OBEX_ObjectAddHeader(obex, obj,
 			OBEX_HDR_WHO, hd, TARGET_SIZE,
 			OBEX_FL_FIT_ONE_PACKET);
@@ -281,7 +302,10 @@ static void cmd_get(struct obex_session *os, obex_t *obex, obex_object_t *obj)
 	guint hlen;
 	guint8 hi;
 
-	if (!os->cmds->get) {
+	if (!os->cmds) {
+		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
+		return;
+	} else if (!os->cmds->get) {
 		OBEX_ObjectSetRsp(obj, OBEX_RSP_NOT_IMPLEMENTED,
 				OBEX_RSP_NOT_IMPLEMENTED);
 		return;
@@ -355,7 +379,10 @@ static void cmd_setpath(struct obex_session *os,
 	guint32 hlen;
 	guint8 hi;
 
-	if (!os->cmds->setpath) {
+	if (!os->cmds) {
+		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
+		return;
+	} else if (!os->cmds->setpath) {
 		OBEX_ObjectSetRsp(obj, OBEX_RSP_NOT_IMPLEMENTED,
 				OBEX_RSP_NOT_IMPLEMENTED);
 		return;
@@ -659,7 +686,7 @@ static gboolean check_put(obex_t *obex, obex_object_t *obj)
 		return FALSE;
 	}
 
-	if (!os->cmds->chkput)
+	if (!os->cmds || !os->cmds->chkput)
 		goto done;
 
 	ret = os->cmds->chkput(obex, obj);
@@ -708,7 +735,10 @@ done:
 
 static void cmd_put(struct obex_session *os, obex_t *obex, obex_object_t *obj)
 {
-	if (!os->cmds->put) {
+	if (!os->cmds) {
+		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
+		return;
+	} else if (!os->cmds->put) {
 		OBEX_ObjectSetRsp(obj, OBEX_RSP_NOT_IMPLEMENTED,
 				OBEX_RSP_NOT_IMPLEMENTED);
 		return;
@@ -784,7 +814,7 @@ static void obex_event(obex_t *obex, obex_object_t *obj, gint mode,
 	case OBEX_EV_REQCHECK:
 		switch (cmd) {
 		case OBEX_CMD_PUT:
-			if (os->cmds->put)
+			if (os->cmds && os->cmds->put)
 				check_put(obex, obj);
 			break;
 		default:
@@ -904,24 +934,11 @@ gint obex_session_start(gint fd, struct server *server)
 	gint ret;
 
 	os = g_new0(struct obex_session, 1);
-	switch (server->service) {
-	case OBEX_OPP:
-		os->target = NULL;
+
+	os->target = NULL;
+
+	if (server->services & OBEX_OPP)
 		os->cmds = &opp;
-		break;
-	case OBEX_FTP:
-		os->target = FTP_TARGET;
-		os->cmds = &ftp;
-		break;
-	case OBEX_PBAP:
-		os->target = PBAP_TARGET;
-		os->cmds = &pbap;
-		break;
-	default:
-		g_free(os);
-		debug("Invalid OBEX server");
-		return -EINVAL;
-	}
 
 	os->current_folder = g_strdup(server->folder);
 	os->server = server;
diff --git a/obexd/src/obex.h b/obexd/src/obex.h
index 01dacfd..6718942 100644
--- a/obexd/src/obex.h
+++ b/obexd/src/obex.h
@@ -29,10 +29,10 @@
 
 #include <glib.h>
 
-#define OBEX_OPP	0x01
-#define OBEX_FTP	0x02
-#define OBEX_BIP	0x03
-#define OBEX_PBAP	0x04
+#define OBEX_OPP	(1 << 0)
+#define OBEX_FTP	(1 << 2)
+#define OBEX_BIP	(1 << 3)
+#define OBEX_PBAP	(1 << 4)
 
 #define OBJECT_SIZE_UNKNOWN -1
 #define OBJECT_SIZE_DELETE -2
@@ -45,7 +45,7 @@ struct obex_commands {
 };
 
 struct server {
-	guint16		service;
+	guint16		services;
 	gboolean	auto_accept;
 	gchar		*name;
 	gchar		*folder;