diff --git a/obexd/src/bluetooth.c b/obexd/src/bluetooth.c
index d71de24..a385087 100644
--- a/obexd/src/bluetooth.c
+++ b/obexd/src/bluetooth.c
</attribute> \
</record>";
+const static gchar *pbap_record = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
+<record> \
+ <attribute id=\"0x0001\"> \
+ <sequence> \
+ <uuid value=\"0x112f\"/> \
+ </sequence> \
+ </attribute> \
+ \
+ <attribute id=\"0x0004\"> \
+ <sequence> \
+ <sequence> \
+ <uuid value=\"0x0100\"/> \
+ </sequence> \
+ <sequence> \
+ <uuid value=\"0x0003\"/> \
+ <uint8 value=\"%u\" name=\"channel\"/> \
+ </sequence> \
+ <sequence> \
+ <uuid value=\"0x0008\"/> \
+ </sequence> \
+ </sequence> \
+ </attribute> \
+ \
+ <attribute id=\"0x0009\"> \
+ <sequence> \
+ <sequence> \
+ <uuid value=\"0x1130\"/> \
+ <uint16 value=\"0x0100\" name=\"version\"/> \
+ </sequence> \
+ </sequence> \
+ </attribute> \
+ \
+ <attribute id=\"0x0100\"> \
+ <text value=\"%s\" name=\"name\"/> \
+ </attribute> \
+ \
+ <attribute id=\"0x0314\"> \
+ <uint8 value=\"0x01\"/> \
+ </attribute> \
+</record>";
+
static uint32_t register_record(const gchar *name,
guint16 service, guint8 channel)
{
gint handle;
switch (service) {
- case OBEX_OPUSH:
+ case OBEX_OPP:
record = g_markup_printf_escaped(opp_record, channel, name);
break;
case OBEX_FTP:
record = g_markup_printf_escaped(ftp_record, channel, name);
break;
+ case OBEX_PBAP:
+ record = g_markup_printf_escaped(pbap_record, channel, name);
+ break;
default:
return 0;
}
info("New connection from: %s, channel %u, fd %d", address,
raddr.rc_channel, nsk);
- if (server->service == OBEX_OPUSH) {
+ if (server->service == OBEX_OPP) {
if (obex_session_start(nsk, server) < 0)
close(nsk);
}
gint bluetooth_init(guint service, const gchar *name, const gchar *folder,
- guint8 channel, gboolean secure, gboolean auto_accept,
- const gchar *capability)
+ guint8 channel, gboolean secure,
+ gboolean auto_accept, const gchar *capability)
{
- return server_register(service, name, channel,
- folder, secure, auto_accept, capability);
+ return server_register(service, name, channel, folder,
+ secure, auto_accept, capability);
}
void bluetooth_exit(void)
diff --git a/obexd/src/main.c b/obexd/src/main.c
index 3a7937c..09d2144 100644
--- a/obexd/src/main.c
+++ b/obexd/src/main.c
#include "logging.h"
#include "bluetooth.h"
-#include "phonebook.h"
#include "obexd.h"
#include "obex.h"
-#define OPUSH_CHANNEL 9
+#define OPP_CHANNEL 9
#define FTP_CHANNEL 10
+#define PBAP_CHANNEL 15
#define DEFAULT_ROOT_PATH "/tmp"
static GMainLoop *main_loop = NULL;
-static void test_phonebook(void)
-{
- struct phonebook_context *context;
- struct phonebook_driver *driver;
-
- driver = phonebook_get_driver(NULL);
- if (driver == NULL)
- return;
-
- context = phonebook_create(driver);
- if (context == NULL)
- return;
-
- phonebook_pullphonebook(context);
-
- phonebook_unref(context);
-}
-
-static void tty_init(int service, const gchar *root_path, const gchar *capability,
- const gchar *devnode)
+static void tty_init(int service, const gchar *root_path,
+ const gchar *capability, const gchar *devnode)
{
struct server *server;
struct termios options;
}
static int server_start(int service, const char *root_path,
- gboolean auto_accept, const gchar *capability,
- const char *devnode)
+ gboolean auto_accept, const gchar *capability,
+ const char *devnode)
{
switch (service) {
- case OBEX_OPUSH:
- bluetooth_init(OBEX_OPUSH, "OBEX OPUSH server",
- root_path, OPUSH_CHANNEL, FALSE,
- auto_accept, capability);
+ case OBEX_OPP:
+ bluetooth_init(OBEX_OPP, "Object Push server",
+ root_path, OPP_CHANNEL, FALSE,
+ auto_accept, capability);
if (devnode)
- tty_init(OBEX_OPUSH, root_path, capability,
- devnode);
+ tty_init(OBEX_OPP, root_path, capability, devnode);
break;
case OBEX_FTP:
- bluetooth_init(OBEX_FTP, "OBEX FTP server",
- root_path, FTP_CHANNEL, TRUE,
- auto_accept, capability);
-
+ 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;
}
option_capability = g_strdup(DEFAULT_CAP_FILE);
if (option_opp == TRUE)
- server_start(OBEX_OPUSH, option_root, option_autoaccept,
+ server_start(OBEX_OPP, option_root, option_autoaccept,
NULL, option_devnode);
if (option_ftp == TRUE)
option_capability, option_devnode);
if (option_pbap == TRUE)
- test_phonebook();
+ server_start(OBEX_PBAP, NULL, FALSE, NULL, NULL);
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sig_term;
diff --git a/obexd/src/obex.c b/obexd/src/obex.c
index 2ccebd1..de96c8a 100644
--- a/obexd/src/obex.c
+++ b/obexd/src/obex.c
#define RX_MTU 32767
#define TX_MTU 32767
-#define TARGET_SIZE 16
-static const guint8 FTP_TARGET[TARGET_SIZE] = { 0xF9, 0xEC, 0x7B, 0xC4,
- 0x95, 0x3C, 0x11, 0xD2,
- 0x98, 0x4E, 0x52, 0x54,
- 0x00, 0xDC, 0x9E, 0x09 };
+#define TARGET_SIZE 16
+
+static const guint8 FTP_TARGET[TARGET_SIZE] = {
+ 0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2,
+ 0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 };
+
+static const guint8 PBAP_TARGET[TARGET_SIZE] = {
+ 0x79, 0x61, 0x35, 0xF0, 0xF0, 0xC5, 0x11, 0xD8,
+ 0x09, 0x66, 0x08, 0x00, 0x20, 0x0C, 0x9A, 0x66 };
/* Connection ID */
static guint32 cid = 0x0000;
typedef struct {
- guint8 version;
- guint8 flags;
- guint16 mtu;
+ guint8 version;
+ guint8 flags;
+ guint16 mtu;
} __attribute__ ((packed)) obex_connect_hdr_t;
struct obex_commands opp = {
.get = opp_get,
- .chkput = opp_chkput,
.put = opp_put,
- .setpath = NULL,
+ .chkput = opp_chkput,
};
struct obex_commands ftp = {
.get = ftp_get,
.put = ftp_put,
- .setpath = ftp_setpath,
.chkput = ftp_chkput,
+ .setpath = ftp_setpath,
+};
+
+struct obex_commands pbap = {
+ .get = pbap_get,
};
static void os_reset_session(struct obex_session *os)
os = OBEX_GetUserData(obex);
- /* OPUSH doesn't provide a connection id. */
+ /* Object Push doesn't provide a connection id. */
if (os->target == NULL)
return TRUE;
switch (evt) {
case OBEX_EV_PROGRESS:
- /* Just emit progress for OPUSH */
+ /* Just emit progress for Object Push */
if (os->target == NULL)
emit_transfer_progress(os->cid, os->size, os->offset);
break;
os = g_new0(struct obex_session, 1);
switch (server->service) {
- case OBEX_OPUSH:
+ case OBEX_OPP:
os->target = NULL;
os->cmds = &opp;
break;
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");
diff --git a/obexd/src/obex.h b/obexd/src/obex.h
index fad8a2d..e1889ec 100644
--- a/obexd/src/obex.h
+++ b/obexd/src/obex.h
#include <glib.h>
-#define OBEX_OPUSH 0x00
-#define OBEX_FTP 0x01
+#define OBEX_OPP 0x01
+#define OBEX_FTP 0x02
+#define OBEX_BIP 0x03
+#define OBEX_PBAP 0x04
#define OBJECT_SIZE_UNKNOWN -1
#define OBJECT_SIZE_DELETE -2
struct obex_commands {
void (*get) (obex_t *obex, obex_object_t *obj);
- gint (*chkput) (obex_t *obex, obex_object_t *obj);
void (*put) (obex_t *obex, obex_object_t *obj);
+ gint (*chkput) (obex_t *obex, obex_object_t *obj);
void (*setpath) (obex_t *obex, obex_object_t *obj);
};
gint obex_session_start(gint fd, struct server *server);
gint obex_session_stop();
-gint opp_chkput(obex_t *obex, obex_object_t *obj);
-void opp_put(obex_t *obex, obex_object_t *obj);
void opp_get(obex_t *obex, obex_object_t *obj);
+void opp_put(obex_t *obex, obex_object_t *obj);
+gint opp_chkput(obex_t *obex, obex_object_t *obj);
void ftp_get(obex_t *obex, obex_object_t *obj);
void ftp_put(obex_t *obex, obex_object_t *obj);
-void ftp_setpath(obex_t *obex, obex_object_t *obj);
gint ftp_chkput(obex_t *obex, obex_object_t *obj);
+void ftp_setpath(obex_t *obex, obex_object_t *obj);
+
+void pbap_get(obex_t *obex, obex_object_t *obj);
gboolean os_prepare_get(struct obex_session *os, gchar *file, guint32 *size);
gint os_prepare_put(struct obex_session *os);
diff --git a/obexd/src/pbap.c b/obexd/src/pbap.c
new file mode 100644
index 0000000..fa12f12
--- /dev/null
+++ b/obexd/src/pbap.c
+/*
+ *
+ * OBEX Server
+ *
+ * Copyright (C) 2007-2008 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <openobex/obex.h>
+#include <openobex/obex_const.h>
+
+#include <glib.h>
+
+#include "phonebook.h"
+#include "logging.h"
+#include "obex.h"
+
+static void test_phonebook(void)
+{
+ struct phonebook_context *context;
+ struct phonebook_driver *driver;
+
+ driver = phonebook_get_driver(NULL);
+ if (driver == NULL)
+ return;
+
+ context = phonebook_create(driver);
+ if (context == NULL)
+ return;
+
+ phonebook_pullphonebook(context);
+
+ phonebook_unref(context);
+}
+
+void pbap_get(obex_t *obex, obex_object_t *obj)
+{
+ struct obex_session *os;
+ obex_headerdata_t hv;
+ guint32 size;
+
+ os = OBEX_GetUserData(obex);
+ if (os == NULL)
+ return;
+
+ if (os->name)
+ goto fail;
+
+ if (os->type == NULL)
+ goto fail;
+
+ test_phonebook();
+ size = 0;
+
+ hv.bq4 = size;
+ OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_LENGTH, hv, 4, 0);
+
+ /* Add body header */
+ hv.bs = NULL;
+ if (size == 0)
+ OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY,
+ hv, 0, OBEX_FL_FIT_ONE_PACKET);
+ else
+ OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY,
+ hv, 0, OBEX_FL_STREAM_START);
+
+ OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
+
+ return;
+
+fail:
+ OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
+}