---
 acinclude.m4         |   25 +++-
 configure.ac         |    1 +
 doc/Doxyfile         |    2 +-
 doc/Doxyfile.in      |    2 +-
 lib/Makefile.am      |    7 +-
 lib/obex_transport.c |   19 +++
 lib/usb1obex.c       |  419 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/usbobex.c        |   55 +------
 lib/usbobex.h        |   16 ++-
 lib/usbutils.c       |   82 ++++++++++
 lib/usbutils.h       |   30 ++++
 11 files changed, 599 insertions(+), 59 deletions(-)
 create mode 100644 lib/usb1obex.c
 create mode 100644 lib/usbutils.c
 create mode 100644 lib/usbutils.h

diff --git a/acinclude.m4 b/acinclude.m4
index b85d8a4..c926503 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -177,6 +177,23 @@ AC_DEFUN([AC_PATH_USB], [
        fi
 ])
 
+AC_DEFUN([AC_PATH_USB1], [
+       usb1_lib_found=no
+       PKG_CHECK_MODULES(USB1, libusb-1.0, usb1_lib_found=yes, 
AC_MSG_RESULT(no))
+       AC_CHECK_FILE(${prefix}/lib/pkgconfig/libusb-1.0.pc, REQUIRES="libusb1")
+       AC_SUBST(USB1_CFLAGS)
+       AC_SUBST(USB1_LIBS)
+
+       usb1_get_device_list=no
+       AC_CHECK_LIB(usb-1.0, libusb_get_device_list, usb1_get_device_list=yes, 
AC_DEFINE(NEED_USB1_GET_DEVICE_LIST, 1, [Define to 1 if you need the 
libusb_get_device_list() function.]))
+
+       if (test "$usb1_lib_found" = "yes" && test "$usb1_get_device_list" = 
"yes"); then
+               usb1_found=yes
+       else
+               usb1_found=no
+       fi
+])
+
 dnl AC_DEFUN([AC_PATH_GLIB], [
 dnl    PKG_CHECK_MODULES(GLIB, glib-2.0 gobject-2.0 gthread-2.0, 
glib_found=yes, AC_MSG_RESULT(no))
 dnl    AC_SUBST(GLIB_CFLAGS)
@@ -282,8 +299,12 @@ AC_DEFUN([AC_ARG_OPENOBEX], [
                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])
+       if (test "${usb_enable}" = "yes" && (test "${usb_found}" = "yes" || 
test "${usb1_found}" = "yes")); then
+               AC_DEFINE(HAVE_USB, 1, [Define if system has libusb 0.x or 
libusb 1.0 and it's enabled])
+       fi
+
+       if (test "${usb_enable}" = "yes" && test "${usb1_found}" = "yes"); then
+               AC_DEFINE(HAVE_USB1, 1, [Define if system has libusb 1.0 and 
it's enabled])
        fi
 
        AM_CONDITIONAL(GLIB, test "${glib_enable}" = "yes" && test 
"${glib_found}" = "yes")
diff --git a/configure.ac b/configure.ac
index 79cd5e6..cb57efe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,6 +28,7 @@ AC_PATH_WIN32
 AC_PATH_IRDA
 AC_PATH_BLUETOOTH
 AC_PATH_USB
+AC_PATH_USB1
 
 AC_ARG_OPENOBEX
 
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 41b820a..7b0b8ac 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -198,7 +198,7 @@ EXPAND_ONLY_PREDEF     = YES
 SEARCH_INCLUDES        = YES
 INCLUDE_PATH           = 
 INCLUDE_FILE_PATTERNS  = 
-PREDEFINED             = "LIB_SYMBOL=" "CALLAPI=" 
"OPENOBEX_SYMBOL(retval)=retval" HAVE_IRDA HAVE_USB HAVE_BLUETOOTH
+PREDEFINED             = "LIB_SYMBOL=" "CALLAPI=" 
"OPENOBEX_SYMBOL(retval)=retval" HAVE_IRDA HAVE_USB HAVE_USB1 HAVE_BLUETOOTH
 EXPAND_AS_DEFINED      = 
 SKIP_FUNCTION_MACROS   = YES
 #---------------------------------------------------------------------------
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index be9e955..dbbfb1f 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -197,7 +197,7 @@ EXPAND_ONLY_PREDEF     = YES
 SEARCH_INCLUDES        = YES
 INCLUDE_PATH           = 
 INCLUDE_FILE_PATTERNS  = 
-PREDEFINED             = "LIB_SYMBOL=" "CALLAPI=" 
"OPENOBEX_SYMBOL(retval)=retval" HAVE_IRDA HAVE_USB HAVE_BLUETOOTH
+PREDEFINED             = "LIB_SYMBOL=" "CALLAPI=" 
"OPENOBEX_SYMBOL(retval)=retval" HAVE_IRDA HAVE_USB HAVE_USB1 HAVE_BLUETOOTH
 EXPAND_AS_DEFINED      = 
 SKIP_FUNCTION_MACROS   = YES
 #---------------------------------------------------------------------------
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f45e7da..7510ee9 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -15,17 +15,18 @@ libopenobex_la_SOURCES = \
        btobex.c btobex.h \
        databuffer.c databuffer.h \
        irda.h irda_wrap.h \
-       usbobex.c usbobex.h \
+       usbutils.c usbutils.h \
+       usbobex.c usb1obex.c usbobex.h \
        bluez_compat.h
 
-libopenobex_la_CFLAGS = @CFLAG_VISIBILITY@
+libopenobex_la_CFLAGS = @CFLAG_VISIBILITY@ @USB1_CFLAGS@
 
 libopenobex_la_LDFLAGS = \
        -no-undefined \
        -version-info 6:0:0 \
        -export-symbols $(top_srcdir)/lib/obex.sym
 
-libopenobex_la_LIBADD = @USB_LIBS@ @EXTRA_LIBS@
+libopenobex_la_LIBADD = @USB_LIBS@ @USB1_LIBS@ @EXTRA_LIBS@
 
 INCLUDES = -I$(top_srcdir)/include
 
diff --git a/lib/obex_transport.c b/lib/obex_transport.c
index 690a79f..e3881e9 100644
--- a/lib/obex_transport.c
+++ b/lib/obex_transport.c
@@ -433,10 +433,19 @@ int obex_transport_write(obex_t *self, buf_t *msg)
                if (self->trans.connected != TRUE)
                        break;
                DEBUG(4, "Endpoint %d\n", 
self->trans.self.usb.data_endpoint_write);
+#ifdef HAVE_USB1
+               int usberror = libusb_bulk_transfer(self->trans.self.usb.dev,
+                                       
self->trans.self.usb.data_endpoint_write,
+                                       (unsigned char *) msg->data, 
msg->data_size,
+                                       &actual, USB_OBEX_TIMEOUT);
+               if (usberror)
+                       actual = usberror;
+#else
                actual = usb_bulk_write(self->trans.self.usb.dev,
                                        
self->trans.self.usb.data_endpoint_write,
                                        (char *) msg->data, msg->data_size,
                                        USB_OBEX_TIMEOUT);
+#endif
                break;
 #endif /*HAVE_USB*/
        case OBEX_TRANS_CUSTOM:
@@ -493,10 +502,20 @@ int obex_transport_read(obex_t *self, int max, uint8_t 
*buf, int buflen)
                if (self->trans.connected != TRUE)
                        break;
                DEBUG(4, "Endpoint %d\n", 
self->trans.self.usb.data_endpoint_read);
+#ifdef HAVE_USB1
+               int usberror = libusb_bulk_transfer(self->trans.self.usb.dev,
+                                       self->trans.self.usb.data_endpoint_read,
+                                       buf_reserve_end(msg, self->mtu_rx),
+                                       self->mtu_rx, &actual,
+                                       USB_OBEX_TIMEOUT);
+               if (usberror)
+                       actual = usberror;
+#else
                actual = usb_bulk_read(self->trans.self.usb.dev,
                                        self->trans.self.usb.data_endpoint_read,
                                        buf_reserve_end(msg, self->mtu_rx),
                                        self->mtu_rx, USB_OBEX_TIMEOUT);
+#endif
                buf_remove_end(msg, self->mtu_rx - actual);
                break;
 #endif /*HAVE_USB*/
diff --git a/lib/usb1obex.c b/lib/usb1obex.c
new file mode 100644
index 0000000..1dffa27
--- /dev/null
+++ b/lib/usb1obex.c
@@ -0,0 +1,419 @@
+/**
+       \file usbobex.c
+       USB OBEX, USB transport for OBEX, libusb 1.x support.
+       OpenOBEX library - Free implementation of the Object Exchange protocol.
+
+       Copyright (c) 2009 Alex Kanavin, All Rights Reserved.
+
+       OpenOBEX 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 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 Lesser General Public License for more details.
+
+       You should have received a copy of the GNU Lesser General Public
+       License along with OpenOBEX. If not, see <http://www.gnu.org/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_USB1
+
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>             /* perror */
+#include <errno.h>             /* errno and EADDRNOTAVAIL */
+#include <stdlib.h>
+
+#include <libusb.h>
+
+#include "obex_main.h"
+#include "usbobex.h"
+#include "usbutils.h"
+
+static struct libusb_context *libusb_ctx = NULL;
+
+/*
+ * Function usbobex_prepare_connect (self, interface)
+ *
+ *    Prepare for USB OBEX connect
+ *
+ */
+void usbobex_prepare_connect(obex_t *self, struct obex_usb_intf_transport_t 
*intf)
+{
+       self->trans.self.usb = *intf;
+}
+
+/*
+ * Helper function to usbobex_find_interfaces
+ */
+static void find_eps(struct obex_usb_intf_transport_t *intf, struct 
libusb_interface_descriptor data_intf, int *found_active, int *found_idle)
+{
+       struct libusb_endpoint_descriptor ep0, ep1;
+
+       if (data_intf.bNumEndpoints == 2) {
+               ep0 = data_intf.endpoint[0];
+               ep1 = data_intf.endpoint[1];
+               if ((ep0.bEndpointAddress & LIBUSB_ENDPOINT_IN) &&
+                   ((ep0.bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == 
LIBUSB_TRANSFER_TYPE_BULK) &&
+                   !(ep1.bEndpointAddress & LIBUSB_ENDPOINT_IN) &&
+                   ((ep1.bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == 
LIBUSB_TRANSFER_TYPE_BULK)) {
+                       *found_active = 1;
+                       intf->data_active_setting = data_intf.bAlternateSetting;
+                       intf->data_interface_active_description = 
data_intf.iInterface;
+                       intf->data_endpoint_read = ep0.bEndpointAddress;
+                       intf->data_endpoint_write = ep1.bEndpointAddress;
+               }
+               if (!(ep0.bEndpointAddress & LIBUSB_ENDPOINT_IN) &&
+                   ((ep0.bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == 
LIBUSB_TRANSFER_TYPE_BULK) &&
+                   (ep1.bEndpointAddress & LIBUSB_ENDPOINT_IN) &&
+                   ((ep1.bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == 
LIBUSB_TRANSFER_TYPE_BULK)) {
+                       *found_active = 1;
+                       intf->data_active_setting = data_intf.bAlternateSetting;
+                       intf->data_interface_active_description = 
data_intf.iInterface;
+                       intf->data_endpoint_read = ep1.bEndpointAddress;
+                       intf->data_endpoint_write = ep0.bEndpointAddress;
+               }
+       }
+       if (data_intf.bNumEndpoints == 0) {
+               *found_idle = 1;
+               intf->data_idle_setting = data_intf.bAlternateSetting;
+               intf->data_interface_idle_description = data_intf.iInterface;
+       }
+}
+
+/*
+ * Helper function to usbobex_find_interfaces
+ */
+static int find_obex_data_interface(const unsigned char *buffer, int buflen, 
struct libusb_config_descriptor *config, struct obex_usb_intf_transport_t *intf)
+{
+       struct cdc_union_desc *union_header = NULL;
+       int i, a;
+       int found_active = 0;
+       int found_idle = 0;
+
+       if (!buffer) {
+               DEBUG(2,"Weird descriptor references");
+               return -EINVAL;
+       }
+
+       while (buflen > 0) {
+               if (buffer [1] != USB_DT_CS_INTERFACE) {
+                       DEBUG(2,"skipping garbage");
+                       goto next_desc;
+               }
+               switch (buffer [2]) {
+               case CDC_UNION_TYPE: /* we've found it */
+                       if (union_header) {
+                               DEBUG(2,"More than one union descriptor, 
skiping ...");
+                               goto next_desc;
+                       }
+                       union_header = (struct cdc_union_desc *)buffer;
+                       break;
+               case CDC_OBEX_TYPE: /* maybe check version */
+               case CDC_OBEX_SERVICE_ID_TYPE: /* This one is handled later */
+               case CDC_HEADER_TYPE:
+                       break; /* for now we ignore it */
+               default:
+                       DEBUG(2, "Ignoring extra header, type %d, length %d", 
buffer[2], buffer[0]);
+                       break;
+               }
+next_desc:
+               buflen -= buffer[0];
+               buffer += buffer[0];
+       }
+
+       if (!union_header) {
+               DEBUG(2,"No union descriptor, giving up\n");
+               return -ENODEV;
+       }
+       /* Found the slave interface, now find active/idle settings and 
endpoints */
+       intf->data_interface = union_header->bSlaveInterface0;
+       /* Loop through all of the interfaces */
+       for (i = 0; i < config->bNumInterfaces; i++) {
+               /* Loop through all of the alternate settings */
+               for (a = 0; a < config->interface[i].num_altsetting; a++) {
+                       /* Check if this interface is OBEX data interface*/
+                       /* and find endpoints */
+                       if (config->interface[i].altsetting[a].bInterfaceNumber 
== intf->data_interface)
+                               find_eps(intf, 
config->interface[i].altsetting[a], &found_active, &found_idle);
+               }
+       }
+       if (!found_idle) {
+               DEBUG(2,"No idle setting\n");
+               return -ENODEV;
+       }
+       if (!found_active) {
+               DEBUG(2,"No active setting\n");
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+
+/*
+ * Helper function to usbobex_find_interfaces
+ */
+static int get_intf_string(struct libusb_device_handle *usb_handle, char 
**string, int id)
+{
+       if (id) {
+               if ((*string = malloc(USB_MAX_STRING_SIZE)) == NULL)
+                       return -ENOMEM;
+               *string[0] = '\0';
+               return libusb_get_string_descriptor_ascii(usb_handle, id, 
(unsigned char*)*string, USB_MAX_STRING_SIZE);
+       }
+
+       return 0;
+}
+
+/*
+ * Helper function to usbobex_find_interfaces
+ */
+static struct obex_usb_intf_transport_t *check_intf(struct libusb_device *dev,
+                                       struct libusb_config_descriptor 
*conf_desc, int i, int a,
+                                       struct obex_usb_intf_transport_t 
*current)
+{
+       struct obex_usb_intf_transport_t *next = NULL;
+       if ((conf_desc->interface[i].altsetting[a].bInterfaceClass == 
USB_CDC_CLASS)
+           && (conf_desc->interface[i].altsetting[a].bInterfaceSubClass == 
USB_CDC_OBEX_SUBCLASS)) {
+               int err;
+               const unsigned char *buffer = 
conf_desc->interface[i].altsetting[a].extra;
+               int buflen = conf_desc->interface[i].altsetting[a].extra_length;
+
+               next = malloc(sizeof(struct obex_usb_intf_transport_t));
+               if (next == NULL)
+                       return current;
+               next->device = dev;
+               libusb_ref_device(dev);
+               next->configuration = conf_desc->bConfigurationValue;
+               next->configuration_description = conf_desc->iConfiguration;
+               next->control_interface = 
conf_desc->interface[i].altsetting[a].bInterfaceNumber;
+               next->control_interface_description = 
conf_desc->interface[i].altsetting[a].iInterface;
+               next->control_setting = 
conf_desc->interface[i].altsetting[a].bAlternateSetting;
+               next->extra_descriptors = malloc(buflen);
+               if (next->extra_descriptors)
+                       memcpy(next->extra_descriptors, buffer, buflen);
+               next->extra_descriptors_len = buflen;
+
+               err = find_obex_data_interface(buffer, buflen, conf_desc, next);
+               if (err)
+                       free(next);
+               else {
+                       if (current)
+                               current->next = next;
+                       next->prev = current;
+                       next->next = NULL;
+                       current = next;
+               }
+       }
+       return current;
+}
+
+/*
+ * Function usbobex_find_interfaces ()
+ *
+ *    Find available USBOBEX interfaces on the system
+ */
+int usbobex_find_interfaces(obex_interface_t **interfaces)
+{
+       int usbinit_error = 0;
+       struct obex_usb_intf_transport_t *current = NULL, *tmp = NULL;
+       int i, a, num;
+       obex_interface_t *intf_array = NULL;
+
+       if (libusb_ctx == NULL)
+               usbinit_error = libusb_init(&libusb_ctx);
+       if (usbinit_error == 0) {
+               libusb_device **list;
+               size_t cnt_dev = libusb_get_device_list(libusb_ctx, &list);
+               size_t d = 0;
+               for (d = 0; d < cnt_dev; d++) {
+                       struct libusb_config_descriptor *conf_desc;
+                       if (libusb_get_active_config_descriptor(list[d], 
&conf_desc) == 0) {
+                               for (i = 0; i < conf_desc->bNumInterfaces; i++) 
{
+                                       for (a = 0; a < 
conf_desc->interface[i].num_altsetting; a++) {
+                                               current = check_intf(list[d], 
conf_desc, i, a, current);
+                                       }
+                               }
+                               libusb_free_config_descriptor(conf_desc);
+                       }
+               }
+               libusb_free_device_list(list, 1);
+       }
+
+       num = 0;
+       if (current)
+               num++;
+       while (current && current->prev) {
+               current = current->prev;
+               num++;
+       }
+       intf_array = malloc(sizeof(obex_interface_t) * num);
+       if (intf_array == NULL)
+               goto cleanup_list;
+       memset(intf_array, 0, sizeof(obex_interface_t) * num);
+       num = 0;
+       while (current) {
+               intf_array[num].usb.intf = current;
+               struct libusb_device_handle *usb_handle;
+               if (libusb_open(current->device, &usb_handle) == 0) {
+                       struct libusb_device_descriptor dev_desc;
+                       if (libusb_get_device_descriptor(current->device, 
&dev_desc) == 0) {
+                               get_intf_string(usb_handle, 
&intf_array[num].usb.manufacturer,
+                                       dev_desc.iManufacturer);
+                               get_intf_string(usb_handle, 
&intf_array[num].usb.product,
+                                       dev_desc.iProduct);
+                               get_intf_string(usb_handle, 
&intf_array[num].usb.serial,
+                                       dev_desc.iSerialNumber);
+                               get_intf_string(usb_handle, 
&intf_array[num].usb.configuration,
+                                       current->configuration_description);
+                               get_intf_string(usb_handle, 
&intf_array[num].usb.control_interface,
+                                       current->control_interface_description);
+                               get_intf_string(usb_handle, 
&intf_array[num].usb.data_interface_idle,
+                                       
current->data_interface_idle_description);
+                               get_intf_string(usb_handle, 
&intf_array[num].usb.data_interface_active,
+                                       
current->data_interface_active_description);
+                       }
+                       find_obex_service_descriptor(current->extra_descriptors,
+                                       current->extra_descriptors_len,
+                                       &intf_array[num].usb.service);
+                       libusb_close(usb_handle);
+               }
+               current = current->next; num++;
+       }
+       *interfaces = intf_array;
+       return num;
+
+cleanup_list:
+       while (current) {
+               tmp = current->next;
+               free(current);
+               current = tmp;
+       }
+       return 0;
+}
+
+/*
+ * Function usbobex_free_interfaces ()
+ *
+ *    Free the list of discovered USBOBEX interfaces on the system
+ */
+void usbobex_free_interfaces(int num, obex_interface_t *intf)
+{
+       int i;
+
+       if (intf == NULL)
+               return;
+
+       for (i = 0; i < num; i++) {
+               free(intf[i].usb.manufacturer);
+               free(intf[i].usb.product);
+               free(intf[i].usb.serial);
+               free(intf[i].usb.configuration);
+               free(intf[i].usb.control_interface);
+               free(intf[i].usb.data_interface_idle);
+               free(intf[i].usb.data_interface_active);
+               free(intf[i].usb.service);
+               free(intf[i].usb.intf->extra_descriptors);
+               libusb_unref_device(intf[i].usb.intf->device);
+               free(intf[i].usb.intf);
+       }
+
+       free(intf);
+       if (libusb_ctx)
+               libusb_exit(libusb_ctx);
+
+}
+
+/*
+ * Function usbobex_connect_request (self)
+ *
+ *    Open the USB connection
+ *
+ */
+int usbobex_connect_request(obex_t *self)
+{
+       int ret;
+
+       DEBUG(4, "\n");
+
+       ret = libusb_open(self->trans.self.usb.device, 
&self->trans.self.usb.dev);
+       if (ret != 0)
+               return ret;
+
+       ret = libusb_claim_interface(self->trans.self.usb.dev, 
self->trans.self.usb.control_interface);
+       if (ret < 0) {
+               DEBUG(4, "Can't claim control interface %d", ret);
+               goto err1;
+       }
+
+       ret = libusb_set_interface_alt_setting(self->trans.self.usb.dev, 
self->trans.self.usb.control_interface, self->trans.self.usb.control_setting);
+       if (ret < 0) {
+               DEBUG(4, "Can't set control setting %d", ret);
+               goto err2;
+       }
+
+       ret = libusb_claim_interface(self->trans.self.usb.dev, 
self->trans.self.usb.data_interface);
+       if (ret < 0) {
+               DEBUG(4, "Can't claim data interface %d", ret);
+               goto err2;
+       }
+
+       ret = libusb_set_interface_alt_setting(self->trans.self.usb.dev, 
self->trans.self.usb.data_interface, self->trans.self.usb.data_active_setting);
+       if (ret < 0) {
+               DEBUG(4, "Can't set data active setting %d", ret);
+               goto err3;
+       }
+
+       self->trans.mtu = OBEX_MAXIMUM_MTU;
+       DEBUG(2, "transport mtu=%d\n", self->trans.mtu);
+       return 1;
+
+err3:
+       libusb_release_interface(self->trans.self.usb.dev, 
self->trans.self.usb.data_interface);
+err2:
+       libusb_release_interface(self->trans.self.usb.dev, 
self->trans.self.usb.control_interface);
+err1:
+       libusb_close(self->trans.self.usb.dev);
+       return ret;
+}
+
+/*
+ * Function usbobex_disconnect_request (self)
+ *
+ *    Shutdown the USB link
+ *
+ */
+int usbobex_disconnect_request(obex_t *self)
+{
+       int ret;
+       if (self->trans.connected == FALSE)
+               return 0;
+
+       DEBUG(4, "\n");
+
+       libusb_clear_halt(self->trans.self.usb.dev, 
self->trans.self.usb.data_endpoint_read);
+       libusb_clear_halt(self->trans.self.usb.dev, 
self->trans.self.usb.data_endpoint_write);
+
+       ret = libusb_set_interface_alt_setting(self->trans.self.usb.dev, 
self->trans.self.usb.data_interface, self->trans.self.usb.data_idle_setting);
+       if (ret < 0)
+               DEBUG(4, "Can't set data idle setting %d", ret);
+       ret = libusb_release_interface(self->trans.self.usb.dev, 
self->trans.self.usb.data_interface);
+       if (ret < 0)
+               DEBUG(4, "Can't release data interface %d", ret);
+       ret = libusb_release_interface(self->trans.self.usb.dev, 
self->trans.self.usb.control_interface);
+       if (ret < 0)
+               DEBUG(4, "Can't release control interface %d", ret);
+       libusb_close(self->trans.self.usb.dev);
+       return 1;
+}
+
+
+#endif /* HAVE_USB1 */
diff --git a/lib/usbobex.c b/lib/usbobex.c
index b87458d..2ad91a0 100644
--- a/lib/usbobex.c
+++ b/lib/usbobex.c
@@ -23,7 +23,7 @@
 #include <config.h>
 #endif
 
-#ifdef HAVE_USB
+#if defined HAVE_USB && !defined HAVE_USB1
 
 #ifdef _WIN32
 #include <winsock2.h>
@@ -43,6 +43,7 @@
 
 #include "obex_main.h"
 #include "usbobex.h"
+#include "usbutils.h"
 
 /*
  * Function usbobex_prepare_connect (self, interface)
@@ -203,7 +204,9 @@ static struct obex_usb_intf_transport_t *check_intf(struct 
usb_device *dev,
                next->control_interface = 
dev->config[c].interface[i].altsetting[a].bInterfaceNumber;
                next->control_interface_description = 
dev->config[c].interface[i].altsetting[a].iInterface;
                next->control_setting = 
dev->config[c].interface[i].altsetting[a].bAlternateSetting;
-               next->extra_descriptors = buffer;
+               next->extra_descriptors = malloc(buflen);
+               if (next->extra_descriptors)
+                       memcpy(next->extra_descriptors, buffer, buflen);
                next->extra_descriptors_len = buflen;
 
                err = find_obex_data_interface(buffer, buflen, dev->config[c], 
next);
@@ -222,53 +225,6 @@ static struct obex_usb_intf_transport_t *check_intf(struct 
usb_device *dev,
 }
 
 /*
- * Helper function to usbobex_find_interfaces
- */
-static void find_obex_service_descriptor(unsigned char *buffer, int buflen, 
obex_usb_intf_service_t **service)
-{
-       if (!buffer) {
-               DEBUG(2, "Weird descriptor references");
-               return ;
-       }
-       while (buflen > 0) {
-               if (buffer[1] != USB_DT_CS_INTERFACE) {
-                       DEBUG(2, "skipping garbage");
-                       goto next_desc;
-               }
-               switch (buffer[2]) {
-               case CDC_OBEX_SERVICE_ID_TYPE: /* we've found it */
-                       if (buflen < 22) /* Check descriptor size */
-                               DEBUG(2, "Invalid service id descriptor");
-                       else if (*service == NULL) {
-                               *service = 
malloc(sizeof(obex_usb_intf_service_t));
-                               if (*service != NULL) {
-                                       const uint8_t default_uuid[16] = 
WMC_DEFAULT_OBEX_SERVER_UUID;
-                                       (*service)->role = buffer[3];
-                                       memcpy((*service)->uuid, buffer+4, 16);
-                                       (*service)->version = 
(buffer[20]<<8)|(buffer[21]);
-                                       if (memcmp((*service)->uuid, 
default_uuid, 16) == 0 )
-                                               (*service)->is_default_uuid = 1;
-                                       else
-                                               (*service)->is_default_uuid = 0;
-                               }
-                       }
-                       break;
-               case CDC_OBEX_TYPE: /* maybe check version */
-               case CDC_UNION_TYPE:
-               case CDC_HEADER_TYPE:
-                       break;
-               default:
-                       DEBUG(2, "Ignoring extra header, type %d, length %d", 
buffer[2], buffer[0]);
-                       break;
-               }
-next_desc:
-               buflen -= buffer[0];
-               buffer += buffer[0];
-       }
-}
-
-
-/*
  * Function usbobex_find_interfaces ()
  *
  *    Find available USBOBEX interfaces on the system
@@ -374,6 +330,7 @@ void usbobex_free_interfaces(int num, obex_interface_t 
*intf)
                free(intf[i].usb.data_interface_idle);
                free(intf[i].usb.data_interface_active);
                free(intf[i].usb.service);
+               free(intf[i].usb.intf->extra_descriptors);
                free(intf[i].usb.intf);
        }
 
diff --git a/lib/usbobex.h b/lib/usbobex.h
index 9fb1797..80203ae 100644
--- a/lib/usbobex.h
+++ b/lib/usbobex.h
@@ -23,12 +23,16 @@
 #define USBOBEX_H
 
 #include <openobex/obex_const.h>
+
+#ifdef HAVE_USB1
+#include <libusb.h>
+#else
 #include <usb.h>
+#endif
 
 /* Information about a USB OBEX interface present on the system */
 struct obex_usb_intf_transport_t {
        struct obex_usb_intf_transport_t *prev, *next;  /* Next and previous 
interfaces in the list */
-       struct usb_device *device;              /* USB device that has the 
interface */
        int configuration;                      /* Device configuration */
        int configuration_description;          /* Configuration string 
descriptor number */
        int control_interface;                  /* OBEX master interface */
@@ -37,7 +41,7 @@ struct obex_usb_intf_transport_t {
                                                 * If non-zero, use 
usb_get_string_simple() from 
                                                 * libusb to retrieve 
human-readable description
                                                 */
-       unsigned char *extra_descriptors;               /* Extra master 
interface descriptors */
+       char *extra_descriptors;                /* Extra master interface 
descriptors */
        int extra_descriptors_len;              /* Length of extra descriptors 
*/
        int data_interface;                     /* OBEX data/slave interface */
        int data_idle_setting;                  /* OBEX data/slave idle setting 
*/
@@ -48,7 +52,13 @@ struct obex_usb_intf_transport_t {
                                                 * in active setting */
        int data_endpoint_read;                 /* OBEX data/slave interface 
read endpoint */
        int data_endpoint_write;                /* OBEX data/slave interface 
write endpoint */
-       usb_dev_handle *dev;                    /* libusb handler */
+#ifdef HAVE_USB1
+       struct libusb_device *device;           /* libusb 1.x device */
+       struct libusb_device_handle *dev;       /* libusb 1.x device handle */
+#else
+       struct usb_device *device;              /* libusb 0.x device */
+       usb_dev_handle *dev;                    /* libusb 0.x device handle */
+#endif
 };
 
 /* "Union Functional Descriptor" from CDC spec 5.2.3.X
diff --git a/lib/usbutils.c b/lib/usbutils.c
new file mode 100644
index 0000000..92bb4bf
--- /dev/null
+++ b/lib/usbutils.c
@@ -0,0 +1,82 @@
+/**
+       \file usbutils.c
+       USB OBEX, USB transport for OBEX, support functions.
+       OpenOBEX library - Free implementation of the Object Exchange protocol.
+
+       Copyright (c) 2009 Alex Kanavin, All Rights Reserved.
+
+       OpenOBEX 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 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 Lesser General Public License for more details.
+
+       You should have received a copy of the GNU Lesser General Public
+       License along with OpenOBEX. If not, see <http://www.gnu.org/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_USB
+
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>             /* perror */
+#include <errno.h>             /* errno and EADDRNOTAVAIL */
+#include <stdlib.h>
+#include "obex_main.h"
+#include "usbobex.h"
+
+/*
+ * Helper function to usbobex_find_interfaces
+ */
+void find_obex_service_descriptor(const char *buffer, int buflen, 
obex_usb_intf_service_t **service)
+{
+       if (!buffer) {
+               DEBUG(2, "Weird descriptor references");
+               return ;
+       }
+       while (buflen > 0) {
+               if (buffer[1] != USB_DT_CS_INTERFACE) {
+                       DEBUG(2, "skipping garbage");
+                       goto next_desc;
+               }
+               switch (buffer[2]) {
+               case CDC_OBEX_SERVICE_ID_TYPE: /* we've found it */
+                       if (buflen < 22) /* Check descriptor size */
+                               DEBUG(2, "Invalid service id descriptor");
+                       else if (*service == NULL) {
+                               *service = 
malloc(sizeof(obex_usb_intf_service_t));
+                               if (*service != NULL) {
+                                       const uint8_t default_uuid[16] = 
WMC_DEFAULT_OBEX_SERVER_UUID;
+                                       (*service)->role = buffer[3];
+                                       memcpy((*service)->uuid, buffer+4, 16);
+                                       (*service)->version = 
(buffer[20]<<8)|(buffer[21]);
+                                       if (memcmp((*service)->uuid, 
default_uuid, 16) == 0 )
+                                               (*service)->is_default_uuid = 1;
+                                       else
+                                               (*service)->is_default_uuid = 0;
+                               }
+                       }
+                       break;
+               case CDC_OBEX_TYPE: /* maybe check version */
+               case CDC_UNION_TYPE:
+               case CDC_HEADER_TYPE:
+                       break;
+               default:
+                       DEBUG(2, "Ignoring extra header, type %d, length %d", 
buffer[2], buffer[0]);
+                       break;
+               }
+next_desc:
+               buflen -= buffer[0];
+               buffer += buffer[0];
+       }
+}
+
+#endif
diff --git a/lib/usbutils.h b/lib/usbutils.h
new file mode 100644
index 0000000..02cb6e3
--- /dev/null
+++ b/lib/usbutils.h
@@ -0,0 +1,30 @@
+/**
+       \file usbutils.h
+       USB OBEX, USB transport for OBEX, support functions.
+       OpenOBEX library - Free implementation of the Object Exchange protocol.
+
+       Copyright (c) 2009 Alex Kanavin, All Rights Reserved.
+
+       OpenOBEX 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 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 Lesser General Public License for more details.
+
+       You should have received a copy of the GNU Lesser General Public
+       License along with OpenOBEX. If not, see <http://www.gnu.org/>.
+ */
+
+#ifndef USBUTILS_H
+#define USBUTILS_H
+
+#include <openobex/obex_const.h>
+
+void find_obex_service_descriptor(const char *buffer, int buflen, 
obex_usb_intf_service_t **service);
+
+#endif
+
-- 
1.6.0.6


------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and code to
build responsive, highly engaging applications that combine the power of local
resources and data with the reach of the web. Download the Adobe AIR SDK and
Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com
_______________________________________________
Openobex-users mailing list
Openobex-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/openobex-users

Reply via email to