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}
openSUSE Build Service is sponsored by