Description: switch to libusb-1.0
Author: Olaf Meeuwissen <paddy-hack@member.fsf.org>
Debian-Bug: #810414

diff --git a/configure.ac b/configure.ac
index 999efd2..99cc357 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,6 +9,7 @@ AM_INIT_AUTOMAKE
 AC_PROG_CC
 AC_PROG_INSTALL
 AC_PROG_LIBTOOL
+PKG_PROG_PKG_CONFIG
 
 # Checks for header files.
 AC_HEADER_STDC
@@ -27,13 +28,9 @@ AC_CHECK_FUNCS([memset strerror])
 AC_C_BIGENDIAN
 
 # Checks for libusb
-AC_PATH_PROG(LIBUSB_CONFIG,libusb-config)
-if test -n "${LIBUSB_CONFIG}"; then
-   USB_LIBS="`$LIBUSB_CONFIG --libs`"
-   USB_CFLAGS="`$LIBUSB_CONFIG --cflags`"
-else
-   AC_MSG_ERROR(cannot build garmintools without libusb)
-fi
+PKG_CHECK_MODULES([USB],[libusb-1.0],
+        [],
+        [AC_MSG_ERROR(cannot build garmintools without libusb)])
 
 # Checks for python
 AC_ARG_WITH(python,[  --with-python		  compile python bindings.],
diff --git a/src/garmin.h b/src/garmin.h
index 540ac38..c24a8bd 100644
--- a/src/garmin.h
+++ b/src/garmin.h
@@ -22,7 +22,7 @@
 
 
 #include <stdio.h>
-#include <usb.h>
+#include <libusb.h>
 #include <math.h>
 
 
@@ -1925,7 +1925,7 @@ typedef struct garmin_datatypes {
 
 
 typedef struct garmin_usb {
-  usb_dev_handle *          handle;
+  libusb_device_handle *    handle;
   int                       bulk_out;
   int                       bulk_in;
   int                       intr_in;
diff --git a/src/usb_comm.c b/src/usb_comm.c
index 6630784..214f274 100644
--- a/src/usb_comm.c
+++ b/src/usb_comm.c
@@ -21,13 +21,14 @@
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
-#include <usb.h>
+#include <libusb.h>
 #include "garmin.h"
 
 
 #define INTR_TIMEOUT  3000
 #define BULK_TIMEOUT  3000
 
+static libusb_context *ctx = NULL;
 
 /* Close the USB connection with the Garmin device. */
 
@@ -35,8 +36,8 @@ int
 garmin_close ( garmin_unit * garmin )
 {
   if ( garmin->usb.handle != NULL ) {
-    usb_release_interface(garmin->usb.handle,0);
-    usb_close(garmin->usb.handle);
+    libusb_release_interface(garmin->usb.handle,0);
+    libusb_close(garmin->usb.handle);
     garmin->usb.handle = NULL;
   }
 
@@ -53,54 +54,76 @@ garmin_close ( garmin_unit * garmin )
 int
 garmin_open ( garmin_unit * garmin )
 {
-  struct usb_bus *     bi;
-  struct usb_device *  di;
+  libusb_device **     dl;
+  libusb_device *      di;
+  int                  cnt;
   int                  err = 0;
   int                  i;
 
   if ( garmin->usb.handle == NULL ) {
-    usb_init();
-    usb_find_busses();
-    usb_find_devices();
+    if ( ctx == NULL ) {
+      err = libusb_init(&ctx);
+      if ( err ) {
+        printf("libusb_init failed: %s\n", libusb_error_name(err));
+        return ( garmin->usb.handle != NULL );
+      } else if ( garmin->verbose != 0 ) {
+        printf("[garmin] libusb_init succeeded\n");
+      }
+    }
+    cnt = libusb_get_device_list(ctx,&dl);
     
-    for ( bi = usb_busses; bi != NULL; bi = bi->next ) {
-      for ( di = bi->devices; di != NULL; di = di->next ) {
-	if ( di->descriptor.idVendor  == GARMIN_USB_VID &&
-	     di->descriptor.idProduct == GARMIN_USB_PID ) {
-
-	  if ( garmin->verbose != 0 ) {
-	    printf("[garmin] found VID %04x, PID %04x on %s/%s\n",
-		   di->descriptor.idVendor,
-		   di->descriptor.idProduct,
-		   bi->dirname,
-		   di->filename);
-	  }
+    for (i = 0; i < cnt; ++i) {
+      {
+        struct libusb_device_descriptor descriptor;
+        struct libusb_config_descriptor *config;
 
-	  garmin->usb.handle = usb_open(di);
-	  garmin->usb.read_bulk = 0;
+        di = dl[i];
+        err = libusb_get_device_descriptor (di, &descriptor);
 
-	  err = 0;
+        if ( !err &&
+             descriptor.idVendor  == GARMIN_USB_VID &&
+             descriptor.idProduct == GARMIN_USB_PID ) {
 
-	  if ( garmin->usb.handle == NULL ) {
-	    printf("usb_open failed: %s\n",usb_strerror());
-	    err = 1;
-	  } else if ( !err && garmin->verbose != 0 ) {
-	    printf("[garmin] usb_open = %p\n",garmin->usb.handle);
+	  if ( garmin->verbose != 0 ) {
+	    printf("[garmin] found VID %04x, PID %04x",
+		   descriptor.idVendor,
+		   descriptor.idProduct);
 	  }
 
-	  if ( !err && usb_set_configuration(garmin->usb.handle,1) < 0 ) {
-	    printf("usb_set_configuration failed: %s\n",usb_strerror());
-	    err = 1;
-	  } else if ( !err && garmin->verbose != 0 ) {
-	    printf("[garmin] usb_set_configuration[1] succeeded\n");
-	  }
+	  err = libusb_open(di,&garmin->usb.handle);
+	  garmin->usb.read_bulk = 0;
 
-	  if ( !err && usb_claim_interface(garmin->usb.handle,0) < 0 ) {
-	    printf("usb_claim_interface failed: %s\n",usb_strerror());
-	    err = 1;
-	  } else if ( !err && garmin->verbose != 0 ) {
-	    printf("[garmin] usb_claim_interface[0] succeeded\n");
-	  }
+	  if ( err ) {
+	    printf("libusb_open failed: %s\n",libusb_error_name(err));
+            garmin->usb.handle = NULL;
+	  } else if ( garmin->verbose != 0 ) {
+	    printf("[garmin] libusb_open = %p\n",garmin->usb.handle);
+
+            err = libusb_set_configuration(garmin->usb.handle,1);
+            if ( err ) {
+              printf("libusb_set_configuration failed: %s\n",
+                     libusb_error_name(err));
+            } else if ( garmin->verbose != 0 ) {
+              printf("[garmin] libusb_set_configuration[1] succeeded\n");
+
+              err = libusb_claim_interface(garmin->usb.handle,0);
+              if ( err ) {
+                printf("libusb_claim_interface failed: %s\n",
+                       libusb_error_name(err));
+              } else if ( garmin->verbose != 0 ) {
+                printf("[garmin] libusb_claim_interface[0] succeeded\n");
+
+                err = libusb_get_config_descriptor_by_value(di,1,&config);
+                if ( err ) {
+                  printf("libusb_get_config_descriptor_by_value failed: %s\n",
+                         libusb_error_name(err));
+                } else if ( garmin->verbose != 0 ) {
+                  printf("[garmin] libusb_get_config_descriptor_by_value "
+                         "succeeded\n");
+                }
+              }
+            }
+          }
 
 	  if ( !err ) {
 
@@ -110,31 +133,31 @@ garmin_open ( garmin_unit * garmin )
 	    */
 
 	    for ( i = 0; 
-		  i < di->config->interface->altsetting->bNumEndpoints; 
+		  i < config->interface->altsetting->bNumEndpoints;
 		  i++ ) {
-	      struct usb_endpoint_descriptor * ep;
+	      const struct libusb_endpoint_descriptor * ep;
 	      
-	      ep = &di->config->interface->altsetting->endpoint[i];
-	      switch ( ep->bmAttributes & USB_ENDPOINT_TYPE_MASK ) {
-	      case USB_ENDPOINT_TYPE_BULK:
-		if ( ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK ) {
+	      ep = &config->interface->altsetting->endpoint[i];
+	      switch ( ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK ) {
+	      case LIBUSB_TRANSFER_TYPE_BULK:
+		if ( ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK ) {
 		  garmin->usb.bulk_in = 
-		    ep->bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;
+		    ep->bEndpointAddress & LIBUSB_ENDPOINT_ADDRESS_MASK;
 		  if ( garmin->verbose != 0 ) {
 		    printf("[garmin] bulk IN  = %d\n",garmin->usb.bulk_in);
 		  }
 		} else {
 		  garmin->usb.bulk_out = 
-		    ep->bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;
+		    ep->bEndpointAddress & LIBUSB_ENDPOINT_ADDRESS_MASK;
 		  if ( garmin->verbose != 0 ) {
 		    printf("[garmin] bulk OUT = %d\n",garmin->usb.bulk_out);
 		  }
 		}
 		break;
-	      case USB_ENDPOINT_TYPE_INTERRUPT:
-		if ( ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK ) {
+	      case LIBUSB_TRANSFER_TYPE_INTERRUPT:
+		if ( ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK ) {
 		  garmin->usb.intr_in = 
-		    ep->bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;
+		    ep->bEndpointAddress & LIBUSB_ENDPOINT_ADDRESS_MASK;
 		  if ( garmin->verbose != 0 ) {
 		    printf("[garmin] intr IN  = %d\n",garmin->usb.intr_in);
 		  }
@@ -154,6 +177,7 @@ garmin_open ( garmin_unit * garmin )
 
       if ( garmin->usb.handle != NULL ) break;
     }
+    libusb_free_device_list (dl, 1);
   }
 
   /* 
@@ -164,9 +188,9 @@ garmin_open ( garmin_unit * garmin )
 
   if ( garmin->usb.handle != NULL && err != 0 ) {
     if ( garmin->verbose != 0 ) {
-      printf("[garmin] (err = %d) usb_close(%p)\n",err,garmin->usb.handle);
+      printf("[garmin] (err = %d) libusb_close(%p)\n",err,garmin->usb.handle);
     }
-    usb_close(garmin->usb.handle);
+    libusb_close(garmin->usb.handle);
     garmin->usb.handle = NULL;
   }
 
@@ -242,11 +266,12 @@ garmin_read ( garmin_unit * garmin, garmin_packet * p )
 
   if ( garmin->usb.handle != NULL ) {
     if ( garmin->usb.read_bulk == 0 ) {
-      r = usb_interrupt_read(garmin->usb.handle,
-			     garmin->usb.intr_in,
-			     p->data,
-			     sizeof(garmin_packet),
-			     INTR_TIMEOUT);
+      libusb_interrupt_transfer(garmin->usb.handle,
+                                garmin->usb.intr_in,
+                                (unsigned char *) p->data,
+                                sizeof(garmin_packet),
+                                &r,
+                                INTR_TIMEOUT);
       /* 
 	 If the packet is a "Pid_Data_Available" packet, we need to read
 	 from the bulk endpoint until we get an empty packet.
@@ -261,11 +286,12 @@ garmin_read ( garmin_unit * garmin, garmin_packet * p )
       }
       
     } else {
-      r = usb_bulk_read(garmin->usb.handle,
-			garmin->usb.bulk_in,
-			p->data,
-			sizeof(garmin_packet),
-			BULK_TIMEOUT);
+      libusb_bulk_transfer(garmin->usb.handle,
+                           garmin->usb.bulk_in,
+                           (unsigned char *) p->data,
+                           sizeof(garmin_packet),
+                           &r,
+                           BULK_TIMEOUT);
     }
   }
 
@@ -280,6 +306,7 @@ garmin_read ( garmin_unit * garmin, garmin_packet * p )
 int
 garmin_write ( garmin_unit * garmin, garmin_packet * p )
 {
+  int err = 0;
   int r = -1;
   int s = garmin_packet_size(p) + PACKET_HEADER_SIZE;
 
@@ -291,13 +318,14 @@ garmin_write ( garmin_unit * garmin, garmin_packet * p )
       garmin_print_packet(p,GARMIN_DIR_WRITE,stdout);
     }
 
-    r = usb_bulk_write(garmin->usb.handle,
-		       garmin->usb.bulk_out,
-		       p->data,
-		       s,
-		       BULK_TIMEOUT);
+    err = libusb_bulk_transfer(garmin->usb.handle,
+                               garmin->usb.bulk_out,
+                               (unsigned char *) p->data,
+                               s,
+                               &r,
+                               BULK_TIMEOUT);
     if ( r != s ) {
-      printf("usb_bulk_write failed: %s\n",usb_strerror());
+      printf("libusb_bulk_write failed: %s\n",libusb_error_name(err));
       exit(1);
     }
   }
