---
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 06646bf..6955907 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -188,6 +188,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)
@@ -293,8 +310,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 477a27d..8e09960 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,6 +30,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
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables
unlimited royalty-free distribution of the report engine
for externally facing server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Openobex-users mailing list
[email protected]
http://lists.sourceforge.net/lists/listinfo/openobex-users