File openobex-svn.patch of Package openobex
diff -urN openobex-1.3/acinclude.m4 openobex/acinclude.m4
--- openobex-1.3/acinclude.m4 2006-06-14 11:11:47.000000000 +0200
+++ openobex/acinclude.m4 2006-12-31 16:09:27.000000000 +0100
@@ -44,6 +44,15 @@
AC_DEFINE_UNQUOTED(CONFIGDIR, "${configdir}", [Directory for the configuration files])
])
+AC_DEFUN([AC_PATH_WIN32], [
+ case $host in
+ *-*-mingw32*)
+ EXTRA_LIBS="$EXTRA_LIBS -lws2_32"
+ ;;
+ esac
+ AC_SUBST(EXTRA_LIBS)
+])
+
AC_DEFUN([AC_PATH_IRDA], [
AC_CACHE_CHECK([for IrDA support], irda_found, [
AC_TRY_COMPILE([
@@ -55,25 +64,76 @@
])
])
+AC_DEFUN([AC_PATH_NETBSDBT], [
+ AC_CACHE_CHECK([for NetBSD Bluetooth support], netbsdbt_found, [
+ AC_TRY_COMPILE([
+ #include <bluetooth.h>
+ ], [
+ struct sockaddr_bt *bt;
+ ], netbsdbt_found=yes, netbsdbt_found=no)
+ ])
+])
+
+AC_DEFUN([AC_PATH_FREEBSDBT], [
+ AC_CACHE_CHECK([for FreeBSD Bluetooth support], freebsdbt_found, [
+ AC_TRY_COMPILE([
+ #include <bluetooth.h>
+ ], [
+ struct sockaddr_rfcomm *rfcomm;
+ ], freebsdbt_found=yes, freebsdbt_found=no)
+ ])
+])
+
AC_DEFUN([AC_PATH_BLUEZ], [
PKG_CHECK_MODULES(BLUEZ, bluez, bluez_found=yes, AC_MSG_RESULT(no))
AC_SUBST(BLUEZ_CFLAGS)
AC_SUBST(BLUEZ_LIBS)
])
+AC_DEFUN([AC_PATH_BLUETOOTH], [
+ case $host in
+ *-*-linux*)
+ AC_PATH_BLUEZ
+ ;;
+ *-*-freebsd*)
+ AC_PATH_FREEBSDBT
+ ;;
+ *-*-netbsd*)
+ AC_PATH_NETBSDBT
+ ;;
+ esac
+])
+
AC_DEFUN([AC_PATH_USB], [
- PKG_CHECK_MODULES(USB, libusb, usb_found=yes, AC_MSG_RESULT(no))
+ case $host in
+ *-*-mingw32*)
+ USB_CFLAGS=""
+ USB_LIBS="-lusb"
+ ;;
+ *)
+ PKG_CHECK_MODULES(USB, libusb, usb_found=yes, AC_MSG_RESULT(no))
+ ;;
+ esac
AC_SUBST(USB_CFLAGS)
AC_SUBST(USB_LIBS)
AC_CHECK_LIB(usb, usb_get_busses, dummy=yes, AC_DEFINE(NEED_USB_GET_BUSSES, 1, [Define to 1 if you need the usb_get_busses() function.]))
AC_CHECK_LIB(usb, usb_interrupt_read, dummy=yes, AC_DEFINE(NEED_USB_INTERRUPT_READ, 1, [Define to 1 if you need the usb_interrupt_read() function.]))
])
+AC_DEFUN([AC_PATH_GLIB], [
+ PKG_CHECK_MODULES(GLIB, glib-2.0 gobject-2.0 gthread-2.0, glib_found=yes, AC_MSG_RESULT(no))
+ AC_SUBST(GLIB_CFLAGS)
+ AC_SUBST(GLIB_LIBS)
+ GLIB_GENMARSHAL=`$PKG_CONFIG --variable=glib_genmarshal glib-2.0`
+ AC_SUBST(GLIB_GENMARSHAL)
+])
+
AC_DEFUN([AC_ARG_OPENOBEX], [
fortify_enable=yes
irda_enable=yes
bluetooth_enable=yes
usb_enable=yes
+ glib_enable=no
apps_enable=no
debug_enable=no
syslog_enable=no
@@ -95,6 +155,10 @@
usb_enable=${enableval}
])
+ AC_ARG_ENABLE(glib, AC_HELP_STRING([--enable-glib], [enable GLib bindings]), [
+ glib_enable=${enableval}
+ ])
+
AC_ARG_ENABLE(apps, AC_HELP_STRING([--enable-apps], [enable test applications]), [
apps_enable=${enableval}
])
@@ -121,16 +185,27 @@
AC_DEFINE(HAVE_IRDA, 1, [Define if system supports IrDA and it's enabled])
fi
+ if (test "${bluetooth_enable}" = "yes" && test "${netbsdbt_found}" = "yes"); then
+ AC_DEFINE(HAVE_BLUETOOTH, 1, [Define if system supports Bluetooth and it's enabled])
+ AC_DEFINE(HAVE_BLUETOOTH_NETBSD, 1, [Define if system supports Bluetooth stack for NetBSD])
+ fi
+
+ if (test "${bluetooth_enable}" = "yes" && test "${freebsdbt_found}" = "yes"); then
+ AC_DEFINE(HAVE_BLUETOOTH, 1, [Define if system supports Bluetooth and it's enabled])
+ AC_DEFINE(HAVE_BLUETOOTH_FREEBSD, 1, [Define if system supports Bluetooth stack for FreeBSD])
+ fi
+
if (test "${bluetooth_enable}" = "yes" && test "${bluez_found}" = "yes"); then
AC_DEFINE(HAVE_BLUETOOTH, 1, [Define if system supports Bluetooth and it's enabled])
- REQUIRES="bluez"
+ AC_DEFINE(HAVE_BLUETOOTH_LINUX, 1, [Define if system supports Bluetooth stack for Linux])
fi
if (test "${usb_enable}" = "yes" && test "${usb_found}" = "yes"); then
AC_DEFINE(HAVE_USB, 1, [Define if system supports USB and it's enabled])
- AC_CHECK_FILE(${prefix}/lib/pkgconfig/libusb.pc, REQUIRES="$REQUIRES libusb")
+ AC_CHECK_FILE(${prefix}/lib/pkgconfig/libusb.pc, REQUIRES="libusb")
fi
+ AM_CONDITIONAL(GLIB, test "${glib_enable}" = "yes" && test "${glib_found}" = "yes")
AM_CONDITIONAL(APPS, test "${apps_enable}" = "yes")
if (test "${debug_enable}" = "yes" && test "${ac_cv_prog_cc_g}" = "yes"); then
diff -urN openobex-1.3/apps/Makefile.am openobex/apps/Makefile.am
--- openobex-1.3/apps/Makefile.am 2006-01-03 19:36:15.000000000 +0100
+++ openobex/apps/Makefile.am 2006-09-29 14:13:03.000000000 +0200
@@ -14,11 +14,11 @@
obex_test_server.c obex_test_server.h \
obex_test_cable.c obex_test_cable.h
-obex_test_LDADD = $(top_builddir)/lib/libopenobex.la @BLUEZ_LIBS@ @USB_LIBS@ libmisc.a
+obex_test_LDADD = $(top_builddir)/lib/libopenobex.la @BLUEZ_LIBS@ libmisc.a
LDADD = $(top_builddir)/lib/libopenobex.la libmisc.a
-INCLUDES = @USB_CFLAGS@ @BLUEZ_CFLAGS@ -I$(top_builddir)/include
+INCLUDES = @BLUEZ_CFLAGS@ -I$(top_builddir)/include
endif
MAINTAINERCLEANFILES = Makefile.in
diff -urN openobex-1.3/apps/obex_put_common.c openobex/apps/obex_put_common.c
--- openobex-1.3/apps/obex_put_common.c 2006-01-03 19:36:15.000000000 +0100
+++ openobex/apps/obex_put_common.c 2006-08-26 20:10:24.000000000 +0200
@@ -176,7 +176,7 @@
case OBEX_EV_REQDONE:
printf("\n");
/* Comes when a command has finished. */
- if(mode == OBEX_CLIENT)
+ if(mode == OBEX_MODE_CLIENT)
client_done(object, obex_cmd, obex_rsp);
else
server_done(object, obex_cmd);
diff -urN openobex-1.3/apps/obex_tcp.c openobex/apps/obex_tcp.c
--- openobex-1.3/apps/obex_tcp.c 2006-05-16 15:30:24.000000000 +0200
+++ openobex/apps/obex_tcp.c 2006-12-31 16:09:27.000000000 +0100
@@ -38,7 +38,7 @@
#include <string.h>
#if _WIN32
-#include <winsock.h>
+#include <winsock2.h>
#else
#include <sys/stat.h>
diff -urN openobex-1.3/apps/obex_test.c openobex/apps/obex_test.c
--- openobex-1.3/apps/obex_test.c 2006-05-16 15:26:15.000000000 +0200
+++ openobex/apps/obex_test.c 2007-01-25 09:44:43.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Pontus Fuchs <pontus.fuchs@tactel.se>
* Created at: Wed Nov 17 22:05:16 1999
- * CVS ID: $Id: obex_test.c,v 1.27 2006/05/16 13:26:15 holtmann Exp $
+ * CVS ID: $Id: obex_test.c 298 2007-01-25 08:44:43Z holtmann $
*
* Copyright (c) 2000, Pontus Fuchs, All Rights Reserved.
*
@@ -35,7 +35,7 @@
#include <string.h>
#if _WIN32
-#include <winsock.h>
+#include <winsock2.h>
#else
#include <sys/socket.h>
#include <arpa/inet.h>
@@ -44,9 +44,28 @@
#endif /* _WIN32 */
#ifdef HAVE_BLUETOOTH
+#ifdef HAVE_BLUETOOTH_LINUX
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#endif
+#ifdef HAVE_BLUETOOTH_FREEBSD
+#include <bluetooth.h>
+#define sockaddr_rc sockaddr_rfcomm
+#define rc_family rfcomm_family
+#define rc_bdaddr rfcomm_bdaddr
+#define rc_channel rfcomm_channel
+#define str2ba bt_aton
+#endif
+#ifdef HAVE_BLUETOOTH_NETBSD
+#define rc_family bt_family
+#define rc_bdaddr bt_bdaddr
+#define rc_channel bt_channel
+#define sockaddr_rc sockaddr_bt
+#define str2ba bt_aton
+#include <bluetooth.h>
+#include <netbt/rfcomm.h>
+#endif
+#endif
#include <openobex/obex.h>
@@ -79,7 +98,7 @@
break;
case OBEX_EV_REQDONE:
- if(mode == OBEX_CLIENT) {
+ if(mode == OBEX_MODE_CLIENT) {
client_done(handle, object, obex_cmd, obex_rsp);
}
else {
@@ -155,7 +174,7 @@
int main (int argc, char *argv[])
{
char cmd[10];
- int end = 0;
+ int num, end = 0;
int cobex = FALSE, tcpobex = FALSE, btobex = FALSE, r320 = FALSE, usbobex = FALSE;
obex_t *handle;
#ifdef HAVE_BLUETOOTH
@@ -320,7 +339,7 @@
while (!end) {
printf("> ");
- scanf("%s", cmd);
+ num = scanf("%s", cmd);
switch (cmd[0] | 0x20) {
case 'q':
end=1;
@@ -340,7 +359,7 @@
case 'c':
/* First connect transport */
if(tcpobex) {
- if(inet_connect(handle) < 0) {
+ if(TcpOBEX_TransportConnect(handle, NULL, 0) < 0) {
printf("Transport connect error! (TCP)\n");
break;
}
@@ -386,7 +405,7 @@
case 's':
/* First register server */
if(tcpobex) {
- if(InOBEX_ServerRegister(handle) < 0) {
+ if(TcpOBEX_ServerRegister(handle, NULL, 0) < 0) {
printf("Server register error! (TCP)\n");
break;
}
diff -urN openobex-1.3/apps/obex_test_cable.c openobex/apps/obex_test_cable.c
--- openobex-1.3/apps/obex_test_cable.c 2006-01-18 14:02:14.000000000 +0100
+++ openobex/apps/obex_test_cable.c 2006-01-18 14:02:14.000000000 +0100
@@ -7,7 +7,7 @@
* Status: Experimental.
* Author: Pontus Fuchs <pontus.fuchs@tactel.se>
* Created at: Wed Nov 17 22:05:16 1999
- * CVS ID: $Id: obex_test_cable.c,v 1.21 2006/01/18 13:02:14 holtmann Exp $
+ * CVS ID: $Id: obex_test_cable.c 210 2006-01-18 13:02:14Z holtmann $
*
* Copyright (c) 1999, 2000 Pontus Fuchs, All Rights Reserved.
*
diff -urN openobex-1.3/apps/obex_test_client.c openobex/apps/obex_test_client.c
--- openobex-1.3/apps/obex_test_client.c 2006-05-16 15:26:15.000000000 +0200
+++ openobex/apps/obex_test_client.c 2006-08-28 16:23:53.000000000 +0200
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Pontus Fuchs <pontus.fuchs@tactel.se>
* Created at: Sun Aug 13 03:00:28 PM CEST 2000
- * CVS ID: $Id: obex_test_client.c,v 1.17 2006/05/16 13:26:15 holtmann Exp $
+ * CVS ID: $Id: obex_test_client.c 263 2006-08-28 14:23:53Z holtmann $
*
* Copyright (c) 2000, Pontus Fuchs, All Rights Reserved.
*
@@ -220,6 +220,7 @@
unsigned int uname_size;
char *bfname;
uint8_t *uname;
+ int num;
obex_headerdata_t hd;
@@ -227,7 +228,7 @@
int file_size;
printf("PUSH filename> ");
- scanf("%s", fname);
+ num = scanf("%s", fname);
bfname = strdup(basename(fname));
buf = easy_readfile(fname, &file_size);
@@ -280,12 +281,13 @@
char rname[200];
unsigned int rname_size;
obex_headerdata_t hd;
+ int num;
uint8_t *buf;
int file_size;
printf("PUT file (local, remote)> ");
- scanf("%s %s", lname, rname);
+ num = scanf("%s %s", lname, rname);
buf = easy_readfile(lname, &file_size);
if(buf == NULL) {
@@ -336,11 +338,11 @@
obex_object_t *object;
uint8_t rname[200];
char req_name[200];
- int rname_size;
+ int num, rname_size;
obex_headerdata_t hd;
printf("GET File> ");
- scanf("%s", req_name);
+ num = scanf("%s", req_name);
if(! (object = OBEX_ObjectNew(handle, OBEX_CMD_GET))) {
printf("Error\n");
@@ -407,11 +409,11 @@
uint8_t setpath_data[2] = { 0, 0 };
obex_object_t *object;
char path[200];
- int path_size;
+ int num, path_size;
obex_headerdata_t hd;
printf("SETPATH> ");
- scanf("%s", path);
+ num = scanf("%s", path);
if(! (object = OBEX_ObjectNew(handle, OBEX_CMD_SETPATH))) {
printf("Error\n");
diff -urN openobex-1.3/AUTHORS openobex/AUTHORS
--- openobex-1.3/AUTHORS 2005-12-25 14:20:28.000000000 +0100
+++ openobex/AUTHORS 2007-01-24 19:43:28.000000000 +0100
@@ -8,3 +8,4 @@
Christian W. Zuckschwerdt <zany@triq.net>
Alex Kanavin <ak@sensi.org>
Johan Hedberg <johan.hedberg@nokia.com>
+Hendrik Sattler <post@hendrik-sattler.de>
diff -urN openobex-1.3/bootstrap openobex/bootstrap
--- openobex-1.3/bootstrap 1970-01-01 01:00:00.000000000 +0100
+++ openobex/bootstrap 2006-01-18 14:02:14.000000000 +0100
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+aclocal && \
+ autoheader && \
+ libtoolize --copy --force || glibtoolize --copy --force && \
+ automake --add-missing --copy && \
+ autoconf
diff -urN openobex-1.3/bootstrap-configure openobex/bootstrap-configure
--- openobex-1.3/bootstrap-configure 1970-01-01 01:00:00.000000000 +0100
+++ openobex/bootstrap-configure 2006-08-26 18:38:50.000000000 +0200
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+if [ -f config.status ]; then
+ make maintainer-clean
+fi
+
+./bootstrap && \
+ ./configure --enable-maintainer-mode \
+ --prefix=/usr \
+ --sysconfdir=/etc \
+ --enable-glib \
+ --enable-apps
diff -urN openobex-1.3/configure.in openobex/configure.in
--- openobex-1.3/configure.in 2006-06-14 11:24:13.000000000 +0200
+++ openobex/configure.in 2006-12-31 16:09:27.000000000 +0100
@@ -17,12 +17,18 @@
m4_define([_LT_AC_TAGCONFIG], [])
m4_ifdef([AC_LIBTOOL_TAGS], [AC_LIBTOOL_TAGS([])])
+AC_LIBTOOL_WIN32_DLL
+
AC_PROG_LIBTOOL
+AC_CANONICAL_HOST
+
+AC_PATH_WIN32
+AC_PATH_GLIB
AC_PATH_IRDA
-AC_PATH_BLUEZ
+AC_PATH_BLUETOOTH
AC_PATH_USB
AC_ARG_OPENOBEX
-AC_OUTPUT(Makefile include/Makefile lib/Makefile apps/Makefile ircp/Makefile doc/Makefile openobex.pc)
+AC_OUTPUT(Makefile include/Makefile lib/Makefile glib/Makefile apps/Makefile ircp/Makefile doc/Makefile openobex.pc openobex-glib.pc)
diff -urN openobex-1.3/doc/Makefile.am openobex/doc/Makefile.am
--- openobex-1.3/doc/Makefile.am 2006-03-29 16:51:52.000000000 +0200
+++ openobex/doc/Makefile.am 2006-11-01 19:46:42.000000000 +0100
@@ -29,7 +29,7 @@
(echo "*** You need to install DocBook stylesheets ***"; \
exit 1)
-$(RM) -r $@
- docbook2html $<
+ docbook2html -o $@ $<
if [ ! -z "$(JPG-$@)" ]; then cp $(JPG-$@) $@; fi
diff -urN openobex-1.3/doc/openobex.tmpl openobex/doc/openobex.tmpl
--- openobex-1.3/doc/openobex.tmpl 2006-03-29 16:51:52.000000000 +0200
+++ openobex/doc/openobex.tmpl 2006-11-01 19:46:42.000000000 +0100
@@ -1,7 +1,7 @@
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
- "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
-<!-- use this for sgml tools
- DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]-->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]>
+<!-- use this for xml tool chain
+ DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+ "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"-->
<book id="OpenOBEX-Guide">
<bookinfo>
diff -urN openobex-1.3/glib/Makefile.am openobex/glib/Makefile.am
--- openobex-1.3/glib/Makefile.am 1970-01-01 01:00:00.000000000 +0100
+++ openobex/glib/Makefile.am 2006-09-11 22:32:16.000000000 +0200
@@ -0,0 +1,42 @@
+
+includedir = @includedir@/openobex
+
+if GLIB
+include_HEADERS = obex-client.h
+
+lib_LTLIBRARIES = libopenobex-glib.la
+
+libopenobex_glib_la_SOURCES = obex-lowlevel.h obex-lowlevel.c obex-client.c obex-debug.h obex-error.c obex-error.h
+
+libopenobex_glib_la_LDFLAGS = -version-info 1:0:0
+
+libopenobex_glib_la_LIBADD = @GLIB_LIBS@ $(top_builddir)/lib/libopenobex.la
+
+BUILT_SOURCES = obex-marshal.h obex-marshal.c
+
+nodist_libopenobex_glib_la_SOURCES = $(BUILT_SOURCES)
+
+CLEANFILES = $(BUILT_SOURCES)
+
+noinst_PROGRAMS = test-lowlevel test-client
+
+test_lowlevel_LDADD = libopenobex-glib.la
+
+test_client_LDADD = @GLIB_LIBS@ libopenobex-glib.la
+endif
+
+AM_CFLAGS = @GLIB_CFLAGS@
+
+INCLUDES = -I$(top_builddir)/include
+
+EXTRA_DIST = obex-marshal.list
+
+MAINTAINERCLEANFILES = Makefile.in
+
+if GLIB
+obex-marshal.h: obex-marshal.list
+ $(GLIB_GENMARSHAL) --prefix=obex_marshal $< --header > $@
+
+obex-marshal.c: obex-marshal.list
+ $(GLIB_GENMARSHAL) --prefix=obex_marshal $< --body > $@
+endif
diff -urN openobex-1.3/glib/obex-client.c openobex/glib/obex-client.c
--- openobex-1.3/glib/obex-client.c 1970-01-01 01:00:00.000000000 +0100
+++ openobex/glib/obex-client.c 2006-09-13 15:25:37.000000000 +0200
@@ -0,0 +1,587 @@
+/*
+ *
+ * OpenOBEX - Free implementation of the Object Exchange protocol
+ *
+ * Copyright (C) 2005-2006 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 <errno.h>
+
+#include "obex-debug.h"
+#include "obex-lowlevel.h"
+#include "obex-error.h"
+#include "obex-marshal.h"
+#include "obex-client.h"
+
+#define OBEX_CLIENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ OBEX_TYPE_CLIENT, ObexClientPrivate))
+
+typedef struct _ObexClientPrivate ObexClientPrivate;
+
+struct _ObexClientPrivate {
+ gboolean auto_connect;
+
+#ifdef G_THREADS_ENABLED
+ GMutex *mutex;
+#endif
+
+ GMainContext *context;
+ GIOChannel *channel;
+ obex_t *handle;
+
+ gpointer watch_data;
+ ObexClientFunc watch_func;
+ GDestroyNotify watch_destroy;
+
+ GSource *idle_source;
+
+ gboolean connected;
+};
+
+G_DEFINE_TYPE(ObexClient, obex_client, G_TYPE_OBJECT)
+
+static void obex_client_init(ObexClient *self)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+
+#ifdef G_THREADS_ENABLED
+ priv->mutex = g_mutex_new();
+#endif
+
+ priv->auto_connect = TRUE;
+
+ priv->context = g_main_context_default();
+ g_main_context_ref(priv->context);
+
+ priv->connected = FALSE;
+}
+
+static void obex_client_finalize(GObject *object)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(object);
+
+ if (priv->connected == TRUE && priv->auto_connect == TRUE)
+ obex_disconnect(priv->handle);
+
+ if (priv->idle_source) {
+ g_source_destroy(priv->idle_source);
+ priv->idle_source = NULL;
+ }
+
+ obex_close(priv->handle);
+ priv->handle = NULL;
+
+ g_main_context_unref(priv->context);
+ priv->context = NULL;
+
+#ifdef G_THREADS_ENABLED
+ g_mutex_free(priv->mutex);
+#endif
+}
+
+enum {
+ PROP_0,
+ PROP_AUTO_CONNECT
+};
+
+static void obex_client_set_property(GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_AUTO_CONNECT:
+ priv->auto_connect = g_value_get_boolean(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void obex_client_get_property(GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_AUTO_CONNECT:
+ g_value_set_boolean(value, priv->auto_connect);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+enum {
+ CONNECTED_SIGNAL,
+ DISCONNECT_SIGNAL,
+ CANCELED_SIGNAL,
+ PROGRESS_SIGNAL,
+ IDLE_SIGNAL,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void obex_client_class_init(ObexClientClass *klass)
+{
+#ifdef G_THREADS_ENABLED
+ if (!g_thread_supported())
+ g_thread_init(NULL);
+#endif
+
+ g_type_class_add_private(klass, sizeof(ObexClientPrivate));
+
+ G_OBJECT_CLASS(klass)->finalize = obex_client_finalize;
+
+ G_OBJECT_CLASS(klass)->set_property = obex_client_set_property;
+ G_OBJECT_CLASS(klass)->get_property = obex_client_get_property;
+
+ g_object_class_install_property(G_OBJECT_CLASS(klass),
+ PROP_AUTO_CONNECT, g_param_spec_boolean("auto-connect",
+ NULL, NULL, TRUE, G_PARAM_READWRITE));
+
+ signals[CONNECTED_SIGNAL] = g_signal_new("connected",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(ObexClientClass, connected),
+ NULL, NULL,
+ obex_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[DISCONNECT_SIGNAL] = g_signal_new("disconnect",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(ObexClientClass, disconnect),
+ NULL, NULL,
+ obex_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[CANCELED_SIGNAL] = g_signal_new("canceled",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(ObexClientClass, canceled),
+ NULL, NULL,
+ obex_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[PROGRESS_SIGNAL] = g_signal_new("progress",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(ObexClientClass, progress),
+ NULL, NULL,
+ obex_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[IDLE_SIGNAL] = g_signal_new("idle",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(ObexClientClass, idle),
+ NULL, NULL,
+ obex_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static gboolean obex_client_callback(GIOChannel *source,
+ GIOCondition cond, gpointer data)
+{
+ ObexClient *self = data;
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+
+ if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+ debug("link error");
+ return FALSE;
+ }
+
+ if (OBEX_HandleInput(priv->handle, 1) < 0)
+ debug("input error");
+ else
+ obex_do_callback(priv->handle);
+
+ return TRUE;
+}
+
+static gboolean obex_client_put_idle(ObexClient *self)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+
+ debug("obex_client_put_idle");
+
+ g_source_destroy(priv->idle_source);
+ priv->idle_source = NULL;
+
+ if (priv->watch_func)
+ priv->watch_func(self, OBEX_CLIENT_COND_OUT, priv->watch_data);
+
+ return FALSE;
+}
+
+ObexClient *obex_client_new(void)
+{
+ return OBEX_CLIENT(g_object_new(OBEX_TYPE_CLIENT, NULL));
+}
+
+void obex_client_destroy(ObexClient *self)
+{
+ g_object_unref(self);
+}
+
+void obex_client_set_auto_connect(ObexClient *self, gboolean auto_connect)
+{
+ g_object_set(self, "auto-connect", auto_connect, NULL);
+}
+
+gboolean obex_client_get_auto_connect(ObexClient *self)
+{
+ gboolean auto_connect;
+
+ g_object_get(self, "auto-connect", &auto_connect, NULL);
+
+ return auto_connect;
+}
+
+void obex_client_add_watch_full(ObexClient *self,
+ ObexClientCondition condition, ObexClientFunc func,
+ gpointer data, GDestroyNotify notify)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+
+ priv->watch_data = data;
+ priv->watch_func = func;
+ priv->watch_destroy = notify;
+}
+
+void obex_client_add_watch(ObexClient *self, ObexClientCondition condition,
+ ObexClientFunc func, gpointer data)
+{
+ obex_client_add_watch_full(self, condition, func, data, NULL);
+}
+
+static void obex_connect_cfm(obex_t *handle, void *user_data)
+{
+ ObexClient *self = user_data;
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+
+ debug("connected");
+
+ priv->connected = TRUE;
+
+ g_signal_emit(self, signals[CONNECTED_SIGNAL], 0, NULL);
+}
+
+static void obex_disconn_ind(obex_t *handle, void *user_data)
+{
+ ObexClient *self = user_data;
+
+ debug("disconnect");
+
+ g_signal_emit(self, signals[DISCONNECT_SIGNAL], 0, NULL);
+}
+
+static void obex_progress_ind(obex_t *handle, void *user_data)
+{
+ ObexClient *self = user_data;
+
+ debug("progress");
+
+ g_signal_emit(self, signals[PROGRESS_SIGNAL], 0, NULL);
+}
+
+static void obex_command_ind(obex_t *handle, int event, void *user_data)
+{
+ ObexClient *self = user_data;
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+
+ if (!priv->watch_func)
+ return;
+
+ switch (event) {
+ case OBEX_EV_LINKERR:
+ case OBEX_EV_PARSEERR:
+ priv->watch_func(self, OBEX_CLIENT_COND_ERR, priv->watch_data);
+ break;
+
+ case OBEX_EV_STREAMAVAIL:
+ priv->watch_func(self, OBEX_CLIENT_COND_IN, priv->watch_data);
+ break;
+
+ case OBEX_EV_STREAMEMPTY:
+ priv->watch_func(self, OBEX_CLIENT_COND_OUT, priv->watch_data);
+ break;
+
+ case OBEX_EV_ABORT:
+ case OBEX_EV_REQDONE:
+ priv->watch_func(self, OBEX_CLIENT_COND_DONE, priv->watch_data);
+ break;
+
+ default:
+ debug("unhandled event %d", event);
+ break;
+ }
+}
+
+static obex_callback_t callback = {
+ .connect_cfm = obex_connect_cfm,
+ .disconn_ind = obex_disconn_ind,
+ .progress_ind = obex_progress_ind,
+ .command_ind = obex_command_ind,
+};
+
+void obex_client_attach_fd(ObexClient *self, int fd)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ GSource *source;
+
+ priv->handle = obex_open(fd, &callback, self);
+ if (priv->handle == NULL)
+ return;
+
+ priv->channel = g_io_channel_unix_new(fd);
+
+ source = g_io_create_watch(priv->channel,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL);
+
+ g_source_set_callback(source, (GSourceFunc) obex_client_callback,
+ self, NULL);
+
+ g_source_attach(source, priv->context);
+
+ g_source_unref(source);
+}
+
+gboolean obex_client_connect(ObexClient *self, const guchar *target,
+ gsize size, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int err;
+
+ err = obex_connect(priv->handle, target, size);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean obex_client_disconnect(ObexClient *self, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int err;
+
+ err = obex_disconnect(priv->handle);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean obex_client_put_object(ObexClient *self, const gchar *type,
+ const gchar *name, gint size,
+ time_t mtime, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ gboolean add_idle = FALSE;
+ int err;
+
+ if (priv->connected == FALSE && priv->auto_connect == TRUE)
+ obex_connect(priv->handle, NULL, 0);
+ else
+ add_idle = TRUE;
+
+ err = obex_put(priv->handle, type, name, size, mtime);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ /* So the application gets OBEX_CLIENT_COND_OUT immediately when
+ * returning to the mainloop */
+ if (add_idle) {
+ priv->idle_source = g_idle_source_new();
+ g_source_set_callback(priv->idle_source, (GSourceFunc) obex_client_put_idle,
+ self, NULL);
+ g_source_attach(priv->idle_source, priv->context);
+ g_source_unref(priv->idle_source);
+ }
+
+ return TRUE;
+}
+
+gboolean obex_client_get_object(ObexClient *self, const gchar *type,
+ const gchar *name, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int err;
+
+ if (priv->connected == FALSE && priv->auto_connect == TRUE)
+ obex_connect(priv->handle, NULL, 0);
+
+ err = obex_get(priv->handle, type, name);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean obex_client_read(ObexClient *self, gchar *buf, gsize count,
+ gsize *bytes_read, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int err;
+
+ err = obex_read(priv->handle, buf, count, bytes_read);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean obex_client_write(ObexClient *self, const gchar *buf, gsize count,
+ gsize *bytes_written, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int err;
+
+ err = obex_write(priv->handle, buf, count, bytes_written);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean obex_client_flush(ObexClient *self, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int err;
+
+ err = obex_flush(priv->handle);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean obex_client_abort(ObexClient *self, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int err;
+
+ err = obex_abort(priv->handle);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean obex_client_close(ObexClient *self, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int err;
+
+ debug("");
+
+ err = obex_close_transfer(priv->handle);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean obex_client_get_error(ObexClient *self, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int rsp;
+
+ rsp = obex_get_response(priv->handle);
+ if (rsp == OBEX_RSP_SUCCESS)
+ return TRUE;
+
+ rsp2gerror(rsp, error);
+
+ return FALSE;
+}
+
+gboolean obex_client_mkdir(ObexClient *self, const gchar *path, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int err;
+
+ debug("");
+
+ err = obex_setpath(priv->handle, path, 1);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean obex_client_chdir(ObexClient *self, const gchar *path, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int err;
+
+ debug("");
+
+ err = obex_setpath(priv->handle, path, 0);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean obex_client_delete(ObexClient *self, const gchar *name, GError **error)
+{
+ ObexClientPrivate *priv = OBEX_CLIENT_GET_PRIVATE(self);
+ int err;
+
+ debug("");
+
+ err = obex_delete(priv->handle, name);
+ if (err < 0) {
+ err2gerror(-err, error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff -urN openobex-1.3/glib/obex-client.h openobex/glib/obex-client.h
--- openobex-1.3/glib/obex-client.h 1970-01-01 01:00:00.000000000 +0100
+++ openobex/glib/obex-client.h 2006-09-13 15:25:37.000000000 +0200
@@ -0,0 +1,165 @@
+/*
+ *
+ * OpenOBEX - Free implementation of the Object Exchange protocol
+ *
+ * Copyright (C) 2005-2006 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __OBEX_CLIENT_H
+#define __OBEX_CLIENT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+GQuark obex_error_quark(void);
+
+#define OBEX_ERROR obex_error_quark()
+
+enum {
+ OBEX_ERROR_NO_MEMORY,
+ OBEX_ERROR_BUSY,
+ OBEX_ERROR_INVALID_PARAMS,
+ OBEX_ERROR_ALREADY_CONNECTED,
+ OBEX_ERROR_NOT_CONNECTED,
+ OBEX_ERROR_LINK_FAILURE,
+ OBEX_ERROR_ABORTED,
+
+ /* Errors derived from OBEX response codes */
+ OBEX_ERROR_BAD_REQUEST,
+ OBEX_ERROR_UNAUTHORIZED,
+ OBEX_ERROR_PAYMENT_REQUIRED,
+ OBEX_ERROR_FORBIDDEN,
+ OBEX_ERROR_NOT_FOUND,
+ OBEX_ERROR_NOT_ALLOWED,
+ OBEX_ERROR_NOT_ACCEPTABLE,
+ OBEX_ERROR_PROXY_AUTH_REQUIRED,
+ OBEX_ERROR_REQUEST_TIME_OUT,
+ OBEX_ERROR_CONFLICT,
+ OBEX_ERROR_GONE,
+ OBEX_ERROR_LENGTH_REQUIRED,
+ OBEX_ERROR_PRECONDITION_FAILED,
+ OBEX_ERROR_ENTITY_TOO_LARGE,
+ OBEX_ERROR_URL_TOO_LARGE,
+ OBEX_ERROR_UNSUPPORTED_MEDIA_TYPE,
+ OBEX_ERROR_INTERNAL_SERVER_ERROR,
+ OBEX_ERROR_NOT_IMPLEMENTED,
+ OBEX_ERROR_BAD_GATEWAY,
+ OBEX_ERROR_SERVICE_UNAVAILABLE,
+ OBEX_ERROR_GATEWAY_TIMEOUT,
+ OBEX_ERROR_VERSION_NOT_SUPPORTED,
+ OBEX_ERROR_DATABASE_FULL,
+ OBEX_ERROR_DATABASE_LOCKED,
+
+ OBEX_ERROR_FAILED
+};
+
+#define OBEX_TYPE_CLIENT (obex_client_get_type())
+#define OBEX_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ OBEX_TYPE_CLIENT, ObexClient))
+#define OBEX_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
+ OBEX_TYPE_CLIENT, ObexClientClass))
+#define OBEX_IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
+ OBEX_TYPE_CLIENT))
+#define OBEX_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \
+ OBEX_TYPE_CLIENT))
+#define OBEX_GET_CLIENT_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
+ OBEX_TYPE_CLIENT, ObexClientClass))
+
+typedef struct _ObexClient ObexClient;
+typedef struct _ObexClientClass ObexClientClass;
+
+struct _ObexClient {
+ GObject parent;
+};
+
+struct _ObexClientClass {
+ GObjectClass parent_class;
+
+ void (*connected)(ObexClient *self);
+ void (*disconnect)(ObexClient *self);
+ void (*canceled)(ObexClient *self);
+ void (*progress)(ObexClient *self);
+ void (*idle)(ObexClient *self);
+};
+
+GType obex_client_get_type(void);
+
+ObexClient *obex_client_new(void);
+
+void obex_client_destroy(ObexClient *self);
+
+void obex_client_set_auto_connect(ObexClient *self, gboolean auto_connect);
+
+gboolean obex_client_get_auto_connect(ObexClient *self);
+
+typedef enum {
+ OBEX_CLIENT_COND_IN = 1 << 0,
+ OBEX_CLIENT_COND_OUT = 1 << 1,
+ OBEX_CLIENT_COND_DONE = 1 << 2,
+ OBEX_CLIENT_COND_ERR = 1 << 3,
+} ObexClientCondition;
+
+typedef void (*ObexClientFunc)(ObexClient *client,
+ ObexClientCondition condition, gpointer data);
+
+void obex_client_add_watch(ObexClient *self, ObexClientCondition condition,
+ ObexClientFunc func, gpointer data);
+
+void obex_client_add_watch_full(ObexClient *self,
+ ObexClientCondition condition, ObexClientFunc func,
+ gpointer data, GDestroyNotify notify);
+
+void obex_client_attach_fd(ObexClient *self, int fd);
+
+gboolean obex_client_connect(ObexClient *self, const guchar *target,
+ gsize size, GError **error);
+
+gboolean obex_client_disconnect(ObexClient *self, GError **error);
+
+gboolean obex_client_put_object(ObexClient *self, const gchar *type,
+ const gchar *name, gint size,
+ time_t mtime, GError **error);
+
+gboolean obex_client_get_object(ObexClient *self, const gchar *type,
+ const gchar *name, GError **error);
+
+gboolean obex_client_read(ObexClient *self, gchar *buf, gsize count,
+ gsize *bytes_read, GError **error);
+
+gboolean obex_client_write(ObexClient *self, const gchar *buf, gsize count,
+ gsize *bytes_written, GError **error);
+
+gboolean obex_client_flush(ObexClient *self, GError **error);
+
+gboolean obex_client_abort(ObexClient *self, GError **error);
+
+gboolean obex_client_close(ObexClient *self, GError **error);
+
+gboolean obex_client_get_error(ObexClient *self, GError **error);
+
+gboolean obex_client_mkdir(ObexClient *self, const gchar *path, GError **error);
+
+gboolean obex_client_chdir(ObexClient *self, const gchar *path, GError **error);
+
+gboolean obex_client_delete(ObexClient *self, const gchar *name, GError **error);
+
+G_END_DECLS
+
+#endif /* __OBEX_CLIENT_H */
diff -urN openobex-1.3/glib/obex-debug.h openobex/glib/obex-debug.h
--- openobex-1.3/glib/obex-debug.h 1970-01-01 01:00:00.000000000 +0100
+++ openobex/glib/obex-debug.h 2006-08-28 15:40:32.000000000 +0200
@@ -0,0 +1,27 @@
+/*
+ *
+ * OpenOBEX - Free implementation of the Object Exchange protocol
+ *
+ * Copyright (C) 2005-2006 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+
+#define debug(fmt, arg...) fprintf(stderr, "== %s: " fmt "\n" , \
+ __FUNCTION__ , ## arg)
diff -urN openobex-1.3/glib/obex-error.c openobex/glib/obex-error.c
--- openobex-1.3/glib/obex-error.c 1970-01-01 01:00:00.000000000 +0100
+++ openobex/glib/obex-error.c 2006-09-11 22:32:16.000000000 +0200
@@ -0,0 +1,222 @@
+/*
+ *
+ * OpenOBEX - Free implementation of the Object Exchange protocol
+ *
+ * Copyright (C) 2005-2006 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 <errno.h>
+
+#include "obex-debug.h"
+#include "obex-client.h"
+#include "obex-error.h"
+
+GQuark obex_error_quark(void)
+{
+ static GQuark q = 0;
+
+ if (q == 0)
+ q = g_quark_from_static_string("obex-error-quark");
+
+ return q;
+}
+
+void err2gerror(int err, GError **gerr)
+{
+ debug("%s", g_strerror(err));
+
+ if (!gerr)
+ return;
+
+ switch (err) {
+ case ENOMEM:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_NO_MEMORY,
+ "Out of memory");
+ break;
+
+ case EBUSY:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_BUSY,
+ "Busy performing another operation");
+ break;
+
+ case EINVAL:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_INVALID_PARAMS,
+ "Invalid parameters were given");
+ break;
+
+ case EISCONN:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_ALREADY_CONNECTED,
+ "Already connected");
+ break;
+
+ case ENOTCONN:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_NOT_CONNECTED,
+ "Not connected");
+ break;
+
+ case EINTR:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_ABORTED,
+ "The operation was aborted");
+ break;
+
+ default:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_FAILED,
+ "Failed");
+ break;
+ }
+}
+
+void rsp2gerror(int rsp, GError **gerr)
+{
+ if (!gerr)
+ return;
+
+ switch (rsp) {
+ case 0x40:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_BAD_REQUEST,
+ "Bad Request - server couldn't understand request");
+ break;
+
+ case 0x41:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_UNAUTHORIZED,
+ "Unauthorized");
+ break;
+
+ case 0x42:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_PAYMENT_REQUIRED,
+ "Payment required");
+ break;
+
+ case 0x43:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_FORBIDDEN,
+ "Forbidden - operation is understood but refused");
+ break;
+
+ case 0x44:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_NOT_FOUND,
+ "Not Found");
+ break;
+
+ case 0x45:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_NOT_ALLOWED,
+ "Method not allowed");
+ break;
+
+ case 0x46:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_NOT_ACCEPTABLE,
+ "Not Acceptable");
+ break;
+
+ case 0x47:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_PROXY_AUTH_REQUIRED,
+ "Proxy Authentication required");
+ break;
+
+ case 0x48:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_REQUEST_TIME_OUT,
+ "Request Time Out");
+ break;
+
+ case 0x49:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_CONFLICT,
+ "Conflict");
+ break;
+
+ case 0x4A:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_GONE,
+ "Gone");
+ break;
+
+ case 0x4B:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_LENGTH_REQUIRED,
+ "Length Required");
+ break;
+
+ case 0x4C:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_PRECONDITION_FAILED,
+ "Precondition failed");
+ break;
+
+ case 0x4D:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_ENTITY_TOO_LARGE,
+ "Requested entity too large");
+ break;
+
+ case 0x4E:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_URL_TOO_LARGE,
+ "Request URL too large");
+ break;
+
+ case 0x4F:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_UNSUPPORTED_MEDIA_TYPE,
+ "Unsupported media type");
+ break;
+
+ case 0x50:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_INTERNAL_SERVER_ERROR,
+ "Internal Server Error");
+ break;
+
+ case 0x51:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_NOT_IMPLEMENTED,
+ "Not Implemented");
+ break;
+
+ case 0x52:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_BAD_GATEWAY,
+ "Bad Gateway");
+ break;
+
+ case 0x53:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_SERVICE_UNAVAILABLE,
+ "Service Unavailable");
+ break;
+
+ case 0x54:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_GATEWAY_TIMEOUT,
+ "Gateway Timeout");
+ break;
+
+ case 0x55:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_VERSION_NOT_SUPPORTED,
+ "HTTP version not supported");
+ break;
+
+ case 0x60:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_DATABASE_FULL,
+ "Database Full");
+ break;
+
+ case 0x61:
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_DATABASE_LOCKED,
+ "Database Locked");
+ break;
+
+ default:
+ debug("Unmapped OBEX response: %d", rsp);
+ g_set_error(gerr, OBEX_ERROR, OBEX_ERROR_FAILED,
+ "Failed");
+ break;
+ }
+}
+
diff -urN openobex-1.3/glib/obex-error.h openobex/glib/obex-error.h
--- openobex-1.3/glib/obex-error.h 1970-01-01 01:00:00.000000000 +0100
+++ openobex/glib/obex-error.h 2006-09-11 22:32:16.000000000 +0200
@@ -0,0 +1,33 @@
+/*
+ *
+ * OpenOBEX - Free implementation of the Object Exchange protocol
+ *
+ * Copyright (C) 2005-2006 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __OBEX_ERROR_H
+#define __OBEX_ERROR_H
+
+#include <glib.h>
+
+void err2gerror(int err, GError **gerr);
+
+void rsp2gerror(int rsp, GError **gerr);
+
+#endif /* __OBEX_ERROR_H */
diff -urN openobex-1.3/glib/obex-lowlevel.c openobex/glib/obex-lowlevel.c
--- openobex-1.3/glib/obex-lowlevel.c 1970-01-01 01:00:00.000000000 +0100
+++ openobex/glib/obex-lowlevel.c 2006-09-13 15:25:37.000000000 +0200
@@ -0,0 +1,986 @@
+/*
+ *
+ * OpenOBEX - Free implementation of the Object Exchange protocol
+ *
+ * Copyright (C) 2005-2006 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 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 <stdio.h>
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+#include <time.h>
+#include <arpa/inet.h>
+
+#include <glib.h>
+
+#include "obex-debug.h"
+#include "obex-lowlevel.h"
+
+#define BUF_SIZE 32767
+
+#define CID_INVALID 0xFFFFFFFF
+
+#define OBEX_TIMEOUT 1
+
+enum {
+ OBEX_CONNECTED = 1, /* Equal to TCP_ESTABLISHED */
+ OBEX_OPEN,
+ OBEX_BOUND,
+ OBEX_LISTEN,
+ OBEX_CONNECT,
+ OBEX_CONNECT2,
+ OBEX_CONFIG,
+ OBEX_DISCONN,
+ OBEX_CLOSED
+};
+
+typedef struct obex_setpath_hdr {
+ uint8_t flags;
+ uint8_t constants;
+} __attribute__ ((packed)) obex_setpath_hdr_t;
+
+typedef struct obex_connect_hdr {
+ uint8_t version;
+ uint8_t flags;
+ uint16_t mtu;
+} __attribute__ ((packed)) obex_connect_hdr_t;
+
+typedef struct {
+ int event;
+} obex_ev_t;
+
+typedef struct {
+ unsigned long state;
+ uint32_t cid;
+
+ void *user_data;
+ obex_callback_t *callback;
+
+ obex_object_t *pending;
+
+ int obex_rsp; /* Response to last OBEX command */
+
+ /* Transfer related variables */
+ char buf[BUF_SIZE]; /* Data buffer for put and get requests */
+ int data_start; /* Offset of data in buffer */
+ int data_length; /* Length of actual data in buffer */
+ int counter; /* Total bytes transfered so far */
+ int target_size; /* Final length of object under transfer */
+ time_t modtime; /* Modification time of object under transfer */
+ int tx_max; /* Maximum size for sent chunks of data */
+ int close; /* If the user has called obex_close */
+ GSList *events; /* Events to signal when HandleInput returns */
+} obex_context_t;
+
+static void queue_event(obex_context_t *context, int e)
+{
+ obex_ev_t *event;
+
+ event = malloc(sizeof(obex_ev_t));
+ if (!event)
+ return;
+
+ memset(event, 0, sizeof(obex_ev_t));
+
+ event->event = e;
+
+ context->events = g_slist_append(context->events, event);
+}
+
+static int make_iso8601(time_t time, char *str, int len) {
+ struct tm tm;
+#if defined(HAVE_TIMEZONE) && defined(USE_LOCALTIME)
+ time_t tz_offset = 0;
+
+ tzset();
+
+ tz_offset = -timezone;
+ if (daylight > 0)
+ tz_offset += 3600;
+ time += tz_offset;
+#endif
+
+ if (gmtime_r(&time, &tm) == NULL)
+ return -1;
+
+ tm.tm_year += 1900;
+ tm.tm_mon++;
+
+ return snprintf(str, len,
+#ifdef USE_LOCALTIME
+ "%04u%02u%02uT%02u%02u%02u",
+#else
+ "%04u%02u%02uT%02u%02u%02uZ",
+#endif
+ tm.tm_year, tm.tm_mon, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+}
+
+time_t parse_iso8601(const char *str, int len)
+{
+ char *tstr, tz;
+ struct tm tm;
+ int nr;
+ time_t time, tz_offset = 0;
+
+ memset(&tm, 0, sizeof(struct tm));
+
+ /* According to spec the time doesn't have to be null terminated */
+ tstr = malloc(len + 1);
+ if (!tstr)
+ return -1;
+
+ strncpy(tstr, str, len);
+ tstr[len] = '\0';
+
+ nr = sscanf(tstr, "%04u%02u%02uT%02u%02u%02u%c",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
+ &tm.tm_hour, &tm.tm_min, &tm.tm_sec,
+ &tz);
+
+ free(tstr);
+
+ /* Fixup the tm values */
+ tm.tm_year -= 1900; /* Year since 1900 */
+ tm.tm_mon--; /* Months since January, values 0-11 */
+ tm.tm_isdst = -1; /* Daylight savings information not avail */
+
+ if (nr < 6) {
+ /* Invalid time format */
+ return -1;
+ }
+
+ time = mktime(&tm);
+
+#if defined(HAVE_TM_GMTOFF)
+ tz_offset = tm.tm_gmtoff;
+#elif defined(HAVE_TIMEZONE)
+ tz_offset = -timezone;
+ if (tm.tm_isdst > 0)
+ tz_offset += 3600;
+#endif
+
+ if (nr == 7) { /* Date/Time was in localtime (to remote device)
+ * already. Since we don't know anything about the
+ * timezone on that one we won't try to apply UTC offset
+ */
+ time += tz_offset;
+ }
+
+ return time;
+}
+
+static void get_target_size_and_time(obex_t *handle, obex_object_t *object,
+ obex_context_t *context) {
+ obex_headerdata_t hv;
+ uint8_t hi;
+ unsigned int hlen;
+
+ context->target_size = -1;
+ context->modtime = -1;
+
+ while (OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) {
+ switch (hi) {
+ case OBEX_HDR_LENGTH:
+ context->target_size = hv.bq4;
+ break;
+ case OBEX_HDR_TIME:
+ context->modtime = parse_iso8601((char *) hv.bs, hlen);
+ break;
+ default:
+ break;
+ }
+ }
+
+ OBEX_ObjectReParseHeaders(handle, object);
+}
+
+static void obex_progress(obex_t *handle, obex_object_t *object)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+
+ if (context->callback && context->callback->progress_ind)
+ context->callback->progress_ind(handle, context->user_data);
+}
+
+static void obex_connect_done(obex_t *handle,
+ obex_object_t *object, int response)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ obex_headerdata_t hd;
+ uint32_t hl;
+ uint8_t hi, *ptr;
+
+ if (response != OBEX_RSP_SUCCESS)
+ return;
+
+ context->state = OBEX_CONNECTED;
+
+ if (OBEX_ObjectGetNonHdrData(object, &ptr) == sizeof(obex_connect_hdr_t)) {
+ obex_connect_hdr_t *chdr = (obex_connect_hdr_t *) ptr;
+ uint16_t mtu = ntohs(chdr->mtu);
+ int new_size;
+
+ debug("Connect success. Version: 0x%02x. Flags: 0x%02x OBEX packet length: %d",
+ chdr->version, chdr->flags, mtu);
+
+ /* Leave space for headers */
+ new_size = mtu - 200;
+ if (new_size < context->tx_max) {
+ debug("Resizing stream chunks to %d", new_size);
+ context->tx_max = new_size;
+ }
+ }
+
+ while (OBEX_ObjectGetNextHeader(handle, object, &hi, &hd, &hl)) {
+ switch (hi) {
+ case OBEX_HDR_CONNECTION:
+ context->cid = hd.bq4;
+ break;
+ case OBEX_HDR_WHO:
+ break;
+ }
+ }
+
+ if (context->callback && context->callback->connect_cfm)
+ context->callback->connect_cfm(handle, context->user_data);
+}
+
+static void obex_disconnect_done(obex_t *handle,
+ obex_object_t *object, int response)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+
+ context->state = OBEX_CLOSED;
+}
+
+void obex_do_callback(obex_t *handle)
+{
+ GSList *l;
+ obex_context_t *context = OBEX_GetUserData(handle);
+
+ if (!context->events || ! context->callback || ! context->callback->command_ind)
+ return;
+
+ for (l = context->events; l != NULL; l = l->next) {
+ obex_ev_t *event = l->data;
+ context->callback->command_ind(handle, event->event, context->user_data);
+ free(event);
+ }
+
+ g_slist_free(context->events);
+ context->events = NULL;
+}
+
+static void obex_readstream(obex_t *handle, obex_object_t *object)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ const uint8_t *buf;
+ int actual, free_space;
+
+ if (context->counter == 0)
+ get_target_size_and_time(handle, object, context);
+
+ actual = OBEX_ObjectReadStream(handle, object, &buf);
+ if (actual <= 0) {
+ debug("Error or no data on OBEX stream");
+ return;
+ }
+
+ context->counter += actual;
+
+ debug("obex_readstream: got %d bytes (%d in total)", actual, context->counter);
+
+ free_space = sizeof(context->buf) - (context->data_start + context->data_length);
+ if (actual > free_space) {
+ /* This should never happen */
+ debug("Out of buffer space: actual=%d, free=%d", actual, free_space);
+ return;
+ }
+
+ memcpy(&context->buf[context->data_start], buf, actual);
+ context->data_length += actual;
+
+ debug("OBEX_SuspendRequest");
+ OBEX_SuspendRequest(handle, object);
+
+ queue_event(context, OBEX_EV_STREAMAVAIL);
+}
+
+static void obex_writestream(obex_t *handle, obex_object_t *object)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ obex_headerdata_t hv;
+
+ if (context->data_length > 0) {
+ int send_size = context->data_length > context->tx_max ?
+ context->tx_max : context->data_length;
+
+ hv.bs = (uint8_t *) &context->buf[context->data_start];
+ OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY,
+ hv, send_size, OBEX_FL_STREAM_DATA);
+
+ context->counter += send_size;
+ context->data_length -= send_size;
+
+ if (context->data_length == 0)
+ context->data_start = 0;
+ else
+ context->data_start += send_size;
+
+ if (!context->close && context->data_length == 0) {
+ debug("OBEX_SuspendRequest");
+ OBEX_SuspendRequest(handle, object);
+ queue_event(context, OBEX_EV_STREAMEMPTY);
+ }
+ }
+ else {
+ if (context->counter < context->target_size)
+ debug("Sending stream end but only %d/%d bytes sent",
+ context->counter, context->target_size);
+ hv.bs = NULL;
+ OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hv, 0,
+ OBEX_FL_STREAM_DATAEND);
+ }
+}
+
+static void obex_event(obex_t *handle, obex_object_t *object,
+ int mode, int event, int command, int response)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+
+ switch (event) {
+ case OBEX_EV_PROGRESS:
+ obex_progress(handle, object);
+ break;
+
+ case OBEX_EV_REQHINT:
+ OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_IMPLEMENTED, response);
+ break;
+
+ case OBEX_EV_REQ:
+ OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_IMPLEMENTED, response);
+ break;
+
+ case OBEX_EV_REQDONE:
+ debug("OBEX_EV_REQDONE");
+
+ context->obex_rsp = response;
+ queue_event(context, OBEX_EV_REQDONE);
+
+ if (context->pending && OBEX_Request(handle, context->pending) == 0) {
+ if (OBEX_ObjectGetCommand(handle, context->pending) == OBEX_CMD_PUT)
+ queue_event(context, OBEX_EV_STREAMEMPTY);
+ context->pending = NULL;
+ }
+
+ switch (command) {
+ case OBEX_CMD_CONNECT:
+ obex_connect_done(handle, object, response);
+ break;
+ case OBEX_CMD_DISCONNECT:
+ obex_disconnect_done(handle, object, response);
+ break;
+ case OBEX_CMD_PUT:
+ case OBEX_CMD_GET:
+ break;
+ case OBEX_CMD_SETPATH:
+ break;
+ case OBEX_CMD_SESSION:
+ break;
+ case OBEX_CMD_ABORT:
+ break;
+ }
+ break;
+
+ case OBEX_EV_LINKERR:
+ OBEX_TransportDisconnect(handle);
+ break;
+
+ case OBEX_EV_PARSEERR:
+ OBEX_TransportDisconnect(handle);
+ break;
+
+ case OBEX_EV_ACCEPTHINT:
+ break;
+
+ case OBEX_EV_ABORT:
+ queue_event(context, OBEX_EV_ABORT);
+ break;
+
+ case OBEX_EV_STREAMEMPTY:
+ debug("OBEX_EV_STREAMEMPTY");
+ obex_writestream(handle, object);
+ break;
+
+ case OBEX_EV_STREAMAVAIL:
+ debug("OBEX_EV_STREAMAVAIL");
+ obex_readstream(handle, object);
+ break;
+
+ case OBEX_EV_UNEXPECTED:
+ break;
+
+ case OBEX_EV_REQCHECK:
+ break;
+ }
+}
+
+obex_t *obex_open(int fd, obex_callback_t *callback, void *data)
+{
+ obex_t *handle;
+ obex_context_t *context;
+
+ context = malloc(sizeof(*context));
+ if (!context)
+ return NULL;
+
+ memset(context, 0, sizeof(*context));
+
+ context->state = OBEX_OPEN;
+ context->cid = CID_INVALID;
+
+ handle = OBEX_Init(OBEX_TRANS_FD, obex_event, 0);
+ if (!handle) {
+ free(context);
+ return NULL;
+ }
+
+ context->user_data = data;
+ context->callback = callback;
+ context->tx_max = sizeof(context->buf);
+
+ OBEX_SetUserData(handle, context);
+
+ OBEX_SetTransportMTU(handle, sizeof(context->buf), sizeof(context->buf));
+
+ if (FdOBEX_TransportSetup(handle, fd, fd, 0) < 0) {
+ OBEX_Cleanup(handle);
+ return NULL;
+ }
+
+ return handle;
+}
+
+void obex_close(obex_t *handle)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+
+ OBEX_SetUserData(handle, NULL);
+
+ if (context->pending)
+ OBEX_ObjectDelete(handle, context->pending);
+
+ free(context);
+
+ OBEX_Cleanup(handle);
+}
+
+void obex_poll(obex_t *handle)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ unsigned long state = context->state;
+
+ while (1) {
+ OBEX_HandleInput(handle, OBEX_TIMEOUT);
+ if (context->state != state)
+ break;
+ }
+
+ obex_do_callback(handle);
+}
+
+static int obex_send_or_queue(obex_t *handle, obex_object_t *object)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ int err;
+
+ err = OBEX_Request(handle, object);
+
+ if (err == -EBUSY && !context->pending) {
+ context->pending = object;
+ return 0;
+ }
+
+ return err;
+}
+
+int obex_connect(obex_t *handle, const unsigned char *target, size_t size)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ obex_object_t *object;
+ obex_headerdata_t hd;
+ int err, ret;
+
+ if (context->state != OBEX_OPEN && context->state != OBEX_CLOSED)
+ return -EISCONN;
+
+ object = OBEX_ObjectNew(handle, OBEX_CMD_CONNECT);
+ if (!object)
+ return -ENOMEM;
+
+ if (target) {
+ hd.bs = target;
+
+ err = OBEX_ObjectAddHeader(handle, object,
+ OBEX_HDR_TARGET, hd, size, OBEX_FL_FIT_ONE_PACKET);
+ if (err < 0) {
+ OBEX_ObjectDelete(handle, object);
+ return err;
+ }
+ }
+
+ context->state = OBEX_CONNECT;
+
+ ret = obex_send_or_queue(handle, object);
+ if (ret < 0)
+ OBEX_ObjectDelete(handle, object);
+
+ return ret;
+}
+
+int obex_disconnect(obex_t *handle)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ obex_object_t *object;
+ int ret;
+
+ if (context->state != OBEX_CONNECTED)
+ return -ENOTCONN;
+
+ object = OBEX_ObjectNew(handle, OBEX_CMD_DISCONNECT);
+ if (!object)
+ return -ENOMEM;
+
+ context->state = OBEX_DISCONN;
+
+ if (context->callback && context->callback->disconn_ind)
+ context->callback->disconn_ind(handle, context->user_data);
+
+ ret = obex_send_or_queue(handle, object);
+ if (ret < 0)
+ OBEX_ObjectDelete(handle, object);
+
+ return ret;
+}
+
+int obex_delete(obex_t *handle, const char *name)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ obex_object_t *object;
+ obex_headerdata_t hd;
+ int err;
+
+ if (context->state != OBEX_OPEN && context->state != OBEX_CONNECT
+ && context->state != OBEX_CONNECTED)
+ return -ENOTCONN;
+
+ object = OBEX_ObjectNew(handle, OBEX_CMD_PUT);
+ if (!object)
+ return -ENOMEM;
+
+ if (context->cid != CID_INVALID) {
+ hd.bq4 = context->cid;
+ OBEX_ObjectAddHeader(handle, object,
+ OBEX_HDR_CONNECTION, hd, 4, OBEX_FL_FIT_ONE_PACKET);
+ }
+
+ if (name) {
+ int len, ulen = (strlen(name) + 1) * 2;
+ uint8_t *unicode = malloc(ulen);
+
+ if (!unicode) {
+ OBEX_ObjectDelete(handle, object);
+ return -ENOMEM;
+ }
+
+ len = OBEX_CharToUnicode(unicode, (uint8_t *) name, ulen);
+ hd.bs = unicode;
+
+ err = OBEX_ObjectAddHeader(handle, object,
+ OBEX_HDR_NAME, hd, len, OBEX_FL_FIT_ONE_PACKET);
+ if (err < 0) {
+ OBEX_ObjectDelete(handle, object);
+ free(unicode);
+ return err;
+ }
+
+ free(unicode);
+ }
+
+ err = obex_send_or_queue(handle, object);
+ if (err < 0)
+ OBEX_ObjectDelete(handle, object);
+
+ return err;
+}
+
+int obex_put(obex_t *handle, const char *type, const char *name, int size, time_t mtime)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ obex_object_t *object;
+ obex_headerdata_t hd;
+ int err, cmd;
+
+ if (context->state != OBEX_OPEN && context->state != OBEX_CONNECT
+ && context->state != OBEX_CONNECTED)
+ return -ENOTCONN;
+
+ cmd = OBEX_ObjectGetCommand(handle, NULL);
+ if (cmd == OBEX_CMD_GET || cmd == OBEX_CMD_PUT)
+ return -EBUSY;
+
+ /* Initialize transfer variables */
+ context->data_start = 0;
+ context->data_length = 0;
+ context->counter = 0;
+ context->target_size = size;
+ context->modtime = mtime;
+ context->close = 0;
+
+ object = OBEX_ObjectNew(handle, OBEX_CMD_PUT);
+ if (!object)
+ return -ENOMEM;
+
+ if (context->cid != CID_INVALID) {
+ hd.bq4 = context->cid;
+ OBEX_ObjectAddHeader(handle, object,
+ OBEX_HDR_CONNECTION, hd, 4, OBEX_FL_FIT_ONE_PACKET);
+ }
+
+ if (type) {
+ int len = strlen(name) + 1;
+
+ hd.bs = (uint8_t *) type;
+
+ err = OBEX_ObjectAddHeader(handle, object,
+ OBEX_HDR_TYPE, hd, len, OBEX_FL_FIT_ONE_PACKET);
+ if (err < 0) {
+ OBEX_ObjectDelete(handle, object);
+ return err;
+ }
+ }
+
+ if (name) {
+ int len, ulen = (strlen(name) + 1) * 2;
+ uint8_t *unicode = malloc(ulen);
+
+ if (!unicode) {
+ OBEX_ObjectDelete(handle, object);
+ return -ENOMEM;
+ }
+
+ len = OBEX_CharToUnicode(unicode, (uint8_t *) name, ulen);
+ hd.bs = unicode;
+
+ err = OBEX_ObjectAddHeader(handle, object,
+ OBEX_HDR_NAME, hd, len, OBEX_FL_FIT_ONE_PACKET);
+ if (err < 0) {
+ OBEX_ObjectDelete(handle, object);
+ free(unicode);
+ return err;
+ }
+
+ free(unicode);
+ }
+
+ /* Add a time header if possible */
+ if (context->modtime >= 0) {
+ char tstr[17];
+ int len;
+
+ len = make_iso8601(context->modtime, tstr, sizeof(tstr));
+
+ if (len >= 0) {
+ debug("Adding time header: %s", tstr);
+ hd.bs = (uint8_t *) tstr;
+ OBEX_ObjectAddHeader(handle, object, OBEX_HDR_TIME, hd, len, 0);
+ }
+ }
+
+ /* Add a length header if possible */
+ if (context->target_size > 0) {
+ debug("Adding length header: %d", context->target_size);
+ hd.bq4 = (uint32_t) context->target_size;
+ OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hd, 4, 0);
+ }
+
+ hd.bs = NULL;
+ OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hd, 0, OBEX_FL_STREAM_START);
+
+ /* We need to suspend until the user has provided some data
+ * by calling obex_client_write */
+ debug("OBEX_SuspendRequest");
+ OBEX_SuspendRequest(handle, object);
+
+ err = obex_send_or_queue(handle, object);
+ if (err < 0)
+ OBEX_ObjectDelete(handle, object);
+
+ return err;
+}
+
+int obex_get(obex_t *handle, const char *type, const char *name)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ obex_object_t *object;
+ obex_headerdata_t hd;
+ int err, cmd;
+
+ if (context->state != OBEX_OPEN && context->state != OBEX_CONNECT
+ && context->state != OBEX_CONNECTED)
+ return -ENOTCONN;
+
+ cmd = OBEX_ObjectGetCommand(handle, NULL);
+ if (cmd == OBEX_CMD_GET || cmd == OBEX_CMD_PUT)
+ return -EBUSY;
+
+ /* Initialize transfer variables */
+ context->data_start = 0;
+ context->data_length = 0;
+ context->counter = 0;
+ context->target_size = -1;
+ context->modtime = -1;
+ context->close = 0;
+
+ object = OBEX_ObjectNew(handle, OBEX_CMD_GET);
+ if (!object)
+ return -ENOMEM;
+
+ if (context->cid != CID_INVALID) {
+ hd.bq4 = context->cid;
+ OBEX_ObjectAddHeader(handle, object,
+ OBEX_HDR_CONNECTION, hd, 4, OBEX_FL_FIT_ONE_PACKET);
+ }
+
+ if (type) {
+ int len = strlen(name) + 1;
+
+ hd.bs = (uint8_t *) type;
+
+ err = OBEX_ObjectAddHeader(handle, object,
+ OBEX_HDR_TYPE, hd, len, OBEX_FL_FIT_ONE_PACKET);
+ if (err < 0) {
+ OBEX_ObjectDelete(handle, object);
+ return err;
+ }
+ }
+
+ if (name) {
+ int len, ulen = (strlen(name) + 1) * 2;
+ uint8_t *unicode = malloc(ulen);
+
+ if (!unicode) {
+ OBEX_ObjectDelete(handle, object);
+ return -ENOMEM;
+ }
+
+ len = OBEX_CharToUnicode(unicode, (uint8_t *) name, ulen);
+ hd.bs = unicode;
+
+ err = OBEX_ObjectAddHeader(handle, object,
+ OBEX_HDR_NAME, hd, len, OBEX_FL_FIT_ONE_PACKET);
+ if (err < 0) {
+ OBEX_ObjectDelete(handle, object);
+ free(unicode);
+ return err;
+ }
+
+ free(unicode);
+ }
+
+ OBEX_ObjectReadStream(handle, object, NULL);
+
+ err = obex_send_or_queue(handle, object);
+ if (err < 0)
+ OBEX_ObjectDelete(handle, object);
+
+ return err;
+}
+
+int obex_read(obex_t *handle, char *buf, size_t count, size_t *bytes_read)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+
+ if (OBEX_ObjectGetCommand(handle, NULL) != OBEX_CMD_GET)
+ return -EINVAL;
+
+ if (context->data_length == 0)
+ return -EAGAIN;
+
+ *bytes_read = count < context->data_length ? count : context->data_length;
+
+ memcpy(buf, &context->buf[context->data_start], *bytes_read);
+
+ context->data_length -= *bytes_read;
+
+ if (context->data_length)
+ context->data_start += *bytes_read;
+ else {
+ context->data_start = 0;
+ debug("OBEX_ResumeRequest");
+ OBEX_ResumeRequest(handle);
+ }
+
+ return 0;
+}
+
+int obex_write(obex_t *handle, const char *buf, size_t count, size_t *bytes_written)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ int free_space;
+
+ if (OBEX_ObjectGetCommand(handle, NULL) != OBEX_CMD_PUT)
+ return -EINVAL;
+
+ free_space = sizeof(context->buf) - (context->data_start + context->data_length);
+
+ *bytes_written = count > free_space ? free_space : count;
+
+ memcpy(&context->buf[context->data_start + context->data_length], buf, *bytes_written);
+
+ context->data_length += *bytes_written;
+
+ if (context->data_length >= context->tx_max || *bytes_written == free_space) {
+ debug("OBEX_ResumeRequest");
+ OBEX_ResumeRequest(handle);
+ }
+
+ return 0;
+}
+
+int obex_flush(obex_t *handle)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+
+ if (OBEX_ObjectGetCommand(handle, NULL) != OBEX_CMD_PUT)
+ return -EINVAL;
+
+ if (context->data_length) {
+ debug("OBEX_ResumeRequest");
+ OBEX_ResumeRequest(handle);
+ }
+
+ return 0;
+}
+
+int obex_abort(obex_t *handle)
+{
+ int cmd;
+
+ cmd = OBEX_ObjectGetCommand(handle, NULL);
+ if (cmd != OBEX_CMD_PUT || cmd != OBEX_CMD_GET)
+ return -EINVAL;
+
+ return OBEX_CancelRequest(handle, 1);
+}
+
+int obex_close_transfer(obex_t *handle)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ int cmd;
+
+ cmd = OBEX_ObjectGetCommand(handle, NULL);
+ if (cmd != OBEX_CMD_PUT && cmd != OBEX_CMD_GET)
+ return -EINVAL;
+
+ context->close = 1;
+
+ debug("OBEX_ResumeRequest");
+ OBEX_ResumeRequest(handle);
+
+ return 0;
+}
+
+int obex_get_response(obex_t *handle)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ int rsp;
+
+ rsp = context->obex_rsp;
+ context->obex_rsp = OBEX_RSP_SUCCESS;
+
+ return rsp;
+}
+
+int obex_setpath(obex_t *handle, const char *path, int create)
+{
+ obex_context_t *context = OBEX_GetUserData(handle);
+ obex_object_t *object;
+ obex_headerdata_t hd;
+ obex_setpath_hdr_t sphdr;
+ int ret;
+
+ if (context->state != OBEX_CONNECTED)
+ return -ENOTCONN;
+
+ object = OBEX_ObjectNew(handle, OBEX_CMD_SETPATH);
+ if (!object)
+ return -ENOMEM;
+
+ if (context->cid != CID_INVALID) {
+ hd.bq4 = context->cid;
+ OBEX_ObjectAddHeader(handle, object, OBEX_HDR_CONNECTION, hd, 4, 0);
+ }
+
+ memset(&sphdr, 0, sizeof(obex_setpath_hdr_t));
+
+ if (strcmp(path, "..") == 0) {
+ /* Can't create parent dir */
+ if (create)
+ return -EINVAL;
+ sphdr.flags = 0x03;
+ } else {
+ int len, ulen = (strlen(path) + 1) * 2;
+ uint8_t *unicode = malloc(ulen);
+
+ if (!create)
+ sphdr.flags = 0x02;
+
+ if (!unicode) {
+ OBEX_ObjectDelete(handle, object);
+ return -ENOMEM;
+ }
+
+ len = OBEX_CharToUnicode(unicode, (uint8_t *) path, ulen);
+ hd.bs = unicode;
+
+ ret = OBEX_ObjectAddHeader(handle, object, OBEX_HDR_NAME, hd, len, 0);
+ if (ret < 0) {
+ OBEX_ObjectDelete(handle, object);
+ free(unicode);
+ return ret;
+ }
+
+ free(unicode);
+ }
+
+ OBEX_ObjectSetNonHdrData(object, (uint8_t *) &sphdr, 2);
+
+ ret = obex_send_or_queue(handle, object);
+ if (ret < 0)
+ OBEX_ObjectDelete(handle, object);
+
+ return ret;
+}
diff -urN openobex-1.3/glib/obex-lowlevel.h openobex/glib/obex-lowlevel.h
--- openobex-1.3/glib/obex-lowlevel.h 1970-01-01 01:00:00.000000000 +0100
+++ openobex/glib/obex-lowlevel.h 2006-09-13 15:25:37.000000000 +0200
@@ -0,0 +1,48 @@
+/*
+ *
+ * OpenOBEX - Free implementation of the Object Exchange protocol
+ *
+ * Copyright (C) 2005-2006 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <openobex/obex.h>
+
+typedef struct {
+ void (*connect_cfm)(obex_t *handle, void *data);
+ void (*disconn_ind)(obex_t *handle, void *data);
+ void (*progress_ind)(obex_t *handle, void *data);
+ void (*command_ind)(obex_t *handle, int event, void *data);
+} obex_callback_t;
+
+obex_t *obex_open(int fd, obex_callback_t *callback, void *data);
+void obex_close(obex_t *handle);
+void obex_poll(obex_t *handle);
+int obex_connect(obex_t *handle, const unsigned char *target, size_t size);
+int obex_disconnect(obex_t *handle);
+int obex_put(obex_t *handle, const char *type, const char *name, int size, time_t mtime);
+int obex_get(obex_t *handle, const char *type, const char *name);
+int obex_write(obex_t *handle, const char *buf, size_t count, size_t *bytes_written);
+int obex_read(obex_t *handle, char *buf, size_t count, size_t *bytes_read);
+int obex_abort(obex_t *handle);
+int obex_flush(obex_t *handle);
+int obex_close_transfer(obex_t *handle);
+int obex_get_response(obex_t *handle);
+void obex_do_callback(obex_t *handle);
+int obex_setpath(obex_t *handle, const char *path, int create);
+int obex_delete(obex_t *handle, const char *name);
diff -urN openobex-1.3/glib/obex-marshal.list openobex/glib/obex-marshal.list
--- openobex-1.3/glib/obex-marshal.list 1970-01-01 01:00:00.000000000 +0100
+++ openobex/glib/obex-marshal.list 2006-08-28 13:10:53.000000000 +0200
@@ -0,0 +1 @@
+VOID:VOID
diff -urN openobex-1.3/glib/test-client.c openobex/glib/test-client.c
--- openobex-1.3/glib/test-client.c 1970-01-01 01:00:00.000000000 +0100
+++ openobex/glib/test-client.c 2006-09-12 13:01:26.000000000 +0200
@@ -0,0 +1,211 @@
+/*
+ *
+ * OpenOBEX - Free implementation of the Object Exchange protocol
+ *
+ * Copyright (C) 2005-2006 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 <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <termios.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "obex-client.h"
+
+#define FTP_UUID (guchar *) \
+ "\xF9\xEC\x7B\xC4\x95\x3C\x11\xD2\x98\x4E\x52\x54\x00\xDC\x9E\x09"
+
+static GMainLoop *mainloop;
+
+static void sig_term(int sig)
+{
+ g_main_loop_quit(mainloop);
+}
+
+static int open_device(const char *device)
+{
+ struct termios ti;
+ int fd;
+
+ fd = open(device, O_RDWR | O_NOCTTY);
+ if (fd < 0)
+ return fd;
+
+ tcflush(fd, TCIOFLUSH);
+
+ cfmakeraw(&ti);
+ tcsetattr(fd, TCSANOW, &ti);
+
+ return fd;
+}
+
+static void transfer(ObexClient *client, ObexClientCondition cond, gpointer data)
+{
+ GError *gerr = NULL;
+ int *io = data;
+
+ if (cond & OBEX_CLIENT_COND_IN) {
+ gchar buf[1024];
+ gsize len;
+
+ printf("OBEX_CLIENT_COND_IN\n");
+
+ do {
+ obex_client_read(client, buf, sizeof(buf), &len, &gerr);
+
+ if (gerr != NULL) {
+ printf("obex_client_read failed: %s\n", gerr->message);
+ g_error_free(gerr);
+ gerr = NULL;
+ break;
+ }
+
+ printf("Data buffer with size %zd available\n", len);
+
+ if (len > 0 && *io >= 0)
+ write(*io, buf, len);
+
+ } while (len == sizeof(buf));
+ }
+
+ if (cond & OBEX_CLIENT_COND_OUT) {
+ char buf[10000];
+ ssize_t actual;
+
+ printf("OBEX_CLIENT_COND_OUT\n");
+
+ if (*io < 0) {
+ printf("No data to send!\n");
+ return;
+ }
+
+ actual = read(*io, buf, sizeof(buf));
+ if (actual == 0) {
+ obex_client_close(client, &gerr);
+ if (gerr != NULL) {
+ printf("obex_client_close failed: %s\n",
+ gerr->message);
+ g_error_free(gerr);
+ gerr = NULL;
+ }
+ close(*io);
+ *io = -1;
+ } else if (actual > 0) {
+ gsize written;
+
+ obex_client_write(client, buf, actual, &written, &gerr);
+
+ if (gerr != NULL) {
+ printf("writing data failed: %s\n", gerr->message);
+ g_error_free(gerr);
+ gerr = NULL;
+ } else if (written < actual)
+ printf("Only %zd/%zd bytes were accepted by obex_client_write!\n",
+ written, actual);
+ else
+ obex_client_flush(client, NULL);
+
+ }
+ else
+ fprintf(stderr, "read: %s\n", strerror(errno));
+ }
+
+ if (cond & OBEX_CLIENT_COND_DONE) {
+ obex_client_get_error(client, &gerr);
+ if (gerr != NULL) {
+ printf("Operation failed: %s\n", gerr->message);
+ g_error_free(gerr);
+ gerr = NULL;
+ }
+ else
+ printf("Operation completed with success\n");
+ }
+
+ if (cond & OBEX_CLIENT_COND_ERR)
+ printf("Error in transfer\n");
+}
+
+int main(int argc, char *argv[])
+{
+ ObexClient *client;
+ struct sigaction sa;
+ int fd, io = -1;
+
+ g_type_init();
+
+ fd = open_device("/dev/rfcomm42");
+ if (fd < 0) {
+ perror("Can't open device");
+ exit(EXIT_FAILURE);
+ }
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+
+ client = obex_client_new();
+
+ obex_client_add_watch(client, 0, transfer, &io);
+
+ obex_client_attach_fd(client, fd);
+
+ if (argc > 1) {
+ struct stat s;
+
+ if (stat(argv[1], &s) < 0) {
+ fprintf(stderr, "stat(%s): %s\n", argv[1], strerror(errno));
+ return 1;
+ }
+
+ io = open(argv[1], O_RDONLY);
+ if (io < 0) {
+ fprintf(stderr, "open(%s): %s\n", argv[1], strerror(errno));
+ return 1;
+ }
+
+ obex_client_put_object(client, NULL, argv[1], s.st_size, s.st_mtime, NULL);
+ }
+ else
+ obex_client_get_object(client, NULL, "telecom/devinfo.txt", NULL);
+
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = sig_term;
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+
+ g_main_loop_run(mainloop);
+
+ obex_client_destroy(client);
+
+ if (io >= 0)
+ close(io);
+
+ close(fd);
+
+ return 0;
+}
diff -urN openobex-1.3/glib/test-lowlevel.c openobex/glib/test-lowlevel.c
--- openobex-1.3/glib/test-lowlevel.c 1970-01-01 01:00:00.000000000 +0100
+++ openobex/glib/test-lowlevel.c 2006-08-28 14:22:56.000000000 +0200
@@ -0,0 +1,81 @@
+/*
+ *
+ * OpenOBEX - Free implementation of the Object Exchange protocol
+ *
+ * Copyright (C) 2005-2006 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 <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <termios.h>
+
+#include "obex-lowlevel.h"
+
+static int open_device(const char *device)
+{
+ struct termios ti;
+ int fd;
+
+ fd = open(device, O_RDWR | O_NOCTTY);
+ if (fd < 0)
+ return fd;
+
+ tcflush(fd, TCIOFLUSH);
+
+ cfmakeraw(&ti);
+ tcsetattr(fd, TCSANOW, &ti);
+
+ return fd;
+}
+
+int main(int argc, char *argv[])
+{
+ obex_t *handle;
+ int fd;
+
+ fd = open_device("/dev/rfcomm42");
+ if (fd < 0) {
+ perror("Can't open device");
+ exit(EXIT_FAILURE);
+ }
+
+ handle = obex_open(fd, NULL, NULL);
+
+ obex_connect(handle, NULL, 0);
+ obex_poll(handle);
+
+ obex_get(handle, NULL, "telecom/devinfo.txt");
+ obex_poll(handle);
+
+ obex_disconnect(handle);
+ obex_poll(handle);
+
+ obex_close(handle);
+
+ close(fd);
+
+ return 0;
+}
diff -urN openobex-1.3/include/obex_const.h openobex/include/obex_const.h
--- openobex-1.3/include/obex_const.h 2006-03-08 13:18:55.000000000 +0100
+++ openobex/include/obex_const.h 2006-12-31 15:58:55.000000000 +0100
@@ -65,7 +65,7 @@
/* Active data interface description, typically empty */
char *data_interface_active;
/* Internal information for the transport layer in the library */
- struct obex_usb_intf_transport_t *interface;
+ struct obex_usb_intf_transport_t *intf;
} obex_usb_intf_t;
/* Generic OBEX interface information */
@@ -75,8 +75,8 @@
//obex_bluetooth_intf_t bt; // to be added
} obex_interface_t;
-#define OBEX_CLIENT 0
-#define OBEX_SERVER 1
+#define OBEX_MODE_CLIENT 0
+#define OBEX_MODE_SERVER 1
/* Possible events */
#define OBEX_EV_PROGRESS 0 /* Progress has been made */
@@ -114,31 +114,56 @@
#define OBEX_TRANS_USB 6
/* Standard headers */
-#define OBEX_HDR_EMPTY 0x00 /* Empty header (buggy OBEX servers) */
-#define OBEX_HDR_COUNT 0xc0 /* Number of objects (used by connect) */
-#define OBEX_HDR_NAME 0x01 /* Name of the object */
-#define OBEX_HDR_TYPE 0x42 /* Type of the object */
-#define OBEX_HDR_LENGTH 0xc3 /* Total lenght of object */
-#define OBEX_HDR_TIME 0x44 /* Last modification time of (ISO8601) */
-#define OBEX_HDR_TIME2 0xC4 /* Deprecated use HDR_TIME instead */
-#define OBEX_HDR_DESCRIPTION 0x05 /* Description of object */
-#define OBEX_HDR_TARGET 0x46 /* Identifies the target for the object */
-#define OBEX_HDR_HTTP 0x47 /* An HTTP 1.x header */
-#define OBEX_HDR_BODY 0x48 /* Data part of the object */
-#define OBEX_HDR_BODY_END 0x49 /* Last data part of the object */
-#define OBEX_HDR_WHO 0x4a /* Identifies the sender of the object */
-#define OBEX_HDR_CONNECTION 0xcb /* Connection identifier */
-#define OBEX_HDR_APPARAM 0x4c /* Application parameters */
-#define OBEX_HDR_AUTHCHAL 0x4d /* Authentication challenge */
-#define OBEX_HDR_AUTHRESP 0x4e /* Authentication response */
-#define OBEX_HDR_CREATOR 0xcf /* indicates the creator of an object */
-#define OBEX_HDR_WANUUID 0x50 /* uniquely identifies the network client
- (OBEX server) */
-#define OBEX_HDR_OBJECTCLASS 0x51 /* OBEX Object class of object */
-#define OBEX_HDR_SESSIONPARAM 0x52 /* Parameters used in session
- commands/responses */
-#define OBEX_HDR_SESSIONSEQ 0x93 /* Sequence number used in each OBEX
- packet for reliability */
+#define OBEX_HDR_TYPE_UNICODE (0 << 6) /* zero terminated unicode string (network byte order) */
+#define OBEX_HDR_TYPE_BYTES (1 << 6) /* byte array */
+#define OBEX_HDR_TYPE_UINT8 (2 << 6) /* 8bit unsigned integer */
+#define OBEX_HDR_TYPE_UINT32 (3 << 6) /* 32bit unsigned integer */
+#define OBEX_HDR_TYPE_MASK 0xc0
+
+#define OBEX_HDR_ID_COUNT 0x00 /* Number of objects (used by connect) */
+#define OBEX_HDR_ID_NAME 0x01 /* Name of the object */
+#define OBEX_HDR_ID_TYPE 0x02 /* Type of the object */
+#define OBEX_HDR_ID_LENGTH 0x03 /* Total lenght of object */
+#define OBEX_HDR_ID_TIME 0x04 /* Last modification time of (ISO8601) */
+#define OBEX_HDR_ID_DESCRIPTION 0x05 /* Description of object */
+#define OBEX_HDR_ID_TARGET 0x06 /* Identifies the target for the object */
+#define OBEX_HDR_ID_HTTP 0x07 /* An HTTP 1.x header */
+#define OBEX_HDR_ID_BODY 0x08 /* Data part of the object */
+#define OBEX_HDR_ID_BODY_END 0x09 /* Last data part of the object */
+#define OBEX_HDR_ID_WHO 0x0a /* Identifies the sender of the object */
+#define OBEX_HDR_ID_CONNECTION 0x0b /* Connection identifier */
+#define OBEX_HDR_ID_APPARAM 0x0c /* Application parameters */
+#define OBEX_HDR_ID_AUTHCHAL 0x0d /* Authentication challenge */
+#define OBEX_HDR_ID_AUTHRESP 0x0e /* Authentication response */
+#define OBEX_HDR_ID_CREATOR 0x0f /* indicates the creator of an object */
+#define OBEX_HDR_ID_WANUUID 0x10 /* uniquely identifies the network client (OBEX server) */
+#define OBEX_HDR_ID_OBJECTCLASS 0x11 /* OBEX Object class of object */
+#define OBEX_HDR_ID_SESSIONPARAM 0x12 /* Parameters used in session commands/responses */
+#define OBEX_HDR_ID_SESSIONSEQ 0x13 /* Sequence number used in each OBEX packet for reliability */
+#define OBEX_HDR_ID_MASK 0x3f
+
+#define OBEX_HDR_EMPTY 0x00 /* Empty header (buggy OBEX servers) */
+#define OBEX_HDR_COUNT (OBEX_HDR_ID_COUNT | OBEX_HDR_TYPE_UINT32 )
+#define OBEX_HDR_NAME (OBEX_HDR_ID_NAME | OBEX_HDR_TYPE_UNICODE)
+#define OBEX_HDR_TYPE (OBEX_HDR_ID_TYPE | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_LENGTH (OBEX_HDR_ID_LENGTH | OBEX_HDR_TYPE_UINT32 )
+#define OBEX_HDR_TIME (OBEX_HDR_ID_TIME | OBEX_HDR_TYPE_BYTES ) /* Format: ISO 8601 */
+#define OBEX_HDR_TIME2 (OBEX_HDR_ID_TIME | OBEX_HDR_TYPE_UINT32 ) /* Deprecated use HDR_TIME instead */
+#define OBEX_HDR_DESCRIPTION (OBEX_HDR_ID_DESCRIPTION | OBEX_HDR_TYPE_UNICODE)
+#define OBEX_HDR_TARGET (OBEX_HDR_ID_TARGET | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_HTTP (OBEX_HDR_ID_HTTP | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_BODY (OBEX_HDR_ID_BODY | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_BODY_END (OBEX_HDR_ID_BODY_END | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_WHO (OBEX_HDR_ID_WHO | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_CONNECTION (OBEX_HDR_ID_CONNECTION | OBEX_HDR_TYPE_UINT32 )
+#define OBEX_HDR_APPARAM (OBEX_HDR_ID_APPARAM | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_AUTHCHAL (OBEX_HDR_ID_AUTHCHAL | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_AUTHRESP (OBEX_HDR_ID_AUTHRESP | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_CREATOR (OBEX_HDR_ID_CREATOR | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_WANUUID (OBEX_HDR_ID_WANUUID | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_OBJECTCLASS (OBEX_HDR_ID_OBJECTCLASS | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_SESSIONPARAM (OBEX_HDR_ID_SESSIONPARAM | OBEX_HDR_TYPE_BYTES )
+#define OBEX_HDR_SESSIONSEQ (OBEX_HDR_ID_SESSIONSEQ | OBEX_HDR_TYPE_UINT8 )
/* Commands */
#define OBEX_CMD_CONNECT 0x00
diff -urN openobex-1.3/include/obex.h openobex/include/obex.h
--- openobex-1.3/include/obex.h 2006-01-04 00:06:58.000000000 +0100
+++ openobex/include/obex.h 2007-01-25 09:44:43.000000000 +0100
@@ -34,7 +34,7 @@
#include <inttypes.h>
#ifdef _WIN32
-#include <winsock.h>
+#include <winsock2.h>
#else
#include <sys/socket.h>
#endif
@@ -100,6 +100,7 @@
int OBEX_ObjectSetNonHdrData(obex_object_t *object, const uint8_t *buffer, unsigned int len);
int OBEX_ObjectSetHdrOffset(obex_object_t *object, unsigned int offset);
int OBEX_ObjectReadStream(obex_t *self, obex_object_t *object, const uint8_t **buf);
+int OBEX_ObjectGetCommand(obex_t *self, obex_object_t *object);
int OBEX_UnicodeToChar(uint8_t *c, const uint8_t *uc, int size);
int OBEX_CharToUnicode(uint8_t *uc, const uint8_t *c, int size);
@@ -115,7 +116,13 @@
char* OBEX_GetResponseMessage(obex_t *self, int rsp);
/*
- * InOBEX API (TCP/IP)
+ * TcpOBEX API (IPv4/IPv6)
+ */
+ int TcpOBEX_ServerRegister(obex_t *self, struct sockaddr *addr, int addrlen);
+ int TcpOBEX_TransportConnect(obex_t *self, struct sockaddr *addr, int addrlen);
+
+/*
+ * InOBEX API (deprecated)
*/
int InOBEX_ServerRegister(obex_t *self);
int InOBEX_TransportConnect(obex_t *self, struct sockaddr *saddr, int addrlen);
@@ -140,8 +147,8 @@
/*
* OBEX interface discovery API
*/
- int OBEX_FindInterfaces(obex_t *self, obex_interface_t **interfaces);
- int OBEX_InterfaceConnect(obex_t *self, obex_interface_t *interface);
+ int OBEX_FindInterfaces(obex_t *self, obex_interface_t **intf);
+ int OBEX_InterfaceConnect(obex_t *self, obex_interface_t *intf);
void OBEX_FreeInterfaces(obex_t *self);
#ifdef __cplusplus
diff -urN openobex-1.3/ircp/ircp_client.c openobex/ircp/ircp_client.c
--- openobex-1.3/ircp/ircp_client.c 2006-01-18 14:02:14.000000000 +0100
+++ openobex/ircp/ircp_client.c 2006-08-28 16:23:53.000000000 +0200
@@ -365,7 +365,7 @@
{
struct stat statbuf;
char *origdir;
- int ret;
+ int err, ret;
/* Remember cwd */
origdir = getcwd(NULL, 0);
@@ -381,7 +381,7 @@
char *newrealdir = NULL;
char *dirname;
- chdir(name);
+ err = chdir(name);
name = ".";
/* Get real name of new wd, extract last part of and do setpath to it */
@@ -395,7 +395,7 @@
ret = visit_all_files(name, ircp_visit, cli);
- chdir(origdir);
+ err = chdir(origdir);
free(origdir);
return ret;
diff -urN openobex-1.3/ircp/ircp_server.c openobex/ircp/ircp_server.c
--- openobex-1.3/ircp/ircp_server.c 2006-01-18 14:02:14.000000000 +0100
+++ openobex/ircp/ircp_server.c 2006-08-28 16:23:53.000000000 +0200
@@ -249,7 +249,7 @@
int ircp_srv_receive(ircp_server_t *srv, obex_object_t *object, int finished)
{
const uint8_t *body = NULL;
- int body_len = 0;
+ int len, body_len = 0;
if(srv->fd < 0 && finished == FALSE) {
/* Not receiving a file */
@@ -278,7 +278,7 @@
}
else {
if(srv->fd > 0)
- write(srv->fd, body, body_len);
+ len = write(srv->fd, body, body_len);
}
return 1;
}
@@ -331,7 +331,7 @@
//
int ircp_srv_recv(ircp_server_t *srv, char *inbox)
{
- int ret;
+ int err, ret;
if(ircp_checkdir("", inbox, CD_ALLOWABS) < 0) {
srv->infocb(IRCP_EV_ERRMSG, "Specified desination directory does not exist.");
@@ -351,7 +351,7 @@
ret = ircp_srv_sync_wait(srv);
/* Go back to inbox */
- chdir(inbox);
+ err = chdir(inbox);
return ret;
}
diff -urN openobex-1.3/ircp/Makefile.am openobex/ircp/Makefile.am
--- openobex-1.3/ircp/Makefile.am 2006-01-03 19:36:15.000000000 +0100
+++ openobex/ircp/Makefile.am 2006-08-02 15:26:06.000000000 +0200
@@ -11,7 +11,7 @@
bin_PROGRAMS = ircp
-LDADD = $(top_builddir)/lib/libopenobex.la libircp.a
+LDADD = libircp.a $(top_builddir)/lib/libopenobex.la
INCLUDES = -I$(top_builddir)/include
endif
diff -urN openobex-1.3/lib/btobex.c openobex/lib/btobex.c
--- openobex-1.3/lib/btobex.c 2006-01-03 19:36:15.000000000 +0100
+++ openobex/lib/btobex.c 2006-12-31 16:09:27.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Marcel Holtmann <marcel@holtmann.org>
* Created at: Fri Aug 23 14:28:13 2002
- * CVS ID: $Id: btobex.c,v 1.8 2006/01/03 18:36:15 holtmann Exp $
+ * CVS ID: $Id: btobex.c 293 2006-12-31 15:09:27Z holtmann $
*
* Copyright (c) 2002 Marcel Holtmann, All Rights Reserved.
*
@@ -34,10 +34,10 @@
#ifdef HAVE_BLUETOOTH
#ifdef _WIN32
-#include <winsock.h>
+#include <winsock2.h>
#else /* _WIN32 */
-/* Linux case */
+/* Linux/FreeBSD/NetBSD case */
#include <string.h>
#include <unistd.h>
@@ -46,8 +46,25 @@
#include <netinet/in.h>
#include <sys/socket.h>
+#ifdef HAVE_BLUETOOTH_LINUX
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
+#endif
+#ifdef HAVE_BLUETOOTH_FREEBSD
+#include <bluetooth.h>
+#define sockaddr_rc sockaddr_rfcomm
+#define rc_family rfcomm_family
+#define rc_bdaddr rfcomm_bdaddr
+#define rc_channel rfcomm_channel
+#endif
+#ifdef HAVE_BLUETOOTH_NETBSD
+#define rc_family bt_family
+#define rc_bdaddr bt_bdaddr
+#define rc_channel bt_channel
+#define sockaddr_rc sockaddr_bt
+#include <bluetooth.h>
+#include <netbt/rfcomm.h>
+#endif
#endif /* _WIN32 */
diff -urN openobex-1.3/lib/btobex.h openobex/lib/btobex.h
--- openobex-1.3/lib/btobex.h 2002-11-01 13:10:59.000000000 +0100
+++ openobex/lib/btobex.h 2002-11-01 13:10:59.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Marcel Holtmann <marcel@holtmann.org>
* Created at: Fri Aug 23 14:32:31 2002
- * CVS ID: $Id: btobex.h,v 1.3 2002/11/01 12:10:59 holtmann Exp $
+ * CVS ID: $Id: btobex.h 121 2002-11-01 12:10:59Z holtmann $
*
* Copyright (c) 2002 Marcel Holtmann, All Rights Reserved.
*
diff -urN openobex-1.3/lib/databuffer.c openobex/lib/databuffer.c
--- openobex-1.3/lib/databuffer.c 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/databuffer.c 2007-01-24 19:45:50.000000000 +0100
@@ -33,6 +33,8 @@
#include <stdio.h>
#include <string.h>
+#include "obex_main.h"
+
slist_t *slist_append(slist_t *list, void *element)
{
slist_t *node, *p;
@@ -286,22 +288,14 @@
n = 0;
for (i = 0; i < p->data_size; ++i) {
-#ifndef OBEX_SYSLOG
- if (n == 0)
- fprintf(stderr, "%s: ", label);
- fprintf(stderr, "%02X ", p->data[i]);
- if (n >= 25 || i == p->data_size - 1) {
- fprintf(stderr, "\n");
-#else
if (n == 0)
- syslog(LOG_DEBUG, "OpenObex: %s: ", label);
- syslog(LOG_DEBUG, "%02X ", p->data[i]);
+ log_debug("%s%s:", log_debug_prefix, label);
+ log_debug(" %02X", p->data[i]);
if (n >= 25 || i == p->data_size - 1) {
- syslog(LOG_DEBUG, "\n");
-#endif
- n = -1;
- }
- n++;
+ log_debug("\n");
+ n = 0;
+ } else
+ n++;
}
}
diff -urN openobex-1.3/lib/inobex.c openobex/lib/inobex.c
--- openobex-1.3/lib/inobex.c 2006-02-12 10:51:14.000000000 +0100
+++ openobex/lib/inobex.c 2007-01-25 01:23:37.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sat Apr 17 16:50:35 1999
- * CVS ID: $Id: inobex.c,v 1.16 2006/02/12 09:51:14 holtmann Exp $
+ * CVS ID: $Id: inobex.c 297 2007-01-25 00:23:37Z holtmann $
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
@@ -35,19 +35,51 @@
#include <string.h>
#ifdef _WIN32
-#include <winsock.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <sys/socket.h>
+#include <arpa/inet.h>
#endif /*_WIN32*/
#include "obex_main.h"
#define OBEX_PORT 650
+static void map_ip4to6(struct sockaddr_in *in, struct sockaddr_in6 *out)
+{
+ out->sin6_family = AF_INET6;
+ if (in->sin_port == 0)
+ out->sin6_port = htons(OBEX_PORT);
+ else
+ out->sin6_port = in->sin_port;
+ out->sin6_flowinfo = 0;
+
+ /* default, matches IN6ADDR_ANY */
+ memset(out->sin6_addr.s6_addr, 0, sizeof(out->sin6_addr.s6_addr));
+ switch (in->sin_addr.s_addr) {
+ case INADDR_ANY:
+ /* does not work, so use IN6ADDR_ANY
+ * which includes INADDR_ANY
+ */
+ break;
+ default:
+ /* map the IPv4 address to [::FFFF:<ipv4>]
+ * see RFC2373 and RFC2553 for details
+ */
+ out->sin6_addr.s6_addr16[10/2] = 0xFFFF;
+ out->sin6_addr.s6_addr[12] = (in->sin_addr.s_addr >> 24) & 0xFF;
+ out->sin6_addr.s6_addr[13] = (in->sin_addr.s_addr >> 16) & 0xFF;
+ out->sin6_addr.s6_addr[14] = (in->sin_addr.s_addr >> 8) & 0xFF;
+ out->sin6_addr.s6_addr[15] = (in->sin_addr.s_addr >> 0) & 0xFF;
+ break;
+ }
+}
+
/*
* Function inobex_prepare_connect (self, service)
*
@@ -56,10 +88,30 @@
*/
void inobex_prepare_connect(obex_t *self, struct sockaddr *saddr, int addrlen)
{
- memcpy(&self->trans.peer, saddr, addrlen);
- /* Override to be safe... */
- self->trans.peer.inet.sin_family = AF_INET;
- self->trans.peer.inet.sin_port = htons(OBEX_PORT);
+ struct sockaddr_in6 addr = {
+ .sin6_family = AF_INET6,
+ .sin6_port = htons(OBEX_PORT),
+#ifdef _WIN32
+ .sin6_addr.s6_addr = IN6ADDR_LOOPBACK_INIT,
+#else
+ .sin6_addr = IN6ADDR_LOOPBACK_INIT,
+#endif
+ .sin6_flowinfo = 0
+ };
+ if (saddr == NULL)
+ saddr = (struct sockaddr*)(&addr);
+ else
+ switch (saddr->sa_family){
+ case AF_INET6:
+ break;
+ case AF_INET:
+ map_ip4to6((struct sockaddr_in*)saddr,&addr);
+ /* no break */
+ default:
+ saddr = (struct sockaddr*)(&addr);
+ break;
+ }
+ memcpy(&self->trans.peer.inet6, saddr, sizeof(self->trans.self.inet6));
}
/*
@@ -68,12 +120,33 @@
* Prepare for INET-listen
*
*/
-void inobex_prepare_listen(obex_t *self)
+void inobex_prepare_listen(obex_t *self, struct sockaddr *saddr, int addrlen)
{
+ struct sockaddr_in6 addr = {
+ .sin6_family = AF_INET6,
+ .sin6_port = htons(OBEX_PORT),
+#ifdef _WIN32
+ .sin6_addr.s6_addr = IN6ADDR_ANY_INIT,
+#else
+ .sin6_addr = IN6ADDR_ANY_INIT,
+#endif
+ .sin6_flowinfo = 0
+ };
/* Bind local service */
- self->trans.self.inet.sin_family = AF_INET;
- self->trans.self.inet.sin_port = htons(OBEX_PORT);
- self->trans.self.inet.sin_addr.s_addr = INADDR_ANY;
+ if (saddr == NULL)
+ saddr = (struct sockaddr *) &addr;
+ else
+ switch (saddr->sa_family) {
+ case AF_INET6:
+ break;
+ case AF_INET:
+ map_ip4to6((struct sockaddr_in *) saddr, &addr);
+ /* no break */
+ default:
+ saddr = (struct sockaddr *) &addr;
+ break;
+ }
+ memcpy(&self->trans.self.inet6, saddr, sizeof(self->trans.self.inet6));
}
/*
@@ -86,7 +159,7 @@
{
DEBUG(4, "\n");
- self->serverfd = obex_create_socket(self, AF_INET);
+ self->serverfd = obex_create_socket(self, AF_INET6);
if(self->serverfd < 0) {
DEBUG(0, "Cannot create server-socket\n");
return -1;
@@ -94,9 +167,8 @@
//printf("TCP/IP listen %d %X\n", self->trans.self.inet.sin_port,
// self->trans.self.inet.sin_addr.s_addr);
- if (bind(self->serverfd, (struct sockaddr*) &self->trans.self.inet,
- sizeof(struct sockaddr_in)))
- {
+ if (bind(self->serverfd, (struct sockaddr *) &self->trans.self.inet6,
+ sizeof(struct sockaddr_in6))) {
DEBUG(0, "bind() Failed\n");
return -1;
}
@@ -120,10 +192,11 @@
*/
int inobex_accept(obex_t *self)
{
- socklen_t addrlen = sizeof(struct sockaddr_in);
+ socklen_t addrlen = sizeof(struct sockaddr_in6);
- self->fd = accept(self->serverfd, (struct sockaddr *)
- &self->trans.peer.inet, &addrlen);
+ self->fd = accept(self->serverfd,
+ (struct sockaddr *) &self->trans.peer.inet6,
+ &addrlen);
if(self->fd < 0)
return -1;
@@ -142,26 +215,30 @@
*/
int inobex_connect_request(obex_t *self)
{
- unsigned char *addr;
+ char addr[INET6_ADDRSTRLEN];
int ret;
- self->fd = obex_create_socket(self, AF_INET);
+ self->fd = obex_create_socket(self, AF_INET6);
if(self->fd < 0)
return -1;
/* Set these just in case */
- self->trans.peer.inet.sin_family = AF_INET;
- if (self->trans.peer.inet.sin_port == 0)
- self->trans.peer.inet.sin_port = htons(OBEX_PORT);
-
- addr = (unsigned char *) &self->trans.peer.inet.sin_addr.s_addr;
-
- DEBUG(2, "peer addr = %d.%d.%d.%d\n",
- addr[0], addr[1], addr[2], addr[3]);
+ if (self->trans.peer.inet6.sin6_port == 0)
+ self->trans.peer.inet6.sin6_port = htons(OBEX_PORT);
+#ifndef _WIN32
+ if (!inet_ntop(AF_INET6,&self->trans.peer.inet6.sin6_addr,
+ addr,sizeof(addr))) {
+ DEBUG(4, "Adress problem\n");
+ obex_delete_socket(self, self->fd);
+ self->fd = -1;
+ return -1;
+ }
+ DEBUG(2, "peer addr = [%s]:%u\n",addr,ntohs(self->trans.peer.inet6.sin6_port));
+#endif
- ret = connect(self->fd, (struct sockaddr*) &self->trans.peer.inet,
- sizeof(struct sockaddr_in));
+ ret = connect(self->fd, (struct sockaddr *) &self->trans.peer.inet6,
+ sizeof(struct sockaddr_in6));
if (ret < 0) {
DEBUG(4, "Connect failed\n");
obex_delete_socket(self, self->fd);
diff -urN openobex-1.3/lib/inobex.h openobex/lib/inobex.h
--- openobex-1.3/lib/inobex.h 2002-10-28 22:51:18.000000000 +0100
+++ openobex/lib/inobex.h 2007-01-25 01:23:37.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Apr 26 13:55:27 1999
- * CVS ID: $Id: inobex.h,v 1.7 2002/10/28 21:51:18 holtmann Exp $
+ * CVS ID: $Id: inobex.h 297 2007-01-25 00:23:37Z holtmann $
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
@@ -31,7 +31,7 @@
#define INOBEX_H
void inobex_prepare_connect(obex_t *self, struct sockaddr *saddr, int addrlen);
-void inobex_prepare_listen(obex_t *self);
+void inobex_prepare_listen(obex_t *self, struct sockaddr *saddr, int addrlen);
int inobex_listen(obex_t *self);
int inobex_accept(obex_t *self);
int inobex_connect_request(obex_t *self);
diff -urN openobex-1.3/lib/irobex.c openobex/lib/irobex.c
--- openobex-1.3/lib/irobex.c 2006-01-03 19:36:15.000000000 +0100
+++ openobex/lib/irobex.c 2006-12-31 16:09:27.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Fri Apr 23 14:28:13 1999
- * CVS ID: $Id: irobex.c,v 1.18 2006/01/03 18:36:15 holtmann Exp $
+ * CVS ID: $Id: irobex.c 293 2006-12-31 15:09:27Z holtmann $
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000 Pontus Fuchs, All Rights Reserved.
@@ -35,7 +35,7 @@
#ifdef HAVE_IRDA
#ifdef _WIN32
-#include <winsock.h>
+#include <winsock2.h>
#include <irda_wrap.h>
diff -urN openobex-1.3/lib/irobex.h openobex/lib/irobex.h
--- openobex-1.3/lib/irobex.h 2002-10-28 22:51:18.000000000 +0100
+++ openobex/lib/irobex.h 2002-10-28 22:51:18.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Fri Apr 23 14:32:31 1999
- * CVS ID: $Id: irobex.h,v 1.8 2002/10/28 21:51:18 holtmann Exp $
+ * CVS ID: $Id: irobex.h 107 2002-10-28 21:51:18Z holtmann $
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
diff -urN openobex-1.3/lib/Makefile.am openobex/lib/Makefile.am
--- openobex-1.3/lib/Makefile.am 2006-06-14 11:20:50.000000000 +0200
+++ openobex/lib/Makefile.am 2007-01-24 19:44:25.000000000 +0100
@@ -18,10 +18,11 @@
usbobex.c usbobex.h
libopenobex_la_LDFLAGS = \
+ -no-undefined \
-version-info 4:0:3 \
-export-symbols $(top_srcdir)/lib/obex.sym
-libopenobex_la_LIBADD = @USB_LIBS@
+libopenobex_la_LIBADD = @USB_LIBS@ @EXTRA_LIBS@
INCLUDES = -I$(top_builddir)/include
diff -urN openobex-1.3/lib/obex.c openobex/lib/obex.c
--- openobex-1.3/lib/obex.c 2006-05-25 20:09:41.000000000 +0200
+++ openobex/lib/obex.c 2007-01-25 09:44:43.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Stable.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sat Apr 17 16:50:25 1999
- * CVS ID: $Id: obex.c,v 1.47 2006/05/25 18:09:41 zany Exp $
+ * CVS ID: $Id: obex.c 298 2007-01-25 08:44:43Z holtmann $
*
* Copyright (c) 1999, 2000 Dag Brattli, All Rights Reserved.
* Copyright (c) 1999, 2000 Pontus Fuchs, All Rights Reserved.
@@ -33,11 +33,12 @@
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef _WIN32
-#include <winsock.h>
+#include <winsock2.h>
#define ESOCKTNOSUPPORT 1
#else /* _WIN32 */
@@ -60,6 +61,9 @@
#endif
#ifdef HAVE_BLUETOOTH
#include "btobex.h"
+#ifdef HAVE_BLUETOOTH_FREEBSD
+#define BDADDR_ANY NG_HCI_BDADDR_ANY
+#endif
#else
// This is to workaround compilation without Bluetooth support. - Jean II
typedef char *bdaddr_t;
@@ -802,6 +806,23 @@
}
/**
+ * OBEX_ObjecGetCommand - Get the OBEX commmand of an object
+ * @self: OBEX context
+ * @object: OBEX object (or NULL to access the current object)
+ *
+ * Call this function to get the OBEX command of an object.
+ */
+int OBEX_ObjectGetCommand(obex_t *self, obex_object_t *object)
+{
+ obex_return_val_if_fail(object != NULL || self->object != NULL, -1);
+
+ if (object)
+ return object->cmd;
+
+ return self->object->cmd;
+}
+
+/**
* OBEX_UnicodeToChar - Simple unicode to char function.
* @c: Destination (char)
* @uc: Source (unicode)
@@ -920,47 +941,102 @@
}
/**
- * InOBEX_ServerRegister - Start listening for incoming connections
+ * TcpOBEX_ServerRegister - Start listening for incoming TCP connections
* @self: OBEX handle
+ * @addr: Address to bind to (*:650 if NULL)
+ * @addrlen: Length of address structure
*
- * An easier server function to use for TCP/IP (InOBEX) only.
+ * An easier server function to use for TCP/IP (TcpOBEX) only.
+ * It supports IPv4 (AF_INET) and IPv6 (AF_INET6).
+ * Note: INADDR_ANY will get mapped to IN6ADDR_ANY and using port 0
+ * will select the default OBEX port.
*
* Returns -1 on error.
*/
-int InOBEX_ServerRegister(obex_t *self)
+int TcpOBEX_ServerRegister(obex_t *self, struct sockaddr *addr, int addrlen)
{
DEBUG(3, "\n");
+ errno = EINVAL;
obex_return_val_if_fail(self != NULL, -1);
- inobex_prepare_listen(self);
+ inobex_prepare_listen(self, addr, addrlen);
return obex_transport_listen(self);
}
/**
- * InOBEX_TransportConnect - Connect Inet transport
+ * TcpOBEX_TransportConnect - Connect TCP transport
* @self: OBEX handle
+ * @addr: Address to connect to ([::1]:650 if NULL)
+ * @addrlen: Length of address structure
+ *
+ * An easier connect function to use for TCP/IP (TcpOBEX) only.
+ * It supports IPv4 (AF_INET) and IPv6 (AF_INET6).
+ *
+ * Returns -1 on error.
+ */
+int TcpOBEX_TransportConnect(obex_t *self, struct sockaddr *addr, int addrlen)
+{
+ DEBUG(4, "\n");
+
+ errno = EINVAL;
+ obex_return_val_if_fail(self != NULL, -1);
+
+ if (self->object) {
+ DEBUG(1, "We are busy.\n");
+ errno = EBUSY;
+ return -1;
+ }
+
+ inobex_prepare_connect(self, addr, addrlen);
+ return obex_transport_connect_request(self);
+}
+/**
+ * InOBEX_ServerRegister - Start listening for incoming connections
+ * @self: OBEX handle
+ *
+ * An easier server function to use for TCP/IP (InOBEX) only.
+ *
+ * This function is deprecated, use TcpOBEX_ServerRegister() instead.
+ *
+ * Returns -1 on error.
+ */
+int InOBEX_ServerRegister(obex_t *self)
+{
+ DEBUG(3, "\n");
+
+ return TcpOBEX_ServerRegister(self, NULL, 0);
+}
+
+/**
+ * InOBEX_TransportConnect - Connect Inet transport (deprecated)
+ * @self: OBEX handle
+ * @saddr: Address to connect to
+ * @addrlen: Length of address
*
* An easier connect function to use for TCP/IP (InOBEX) only.
*
- * Note : I would like feedback on this API to know which input
- * parameter make most sense. Thanks...
+ * This function is deprecated, use TcpOBEX_TransportConnect() instead.
+ *
+ * Returns -1 on error.
*/
int InOBEX_TransportConnect(obex_t *self, struct sockaddr *saddr, int addrlen)
{
DEBUG(4, "\n");
+ errno = EINVAL;
obex_return_val_if_fail(self != NULL, -1);
if (self->object) {
DEBUG(1, "We are busy.\n");
- return -EBUSY;
+ errno = EBUSY;
+ return -1;
}
+ errno = EINVAL;
obex_return_val_if_fail(saddr != NULL, -1);
- inobex_prepare_connect(self, saddr, addrlen);
- return obex_transport_connect_request(self);
+ return TcpOBEX_TransportConnect(self, saddr, addrlen);
}
/**
@@ -1101,7 +1177,7 @@
* An easier connect function to connect to a discovered interface (currently
* USB OBEX only).
*/
-int OBEX_InterfaceConnect(obex_t *self, obex_interface_t *interface)
+int OBEX_InterfaceConnect(obex_t *self, obex_interface_t *intf)
{
DEBUG(4, "\n");
@@ -1112,12 +1188,12 @@
return -EBUSY;
}
- obex_return_val_if_fail(interface != NULL, -1);
+ obex_return_val_if_fail(intf != NULL, -1);
switch (self->trans.type) {
case OBEX_TRANS_USB:
- obex_return_val_if_fail(interface->usb.interface != NULL, -1);
+ obex_return_val_if_fail(intf->usb.intf != NULL, -1);
#ifdef HAVE_USB
- usbobex_prepare_connect(self, interface->usb.interface);
+ usbobex_prepare_connect(self, intf->usb.intf);
return obex_transport_connect_request(self);
#else
return -ESOCKTNOSUPPORT;
diff -urN openobex-1.3/lib/obex_client.c openobex/lib/obex_client.c
--- openobex-1.3/lib/obex_client.c 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_client.c 2006-09-08 21:39:39.000000000 +0200
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Pontus Fuchs <pontus.fuchs@tactel.se>
* Created at: Thu Nov 11 20:56:00 1999
- * CVS ID: $Id: obex_client.c,v 1.18 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_client.c 269 2006-09-08 19:39:39Z jhedberg $
*
* Copyright (c) 1999-2000 Pontus Fuchs, All Rights Reserved.
*
@@ -97,8 +97,8 @@
* Jean II */
if((self->object->opcode == OBEX_CMD_CONNECT) ||
(obex_object_receive(self, msg) < 0)) {
- obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);
self->state = MODE_SRV | STATE_IDLE;
+ obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);
return -1;
}
obex_deliver_event(self, OBEX_EV_UNEXPECTED, self->object->opcode, 0, FALSE);
@@ -116,8 +116,8 @@
ret = obex_object_send(self, self->object, TRUE, FALSE);
if(ret < 0) {
/* Error while sending */
- obex_deliver_event(self, OBEX_EV_LINKERR, self->object->opcode, 0, TRUE);
self->state = MODE_CLI | STATE_IDLE;
+ obex_deliver_event(self, OBEX_EV_LINKERR, self->object->opcode, 0, TRUE);
}
else if (ret == 0) {
/* Some progress made */
@@ -127,6 +127,7 @@
else {
/* Sending of object finished.. */
self->state = MODE_CLI | STATE_REC;
+ self->object->first_packet_sent = 1;
// Should we deliver a EV_PROGRESS here ? Jean II
}
break;
@@ -139,8 +140,8 @@
if(self->object->opcode == OBEX_CMD_CONNECT) {
DEBUG(2, "We expect a connect-rsp\n");
if(obex_parse_connect_header(self, msg) < 0) {
- obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);
self->state = MODE_SRV | STATE_IDLE;
+ obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);
return -1;
}
self->object->headeroffset=4;
@@ -154,8 +155,8 @@
/* Receive any headers */
if(obex_object_receive(self, msg) < 0) {
- obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);
self->state = MODE_SRV | STATE_IDLE;
+ obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);
return -1;
}
@@ -184,6 +185,7 @@
} else {
/* Notify app that client-operation is done! */
DEBUG(3, "Done! Rsp=%02x!\n", rsp);
+ self->state = MODE_SRV | STATE_IDLE;
if (self->object->abort) {
if (rsp == OBEX_RSP_SUCCESS)
obex_deliver_event(self, OBEX_EV_ABORT, self->object->opcode, rsp, TRUE);
@@ -192,7 +194,6 @@
}
else
obex_deliver_event(self, OBEX_EV_REQDONE, self->object->opcode, rsp, TRUE);
- self->state = MODE_SRV | STATE_IDLE;
}
break;
diff -urN openobex-1.3/lib/obex_client.h openobex/lib/obex_client.h
--- openobex-1.3/lib/obex_client.h 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_client.h 2006-05-04 13:24:21.000000000 +0200
@@ -6,7 +6,7 @@
* Status: Stable.
* Author: Pontus Fuchs <pontus@tactel.se>
* Created at: Thu Nov 11 20:58:00 1999
- * CVS ID: $Id: obex_client.h,v 1.4 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_client.h 230 2006-05-04 11:24:21Z holtmann $
*
* Copyright (c) 1999-2000 Pontus Fuchs, All Rights Reserved.
*
diff -urN openobex-1.3/lib/obex_connect.c openobex/lib/obex_connect.c
--- openobex-1.3/lib/obex_connect.c 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_connect.c 2006-05-04 13:24:21.000000000 +0200
@@ -6,7 +6,7 @@
* Status: Stable
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Wed May 5 11:53:44 1999
- * CVS ID: $Id: obex_connect.c,v 1.9 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_connect.c 230 2006-05-04 11:24:21Z holtmann $
*
* Copyright (c) 2000 Pontus Fuchs, All Rights Reserved.
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
diff -urN openobex-1.3/lib/obex_connect.h openobex/lib/obex_connect.h
--- openobex-1.3/lib/obex_connect.h 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_connect.h 2006-05-04 13:24:21.000000000 +0200
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Wed May 5 11:55:41 1999
- * CVS ID: $Id: obex_connect.h,v 1.5 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_connect.h 230 2006-05-04 11:24:21Z holtmann $
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
diff -urN openobex-1.3/lib/obex_header.c openobex/lib/obex_header.c
--- openobex-1.3/lib/obex_header.c 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_header.c 2006-05-04 13:24:21.000000000 +0200
@@ -6,7 +6,7 @@
* Status: Stable.
* Author: Pontus Fuchs <pontus.fuchs@tactel.se>
* Created at: Sun Mar 21 14:00:03 1999
- * CVS ID: $Id: obex_header.c,v 1.13 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_header.c 230 2006-05-04 11:24:21Z holtmann $
*
* Copyright (c) 1999-2000 Pontus Fuchs, All Rights Reserved.
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
diff -urN openobex-1.3/lib/obex_header.h openobex/lib/obex_header.h
--- openobex-1.3/lib/obex_header.h 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_header.h 2006-05-04 13:24:21.000000000 +0200
@@ -7,7 +7,7 @@
* Status: Stable.
* Author: Pontus Fuchs <pontus.fuchs@tactel.se>
* Created at: Mon Mar 1 10:30:54 1999
- * CVS ID: $Id: obex_header.h,v 1.8 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_header.h 230 2006-05-04 11:24:21Z holtmann $
*
* Copyright (c) 1999, 2000 Pontus Fuchs, All Rights Reserved.
*
diff -urN openobex-1.3/lib/obex_main.c openobex/lib/obex_main.c
--- openobex-1.3/lib/obex_main.c 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_main.c 2006-12-31 16:09:27.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Fri Jul 17 23:02:02 1998
- * CVS ID: $Id: obex_main.c,v 1.26 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_main.c 293 2006-12-31 15:09:27Z holtmann $
*
* Copyright (c) 2000 Pontus Fuchs, All Rights Reserved.
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -33,7 +33,7 @@
#endif
#ifdef _WIN32
-#include <winsock.h>
+#include <winsock2.h>
#else /* _WIN32 */
#include <unistd.h>
@@ -46,7 +46,16 @@
#include <stdio.h>
#ifdef HAVE_BLUETOOTH
+#ifdef HAVE_BLUETOOTH_LINUX
#include <bluetooth/bluetooth.h>
+#endif
+#ifdef HAVE_BLUETOOTH_FREEBSD
+#include <bluetooth.h>
+#define BTPROTO_RFCOMM BLUETOOTH_PROTO_RFCOMM
+#endif
+#ifdef HAVE_BLUETOOTH_NETBSB
+#include <bluetooth.h>
+#endif
#endif /*HAVE_BLUETOOTH*/
#endif /* _WIN32 */
@@ -167,15 +176,18 @@
*/
void obex_deliver_event(obex_t *self, int event, int cmd, int rsp, int del)
{
- if(self->state & MODE_SRV)
- self->eventcb(self, self->object, OBEX_SERVER, event, cmd, rsp);
+ obex_object_t *object = self->object;
+
+ if (del == TRUE)
+ self->object = NULL;
+
+ if (self->state & MODE_SRV)
+ self->eventcb(self, object, OBEX_MODE_SERVER, event, cmd, rsp);
else
- self->eventcb(self, self->object, OBEX_CLIENT, event, cmd, rsp);
+ self->eventcb(self, object, OBEX_MODE_CLIENT, event, cmd, rsp);
- if(del == TRUE && self->object != NULL) {
- obex_object_delete(self->object);
- self->object = NULL;
- }
+ if (del == TRUE)
+ obex_object_delete(object);
}
/*
@@ -264,7 +276,7 @@
size = ntohs(hdr->len);
actual = 0;
- if(msg->data_size != (int) ntohs(hdr->len)) {
+ if(msg->data_size < (int) ntohs(hdr->len)) {
actual = obex_transport_read(self, size - msg->data_size, buf,
buflen);
diff -urN openobex-1.3/lib/obex_main.h openobex/lib/obex_main.h
--- openobex-1.3/lib/obex_main.h 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_main.h 2007-01-24 19:45:50.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Jul 20 22:28:23 1998
- * CVS ID: $Id: obex_main.h,v 1.24 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_main.h 296 2007-01-24 18:45:50Z holtmann $
*
* Copyright (c) 1999, 2000 Pontus Fuchs, All Rights Reserved.
* Copyright (c) 1998, 1999, 2000 Dag Brattli, All Rights Reserved.
@@ -61,46 +61,43 @@
#include "obex_transport.h"
#include "databuffer.h"
-#ifdef OBEX_SYSLOG
+
+#if defined(OBEX_SYSLOG) && !defined(_WIN32)
#include <syslog.h>
+#define log_debug(format, args...) syslog(LOG_DEBUG, format, ##args)
+#define log_debug_prefix "OpenOBEX: "
+#else
+#include <stdio.h>
+#define log_debug(format, args...) fprintf(stderr, format, ##args)
+#define log_debug_prefix ""
#endif
-/* use 0 for none, 1 for sendbuff, 2 for receivebuff and 3 for both */
-#ifndef OBEX_DUMP
-#define OBEX_DUMP 0
-#endif
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef OBEX_DEBUG
-#define OBEX_DEBUG 0
+/* use integer: 0 for production
+ * 1 for verification
+ * >2 for debug
+ */
+#if OBEX_DEBUG
+extern int obex_debug;
+#define DEBUG(n, format, args...) \
+ if (obex_debug >= (n)) \
+ log_debug("%s%s(): " format, log_debug_prefix, __FUNCTION__, ##args)
+#else
+#define DEBUG(n, format, args...)
#endif
-#ifndef _WIN32
-# if OBEX_DEBUG
-extern int obex_debug;
-# ifdef OBEX_SYSLOG
-# define DEBUG(n, format, args...) if (obex_debug >= (n)) syslog(LOG_DEBUG, "OpenOBEX: %s(): " format, __FUNCTION__ , ##args)
-# else
-# define DEBUG(n, format, args...) if (obex_debug >= (n)) fprintf(stderr, "%s(): " format, __FUNCTION__ , ##args)
-# endif /* OBEX_SYSLOG */
-# else
-# define DEBUG(n, format, args...)
-# endif /* OBEX_DEBUG != 0 */
-
-# if OBEX_DUMP
+/* use bitmask: 0x1 for sendbuff
+ * 0x2 for receivebuff
+ */
+#if OBEX_DUMP
extern int obex_dump;
-# define DUMPBUFFER(n, label, msg) if (obex_dump & (n)) buf_dump(msg, label);
-# else
-# define DUMPBUFFER(n, label, msg)
-# endif /* OBEX_DUMP != 0 */
-
-#else /* _WIN32 */
-
-void DEBUG(unsigned int n, ...);
-void DUMPBUFFERS(n, label, msg);
+#define DUMPBUFFER(n, label, msg) \
+ if ((obex_dump & 0x3) & (n)) buf_dump(msg, label);
+#else
+#define DUMPBUFFER(n, label, msg)
+#endif
-#endif /* _WIN32 */
#define OBEX_VERSION 0x10 /* OBEX Protocol Version 1.1 */
diff -urN openobex-1.3/lib/obex_object.c openobex/lib/obex_object.c
--- openobex-1.3/lib/obex_object.c 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_object.c 2006-09-11 13:01:24.000000000 +0200
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Fri Apr 23 14:04:29 1999
- * CVS ID: $Id: obex_object.c,v 1.27 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_object.c 278 2006-09-11 11:01:24Z jhedberg $
*
* Copyright (c) 1999, 2000 Pontus Fuchs, All Rights Reserved.
* Copyright (c) 1999, 2000 Dag Brattli, All Rights Reserved.
@@ -33,6 +33,7 @@
#endif
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "obex_main.h"
@@ -433,6 +434,10 @@
DEBUG(4, "\n");
+ /* Don't do anything of object is suspended */
+ if (object->suspend)
+ return 0;
+
/* Calc how many bytes of headers we can fit in this package */
tx_left = self->mtu_tx - sizeof(struct obex_common_hdr);
switch(self->trans.type)
@@ -931,7 +936,7 @@
object->suspend = 0;
- if (!object->continue_received)
+ if (object->first_packet_sent && !object->continue_received)
return 0;
if (obex_object_send(self, object, TRUE, FALSE) < 0)
@@ -939,6 +944,8 @@
else
obex_deliver_event(self, OBEX_EV_PROGRESS, object->opcode, 0, FALSE);
+ self->state = MODE_CLI | STATE_REC;
+ object->first_packet_sent = 1;
object->continue_received = 0;
return 0;
diff -urN openobex-1.3/lib/obex_object.h openobex/lib/obex_object.h
--- openobex-1.3/lib/obex_object.h 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_object.h 2006-09-08 21:39:39.000000000 +0200
@@ -6,7 +6,7 @@
* Status: Stable.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Fri Apr 23 14:05:28 1999
- * CVS ID: $Id: obex_object.h,v 1.15 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_object.h 269 2006-09-08 19:39:39Z jhedberg $
*
* Copyright (c) 1999, 2000 Dag Brattli, All Rights Reserved.
* Copyright (c) 1999, 2000 Pontus Fuchs, All Rights Reserved.
@@ -76,6 +76,7 @@
int suspend; /* Temporarily stop transfering object */
int continue_received; /* CONTINUE received after sending last command */
+ int first_packet_sent; /* Whether we've sent the first packet */
const uint8_t *s_buf; /* Pointer to streaming data */
unsigned int s_len; /* Length of stream-data */
diff -urN openobex-1.3/lib/obex_server.c openobex/lib/obex_server.c
--- openobex-1.3/lib/obex_server.c 2006-06-14 11:00:59.000000000 +0200
+++ openobex/lib/obex_server.c 2006-08-28 16:15:42.000000000 +0200
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Pontus Fuchs <pontus.fuchs@tactel.se>
* Created at: Thu Nov 11 20:55:00 1999
- * CVS ID: $Id: obex_server.c,v 1.20 2006/06/14 09:00:59 holtmann Exp $
+ * CVS ID: $Id: obex_server.c 262 2006-08-28 14:15:42Z holtmann $
*
* Copyright (c) 1999-2000 Pontus Fuchs, All Rights Reserved.
*
@@ -113,9 +113,9 @@
/* Abort? */
if(cmd == OBEX_CMD_ABORT) {
DEBUG(1, "Got OBEX_ABORT request!\n");
- obex_deliver_event(self, OBEX_EV_ABORT, self->object->opcode, cmd, TRUE);
obex_response_request(self, OBEX_RSP_SUCCESS);
- self->state = MODE_SRV | STATE_IDLE;
+ self->state = MODE_SRV | STATE_IDLE;
+ obex_deliver_event(self, OBEX_EV_ABORT, self->object->opcode, cmd, TRUE);
/* This is not an Obex error, it is just that the peer
* aborted the request, so return 0 - Jean II */
return 0;
@@ -126,16 +126,16 @@
/* The cmd-field of this packet is not the
same as int the first fragment. Bail out! */
obex_response_request(self, OBEX_RSP_BAD_REQUEST);
+ self->state = MODE_SRV | STATE_IDLE;
obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, cmd, TRUE);
- self->state = MODE_SRV | STATE_IDLE;
return -1;
}
/* Get the headers... */
if(obex_object_receive(self, msg) < 0) {
obex_response_request(self, OBEX_RSP_BAD_REQUEST);
+ self->state = MODE_SRV | STATE_IDLE;
obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);
- self->state = MODE_SRV | STATE_IDLE;
return -1;
}
@@ -196,8 +196,8 @@
if(cmd == OBEX_CMD_ABORT) {
DEBUG(1, "Got OBEX_ABORT request!\n");
obex_response_request(self, OBEX_RSP_SUCCESS);
+ self->state = MODE_SRV | STATE_IDLE;
obex_deliver_event(self, OBEX_EV_ABORT, self->object->opcode, cmd, TRUE);
- self->state = MODE_SRV | STATE_IDLE;
/* This is not an Obex error, it is just that the peer
* aborted the request, so return 0 - Jean II */
return 0;
@@ -229,8 +229,8 @@
if((cmd == OBEX_CMD_CONNECT) ||
(obex_object_receive(self, msg) < 0)) {
obex_response_request(self, OBEX_RSP_BAD_REQUEST);
- obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);
self->state = MODE_SRV | STATE_IDLE;
+ obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);
return -1;
}
obex_deliver_event(self, OBEX_EV_UNEXPECTED, self->object->opcode, 0, FALSE);
@@ -263,8 +263,8 @@
DEBUG(2, "CMD_DISCONNECT done. Resetting MTU!\n");
self->mtu_tx = OBEX_MINIMUM_MTU;
}
+ self->state = MODE_SRV | STATE_IDLE;
obex_deliver_event(self, OBEX_EV_REQDONE, cmd, 0, TRUE);
- self->state = MODE_SRV | STATE_IDLE;
}
break;
diff -urN openobex-1.3/lib/obex_server.h openobex/lib/obex_server.h
--- openobex-1.3/lib/obex_server.h 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_server.h 2006-05-04 13:24:21.000000000 +0200
@@ -6,7 +6,7 @@
* Status: Stable.
* Author: Pontus Fuchs <pontus@tactel.se>
* Created at: Thu Nov 11 20:58:00 1999
- * CVS ID: $Id: obex_server.h,v 1.4 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_server.h 230 2006-05-04 11:24:21Z holtmann $
*
* Copyright (c) 1999-2000 Pontus Fuchs, All Rights Reserved.
*
diff -urN openobex-1.3/lib/obex.sym openobex/lib/obex.sym
--- openobex-1.3/lib/obex.sym 2005-12-19 12:58:25.000000000 +0100
+++ openobex/lib/obex.sym 2007-01-25 09:44:43.000000000 +0100
@@ -28,10 +28,13 @@
OBEX_ObjectSetNonHdrData
OBEX_ObjectSetHdrOffset
OBEX_ObjectReadStream
+OBEX_ObjectGetCommand
OBEX_UnicodeToChar
OBEX_CharToUnicode
OBEX_ResponseToString
OBEX_GetResponseMessage
+TcpOBEX_ServerRegister
+TcpOBEX_TransportConnect
InOBEX_ServerRegister
InOBEX_TransportConnect
IrOBEX_ServerRegister
diff -urN openobex-1.3/lib/obex_transport.c openobex/lib/obex_transport.c
--- openobex-1.3/lib/obex_transport.c 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_transport.c 2006-10-13 15:00:12.000000000 +0200
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sat May 1 20:15:04 1999
- * CVS ID: $Id: obex_transport.c,v 1.29 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID: $Id: obex_transport.c 286 2006-10-13 13:00:12Z jhedberg $
*
* Copyright (c) 1999, 2000 Pontus Fuchs, All Rights Reserved.
* Copyright (c) 1999, 2000 Dag Brattli, All Rights Reserved.
@@ -33,6 +33,7 @@
#endif
#include <string.h>
+#include <unistd.h>
#include <stdio.h>
#include "obex_main.h"
@@ -91,6 +92,7 @@
FD_ZERO(&fdset);
if(self->fd >= 0) {
FD_SET(self->fd, &fdset);
+ if(self->fd > highestfd)
highestfd = self->fd;
}
if(self->serverfd >= 0) {
@@ -453,7 +455,8 @@
case OBEX_TRANS_INET:
case OBEX_TRANS_FD:
actual = read(self->fd, buf_reserve_end(msg, max), max);
- buf_remove_end(msg, max - actual);
+ if (actual > 0)
+ buf_remove_end(msg, max - actual);
break;
#ifdef HAVE_USB
case OBEX_TRANS_USB:
diff -urN openobex-1.3/lib/obex_transport.h openobex/lib/obex_transport.h
--- openobex-1.3/lib/obex_transport.h 2006-05-04 13:24:21.000000000 +0200
+++ openobex/lib/obex_transport.h 2007-01-25 01:23:37.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Sat May 1 20:16:45 1999
- * CVS ID $Id: obex_transport.h,v 1.13 2006/05/04 11:24:21 holtmann Exp $
+ * CVS ID $Id: obex_transport.h 297 2007-01-25 00:23:37Z holtmann $
*
* Copyright (c) 1999 Dag Brattli, All Rights Reserved.
*
@@ -31,7 +31,8 @@
#define OBEX_TRANSPORT_H
#ifdef _WIN32
-#include <winsock.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
#else
#include <netinet/in.h>
#endif
@@ -40,8 +41,18 @@
#include "irda_wrap.h"
#endif /*HAVE_IRDA*/
#ifdef HAVE_BLUETOOTH
+#ifdef HAVE_BLUETOOTH_LINUX
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
+#endif
+#ifdef HAVE_BLUETOOTH_FREEBSD
+#include <bluetooth.h>
+#define sockaddr_rc sockaddr_rfcomm
+#endif
+#ifdef HAVE_BLUETOOTH_NETBSD
+#include <bluetooth.h>
+#include <netbt/rfcomm.h>
+#endif
#endif /*HAVE_BLUETOOTH*/
#ifdef HAVE_USB
#include "usbobex.h"
@@ -53,9 +64,14 @@
#ifdef HAVE_IRDA
struct sockaddr_irda irda;
#endif /*HAVE_IRDA*/
- struct sockaddr_in inet;
+ struct sockaddr_in6 inet6;
#ifdef HAVE_BLUETOOTH
+#ifdef HAVE_BLUETOOTH_LINUX
struct sockaddr_rc rfcomm;
+#endif
+#ifdef HAVE_BLUETOOTH_NETBSD
+ struct sockaddr_bt rfcomm;
+#endif
#endif /*HAVE_BLUETOOTH*/
#ifdef HAVE_USB
struct obex_usb_intf_transport_t usb;
diff -urN openobex-1.3/lib/usbobex.c openobex/lib/usbobex.c
--- openobex-1.3/lib/usbobex.c 2006-01-18 13:59:15.000000000 +0100
+++ openobex/lib/usbobex.c 2006-12-31 15:58:55.000000000 +0100
@@ -264,7 +264,7 @@
memset(intf_array, 0, sizeof(obex_interface_t) * num);
num = 0;
while (current) {
- intf_array[num].usb.interface = current;
+ intf_array[num].usb.intf = current;
usb_handle = usb_open(current->device);
get_intf_string(usb_handle, &intf_array[num].usb.manufacturer,
current->device->descriptor.iManufacturer);
@@ -313,7 +313,7 @@
free(intf[i].usb.control_interface);
free(intf[i].usb.data_interface_idle);
free(intf[i].usb.data_interface_active);
- free(intf[i].usb.interface);
+ free(intf[i].usb.intf);
}
free(intf);
}
diff -urN openobex-1.3/lib/win32compat.c openobex/lib/win32compat.c
--- openobex-1.3/lib/win32compat.c 2004-03-06 12:32:56.000000000 +0100
+++ openobex/lib/win32compat.c 2004-03-06 12:32:56.000000000 +0100
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Pontus Fuchs <pontus.fuchs@tactel.se>
* Created at: Sun Aug 06 10:22:00 2000
- * CVS ID: $Id: win32compat.c,v 1.7 2004/03/06 11:32:56 zany Exp $
+ * CVS ID: $Id: win32compat.c 162 2004-03-06 11:32:56Z zany $
*
* Copyright (c) 2000 Pontus Fuchs, All Rights Reserved.
*
diff -urN openobex-1.3/Makefile.am openobex/Makefile.am
--- openobex-1.3/Makefile.am 2006-02-10 02:46:53.000000000 +0100
+++ openobex/Makefile.am 2006-08-26 18:38:50.000000000 +0200
@@ -1,5 +1,5 @@
-SUBDIRS = include lib apps ircp doc
+SUBDIRS = include lib glib apps ircp doc
aclocaldir = $(datadir)/aclocal
@@ -7,7 +7,11 @@
pkgconfigdir = $(libdir)/pkgconfig
+if GLIB
+pkgconfig_DATA = openobex.pc openobex-glib.pc
+else
pkgconfig_DATA = openobex.pc
+endif
EXTRA_DIST = $(aclocal_DATA)
diff -urN openobex-1.3/openobex-glib.pc.in openobex/openobex-glib.pc.in
--- openobex-1.3/openobex-glib.pc.in 1970-01-01 01:00:00.000000000 +0100
+++ openobex/openobex-glib.pc.in 2006-09-29 09:41:17.000000000 +0200
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: OpenOBEX
+Description: GLib integration of the Object Exchange protocol
+Version: @VERSION@
+Requires: glib-2.0
+Requires.private: openobex
+Libs: -L${libdir} -lopenobex-glib
+Cflags: -I${includedir}
diff -urN openobex-1.3/openobex.pc.in openobex/openobex.pc.in
--- openobex-1.3/openobex.pc.in 2005-12-25 14:45:32.000000000 +0100
+++ openobex/openobex.pc.in 2006-09-29 09:41:17.000000000 +0200
@@ -6,6 +6,6 @@
Name: OpenOBEX
Description: Free implementation of the Object Exchange protocol
Version: @VERSION@
-Requires: @REQUIRES@
+Requires.private: @REQUIRES@
Libs: -L${libdir} -lopenobex
Cflags: -I${includedir}