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
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;
}
}
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
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);
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)
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)
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;
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
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);
}
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
/* 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;
}
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);
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;
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;
return FALSE;
}
- if (!os->cmds->chkput)
+ if (!os->cmds || !os->cmds->chkput)
goto done;
ret = os->cmds->chkput(obex, obj);
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;
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:
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
#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
};
struct server {
- guint16 service;
+ guint16 services;
gboolean auto_accept;
gchar *name;
gchar *folder;