/[pcsclite]/trunk/Drivers/ccid/src/ccid_usb.c
ViewVC logotype

Diff of /trunk/Drivers/ccid/src/ccid_usb.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2469 by rousseau, Thu Mar 8 10:21:47 2007 UTC revision 5010 by rousseau, Thu Jun 17 09:51:59 2010 UTC
# Line 1  Line 1 
1  /*  /*
2      ccid_usb.c: USB access routines using the libusb library      ccid_usb.c: USB access routines using the libusb library
3      Copyright (C) 2003-2004   Ludovic Rousseau      Copyright (C) 2003-2010   Ludovic Rousseau
4    
5      This library is free software; you can redistribute it and/or      This library is free software; you can redistribute it and/or
6      modify it under the terms of the GNU Lesser General Public      modify it under the terms of the GNU Lesser General Public
# Line 12  Line 12 
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Lesser General Public License for more details.      Lesser General Public License for more details.
14    
15      You should have received a copy of the GNU Lesser General Public          You should have received a copy of the GNU Lesser General Public License
16      License along with this library; if not, write to the Free Software          along with this library; if not, write to the Free Software Foundation,
17      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA          Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */  */
19    
20  /*  /*
# Line 29  Line 29 
29  # ifdef S_SPLINT_S  # ifdef S_SPLINT_S
30  # include <sys/types.h>  # include <sys/types.h>
31  # endif  # endif
32  #include <usb.h>  #include <libusb-1.0/libusb.h>
33    #include <stdlib.h>
34    #include <ifdhandler.h>
35    
36  #include "misc.h"  #include "misc.h"
37  #include "ccid.h"  #include "ccid.h"
# Line 57  Line 59 
59    
60  typedef struct  typedef struct
61  {  {
62          usb_dev_handle *handle;          libusb_device_handle *dev_handle;
63          char *dirname;          uint8_t bus_number;
64          char *filename;          uint8_t device_address;
65          int interface;          int interface;
66    
67          /*          /*
# Line 67  typedef struct Line 69  typedef struct
69           */           */
70          int bulk_in;          int bulk_in;
71          int bulk_out;          int bulk_out;
72            int interrupt;
73    
74          /* Number of slots using the same device */          /* Number of slots using the same device */
75          int real_nb_opened_slots;          int real_nb_opened_slots;
# Line 82  typedef struct Line 85  typedef struct
85  /* The _usbDevice structure must be defined before including ccid_usb.h */  /* The _usbDevice structure must be defined before including ccid_usb.h */
86  #include "ccid_usb.h"  #include "ccid_usb.h"
87    
88  static int get_end_points(struct usb_device *dev, _usbDevice *usbdevice);  static int get_end_points(struct libusb_config_descriptor *desc,
89  int ccid_check_firmware(struct usb_device *dev);          _usbDevice *usbdevice, int num);
90    int ccid_check_firmware(struct libusb_device_descriptor *desc);
91  static unsigned int *get_data_rates(unsigned int reader_index,  static unsigned int *get_data_rates(unsigned int reader_index,
92          struct usb_device *dev);          struct libusb_config_descriptor *desc, int num);
93    
94  /* ne need to initialize to 0 since it is static */  /* ne need to initialize to 0 since it is static */
95  static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];  static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];
# Line 102  struct _bogus_firmware Line 106  struct _bogus_firmware
106  };  };
107    
108  static struct _bogus_firmware Bogus_firmwares[] = {  static struct _bogus_firmware Bogus_firmwares[] = {
 #ifndef O2MICRO_OZ776_PATCH  
         { 0x0b97, 0x7762, 0x0111 },     /* Oz776S */ /* the firmware version is not correct since I do not have received a working reader yet */  
 #endif  
109          { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */          { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */
110          { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */          { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */
111          { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */          { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */
# Line 115  static struct _bogus_firmware Bogus_firm Line 116  static struct _bogus_firmware Bogus_firm
116          { 0x0DC3, 0x1004, 0x0502 },     /* ASE IIIe USBv2 */          { 0x0DC3, 0x1004, 0x0502 },     /* ASE IIIe USBv2 */
117          { 0x0DC3, 0x1102, 0x0607 },     /* ASE IIIe KB USB */          { 0x0DC3, 0x1102, 0x0607 },     /* ASE IIIe KB USB */
118          { 0x058F, 0x9520, 0x0102 },     /* Alcor AU9520-G */          { 0x058F, 0x9520, 0x0102 },     /* Alcor AU9520-G */
119            { 0x072F, 0x2200, 0x0206 }, /* ACS ACR122U-WB-R */
120            { 0x08C3, 0x0402, 0x5000 },     /* Precise Biometrics Precise 200 MC */
121            { 0x08C3, 0x0401, 0x5000 },     /* Precise Biometrics Precise 250 MC */
122            { 0x0B0C, 0x0050, 0x0101 },     /* Todos Argos Mini II */
123    
124            /* the firmware version is not correct since I do not have received a
125             * working reader yet */
126    #ifndef O2MICRO_OZ776_PATCH
127            { 0x0b97, 0x7762, 0x0111 },     /* Oz776S */
128    #endif
129  };  };
130    
131  /* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */  /* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
# Line 128  unsigned int SerialCustomDataRates[] = { Line 139  unsigned int SerialCustomDataRates[] = {
139   ****************************************************************************/   ****************************************************************************/
140  status_t OpenUSB(unsigned int reader_index, /*@unused@*/ int Channel)  status_t OpenUSB(unsigned int reader_index, /*@unused@*/ int Channel)
141  {  {
142            (void)Channel;
143    
144          return OpenUSBByName(reader_index, NULL);          return OpenUSBByName(reader_index, NULL);
145  } /* OpenUSB */  } /* OpenUSB */
146    
# Line 139  status_t OpenUSB(unsigned int reader_ind Line 152  status_t OpenUSB(unsigned int reader_ind
152   ****************************************************************************/   ****************************************************************************/
153  status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)  status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
154  {  {
         static struct usb_bus *busses = NULL;  
155          int alias = 0;          int alias = 0;
156          struct usb_bus *bus;          struct libusb_device_handle *dev_handle;
         struct usb_dev_handle *dev_handle;  
157          char keyValue[TOKEN_MAX_VALUE_SIZE];          char keyValue[TOKEN_MAX_VALUE_SIZE];
158          unsigned int vendorID, productID;          unsigned int vendorID, productID;
159          char infofile[FILENAME_MAX];          char infofile[FILENAME_MAX];
160    #ifndef __APPLE__
161          unsigned int device_vendor, device_product;          unsigned int device_vendor, device_product;
162          char *dirname = NULL, *filename = NULL;  #endif
163            int interface_number = -1;
164            int i;
165          static int previous_reader_index = -1;          static int previous_reader_index = -1;
166            libusb_device **devs, *dev;
167            ssize_t cnt;
168    
169          DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);          DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);
170    
171    #ifndef __APPLE__
172          /* device name specified */          /* device name specified */
173          if (device)          if (device)
174          {          {
175                    char *dirname;
176    
177                  /* format: usb:%04x/%04x, vendor, product */                  /* format: usb:%04x/%04x, vendor, product */
178                  if (strncmp("usb:", device, 4) != 0)                  if (strncmp("usb:", device, 4) != 0)
179                  {                  {
# Line 169  status_t OpenUSBByName(unsigned int read Line 188  status_t OpenUSBByName(unsigned int read
188                          return STATUS_UNSUCCESSFUL;                          return STATUS_UNSUCCESSFUL;
189                  }                  }
190    
191                  /* format usb:%04x/%04x:libusb:%s                  /* format usb:%04x/%04x:libhal:%s
192                   * with %s set to %s:%s, dirname, filename */                   * with %s set to
193                  if ((dirname = strstr(device, "libusb:")) != NULL)                   * /org/freedesktop/Hal/devices/usb_device_VID_PID_SERIAL_ifX
194                     * VID is VendorID
195                     * PID is ProductID
196                     * SERIAL is device serial number
197                     * X is the interface number
198                     */
199                    if ((dirname = strstr(device, "libhal:")) != NULL)
200                  {                  {
201                          /* dirname points to the first char after libusb: */                          const char *p;
                         dirname += strlen("libusb:");  
202    
203                          /* search the : (separation) char */  #define HAL_HEADER "usb_device_"
                         filename = strchr(dirname, ':');  
204    
205                          if (filename)                          /* parse the hal string */
206                            if (
207                                    /* search the last '/' char */
208                                    (p = strrchr(dirname, '/'))
209    
210                                    /* if the string starts with "usb_device_" we continue */
211                                    && (0 == strncmp(++p, HAL_HEADER, sizeof(HAL_HEADER)-1))
212                                    /* skip the HAL header */
213                                    && (p += sizeof(HAL_HEADER)-1)
214    
215                                    /* search the last '_' */
216                                    && (p = strrchr(++p, '_'))
217                                    && (0 == strncmp(++p, "if", 2))
218                               )
219                          {                          {
220                                  /* end the dirname string */                                  /* convert the interface number */
221                                  *filename = '\0';                                  interface_number = atoi(p+2);
   
                                 /* filename points to the first char after : */  
                                 filename++;  
222                          }                          }
223                          else                          else
224                          {                                  DEBUG_CRITICAL2("can't parse using libhal scheme: %s", device);
                                 /* parse failed */  
                                 dirname = NULL;  
   
                                 DEBUG_CRITICAL2("can't parse using libusb scheme: %s", device);  
                         }  
225                  }                  }
226          }          }
227    #endif
228    
229          if (busses == NULL)          libusb_init(NULL);
                 usb_init();  
   
         usb_find_busses();  
         usb_find_devices();  
   
         busses = usb_get_busses();  
   
         if (busses == NULL)  
         {  
                 DEBUG_CRITICAL("No USB busses found");  
                 return STATUS_UNSUCCESSFUL;  
         }  
230    
231          /* is the reader_index already used? */          /* is the reader_index already used? */
232          if (usbDevice[reader_index].handle != NULL)          if (usbDevice[reader_index].dev_handle != NULL)
233          {          {
234                  DEBUG_CRITICAL2("USB driver with index %X already in use",                  DEBUG_CRITICAL2("USB driver with index %X already in use",
235                          reader_index);                          reader_index);
# Line 220  status_t OpenUSBByName(unsigned int read Line 237  status_t OpenUSBByName(unsigned int read
237          }          }
238    
239          /* Info.plist full patch filename */          /* Info.plist full patch filename */
240          snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",          (void)snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
241                  PCSCLITE_HP_DROPDIR, BUNDLE);                  PCSCLITE_HP_DROPDIR, BUNDLE);
242    
243          /* general driver info */          /* general driver info */
# Line 251  status_t OpenUSBByName(unsigned int read Line 268  status_t OpenUSBByName(unsigned int read
268          for (; vendorID--;)          for (; vendorID--;)
269                  alias ^= keyValue[vendorID];                  alias ^= keyValue[vendorID];
270    
271            cnt = libusb_get_device_list(NULL, &devs);
272            if (cnt < 0)
273            {
274                    (void)printf("libusb_get_device_list() failed\n");
275                    return STATUS_UNSUCCESSFUL;
276            }
277    
278          /* for any supported reader */          /* for any supported reader */
279          while (LTPBundleFindValueWithKey(infofile, PCSCLITE_MANUKEY_NAME, keyValue, alias) == 0)          while (LTPBundleFindValueWithKey(infofile, PCSCLITE_MANUKEY_NAME, keyValue, alias) == 0)
280          {          {
# Line 266  status_t OpenUSBByName(unsigned int read Line 290  status_t OpenUSBByName(unsigned int read
290                  /* go to next supported reader for next round */                  /* go to next supported reader for next round */
291                  alias++;                  alias++;
292    
293    #ifndef __APPLE__
294                  /* the device was specified but is not the one we are trying to find */                  /* the device was specified but is not the one we are trying to find */
295                  if (device                  if (device
296                          && (vendorID != device_vendor || productID != device_product))                          && (vendorID != device_vendor || productID != device_product))
297                          continue;                          continue;
298    #else
299                    /* Leopard puts the friendlyname in the device argument */
300                    if (device && strcmp(device, keyValue))
301                            continue;
302    #endif
303    
304                  /* on any USB buses */                  /* for every device */
305                  for (bus = busses; bus; bus = bus->next)                  i = 0;
306                    while ((dev = devs[i++]) != NULL)
307                  {                  {
308                          struct usb_device *dev;                          struct libusb_device_descriptor desc;
309                            struct libusb_config_descriptor *config_desc;
310                            uint8_t bus_number = libusb_get_bus_number(dev);
311                            uint8_t device_address = libusb_get_device_address(dev);
312    
313                          /* any device on this bus */                          int r = libusb_get_device_descriptor(dev, &desc);
314                          for (dev = bus->devices; dev; dev = dev->next)                          if (r < 0)
315                          {                          {
316                                  /* device defined by name? */                                  DEBUG_INFO3("failed to get device descriptor for %d/%d",
317                                  if (dirname && (strcmp(dirname, bus->dirname)                                          bus_number, device_address);
318                                          || strcmp(filename, dev->filename)))                                  continue;
319                                          continue;                          }
320    
321                            if (desc.idVendor == vendorID && desc.idProduct == productID)
322                            {
323                                    int already_used;
324                                    const struct libusb_interface *usb_interface = NULL;
325                                    int interface;
326                                    int num = 0;
327    
328    #ifdef USE_COMPOSITE_AS_MULTISLOT
329                                    static int static_interface = 1;
330    
                                 if (dev->descriptor.idVendor == vendorID  
                                         && dev->descriptor.idProduct == productID)  
331                                  {                                  {
332                                          int r, already_used;                                          /* simulate a composite device as when libhal is
333                                          struct usb_interface *usb_interface = NULL;                                           * used */
334                                          int interface;                                          int readerID = (vendorID << 16) + productID;
335    
336                                          /* is it already opened? */                                          if ((GEMALTOPROXDU == readerID)
337                                          already_used = FALSE;                                                  || (GEMALTOPROXSU == readerID))
   
                                         DEBUG_COMM3("Checking device: %s/%s",  
                                                 bus->dirname, dev->filename);  
                                         for (r=0; r<CCID_DRIVER_MAX_READERS; r++)  
338                                          {                                          {
339                                                  if (usbDevice[r].handle)                                                          /*
340                                                  {                                                           * We can't talk to the two CCID interfaces
341                                                          /* same busname, same filename */                                                           * at the same time (the reader enters a
342                                                          if (strcmp(usbDevice[r].dirname, bus->dirname) == 0 && strcmp(usbDevice[r].filename, dev->filename) == 0)                                                           * dead lock). So we simulate a multi slot
343                                                                  already_used = TRUE;                                                           * reader. By default multi slot readers
344                                                  }                                                           * can't use the slots at the same time. See
345                                                             * TAG_IFD_SLOT_THREAD_SAFE
346                                                             *
347                                                             * One side effect is that the two readers
348                                                             * are seen by pcscd as one reader so the
349                                                             * interface name is the same for the two.
350                                                             *
351                    * So we have:
352                    * 0: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 00
353                    * 1: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 01
354                    * instead of
355                    * 0: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 00
356                    * 1: Gemalto Prox-DU [Prox-DU Contactless_09A00795] (09A00795) 01 00
357                                                             */
358    
359                                                    /* the CCID interfaces are 1 and 2 */
360                                                    interface_number = static_interface;
361                                          }                                          }
362                                    }
363    #endif
364                                    /* is it already opened? */
365                                    already_used = FALSE;
366    
367                                          /* this reader is already managed by us */                                  DEBUG_COMM3("Checking device: %d/%d",
368                                          if (already_used)                                          bus_number, device_address);
369                                    for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
370                                    {
371                                            if (usbDevice[r].dev_handle)
372                                          {                                          {
373                                                  if ((previous_reader_index != -1)                                                  /* same bus, same address */
374                                                          && usbDevice[previous_reader_index].handle                                                  if (usbDevice[r].bus_number == bus_number
375                                                          && (strcmp(usbDevice[previous_reader_index].dirname, bus->dirname)  == 0)                                                          && usbDevice[r].device_address == device_address)
376                                                          && (strcmp(usbDevice[previous_reader_index].filename, dev->filename) == 0)                                                          already_used = TRUE;
377                                                          && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)                                          }
378                                    }
379    
380                                    /* this reader is already managed by us */
381                                    if (already_used)
382                                    {
383                                            if ((previous_reader_index != -1)
384                                                    && usbDevice[previous_reader_index].dev_handle
385                                                    && (usbDevice[previous_reader_index].bus_number == bus_number)
386                                                    && (usbDevice[previous_reader_index].device_address == device_address)
387                                                    && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)
388                                            {
389                                                    /* we reuse the same device
390                                                     * and the reader is multi-slot */
391                                                    usbDevice[reader_index] = usbDevice[previous_reader_index];
392                                                    /* the other slots do not have the same data rates */
393                                                    if ((GEMCOREPOSPRO == usbDevice[reader_index].ccid.readerID)
394                                                            || (GEMCORESIMPRO == usbDevice[reader_index].ccid.readerID))
395                                                  {                                                  {
396                                                          /* we reuse the same device                                                          usbDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates;
397                                                           * and the reader is multi-slot */                                                          usbDevice[reader_index].ccid.dwMaxDataRate = 125000;
                                                         usbDevice[reader_index] = usbDevice[previous_reader_index];  
                                                         /* the other slots do not have the same data rates */  
                                                         if ((GEMCOREPOSPRO == usbDevice[reader_index].ccid.readerID)  
                                                                 || (GEMCORESIMPRO == usbDevice[reader_index].ccid.readerID))  
                                                         {  
                                                                 usbDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates;  
                                                                 usbDevice[reader_index].ccid.dwMaxDataRate = 125000;  
                                                         }  
   
                                                         *usbDevice[reader_index].nb_opened_slots += 1;  
                                                         usbDevice[reader_index].ccid.bCurrentSlotIndex++;  
                                                         DEBUG_INFO2("Opening slot: %d",  
                                                                 usbDevice[reader_index].ccid.bCurrentSlotIndex);  
                                                         goto end;  
398                                                  }                                                  }
399                                                  else  
400                                                    *usbDevice[reader_index].nb_opened_slots += 1;
401                                                    usbDevice[reader_index].ccid.bCurrentSlotIndex++;
402                                                    usbDevice[reader_index].ccid.dwSlotStatus =
403                                                            IFD_ICC_PRESENT;
404                                                    DEBUG_INFO2("Opening slot: %d",
405                                                            usbDevice[reader_index].ccid.bCurrentSlotIndex);
406                                                    goto end;
407                                            }
408                                            else
409                                            {
410                                                    /* if an interface number is given by HAL we
411                                                     * continue with this device. */
412                                                    if (-1 == interface_number)
413                                                  {                                                  {
414                                                          DEBUG_INFO3("USB device %s/%s already in use."                                                          DEBUG_INFO3("USB device %d/%d already in use."
415                                                                  " Checking next one.",                                                                  " Checking next one.",
416                                                                  bus->dirname, dev->filename);                                                                  bus_number, device_address);
417                                                            continue;
418                                                  }                                                  }
   
                                                 continue;  
419                                          }                                          }
420                                    }
421    
422                                          DEBUG_COMM3("Trying to open USB bus/device: %s/%s",                                  DEBUG_COMM3("Trying to open USB bus/device: %d/%d",
423                                                   bus->dirname, dev->filename);                                          bus_number, device_address);
424    
425                                          dev_handle = usb_open(dev);                                  r = libusb_open(dev, &dev_handle);
426                                          if (dev_handle == NULL)                                  if (r < 0)
427                                          {                                  {
428                                                  DEBUG_CRITICAL4("Can't usb_open(%s/%s): %s",                                          DEBUG_CRITICAL4("Can't libusb_open(%d/%d): %d",
429                                                          bus->dirname, dev->filename, strerror(errno));                                                  bus_number, device_address, r);
430    
431                                                  continue;                                          continue;
432                                          }                                  }
433    
434                                          /* now we found a free reader and we try to use it */  again:
435                                          if (dev->config == NULL)                                  r = libusb_get_active_config_descriptor(dev, &config_desc);
436                                          {                                  if (r < 0)
437                                                  usb_close(dev_handle);                                  {
438                                                  DEBUG_CRITICAL3("No dev->config found for %s/%s",                                          (void)libusb_close(dev_handle);
439                                                           bus->dirname, dev->filename);                                          DEBUG_CRITICAL3("Can't get config descriptor on %d/%d",
440                                                  return STATUS_UNSUCCESSFUL;                                                  bus_number, device_address);
441                                          }                                          continue;
442                                    }
443    
444                                          usb_interface = get_ccid_usb_interface(dev);                                  usb_interface = get_ccid_usb_interface(config_desc, &num);
445                                          if (usb_interface == NULL)                                  if (usb_interface == NULL)
446                                          {                                  {
447                                                  usb_close(dev_handle);                                          (void)libusb_close(dev_handle);
448                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",                                          if (0 == num)
449                                                          bus->dirname, dev->filename);                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %d/%d",
450                                                  return STATUS_UNSUCCESSFUL;                                                          bus_number, device_address);
451                                          }                                          interface_number = -1;
452                                            continue;
453                                    }
454    
455                                          if (usb_interface->altsetting->extralen != 54)                                  if (usb_interface->altsetting->extra_length != 54)
456                                          {                                  {
457                                                  usb_close(dev_handle);                                          (void)libusb_close(dev_handle);
458                                                  DEBUG_CRITICAL4("Extra field for %s/%s has a wrong length: %d", bus->dirname, dev->filename, usb_interface->altsetting->extralen);                                          DEBUG_CRITICAL4("Extra field for %d/%d has a wrong length: %d",
459                                                  return STATUS_UNSUCCESSFUL;                                                  bus_number, device_address,
460                                          }                                                  usb_interface->altsetting->extra_length);
461                                            return STATUS_UNSUCCESSFUL;
462                                    }
463    
464                                          interface = usb_interface->altsetting->bInterfaceNumber;                                  interface = usb_interface->altsetting->bInterfaceNumber;
465                                          if (usb_claim_interface(dev_handle, interface) < 0)                                  if (interface_number >= 0 && interface != interface_number)
466                                          {                                  {
467                                                  usb_close(dev_handle);                                          /* an interface was specified and it is not the
468                                                  DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",                                           * current one */
469                                                          bus->dirname, dev->filename, strerror(errno));                                          DEBUG_INFO3("Wrong interface for USB device %d/%d."
470                                                  return STATUS_UNSUCCESSFUL;                                                  " Checking next one.", bus_number, device_address);
                                         }  
471    
472                                          DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",                                          /* check for another CCID interface on the same device */
473                                                  dev->descriptor.idVendor,                                          num++;
                                                 dev->descriptor.idProduct, keyValue);  
                                         DEBUG_INFO3("Using USB bus/device: %s/%s",  
                                                  bus->dirname, dev->filename);  
474    
475                                          /* check for firmware bugs */                                          goto again;
476                                          if (ccid_check_firmware(dev))                                  }
477                                          {  
478                                                  usb_close(dev_handle);                                  r = libusb_claim_interface(dev_handle, interface);
479                                                  return STATUS_UNSUCCESSFUL;                                  if (r < 0)
480                                          }                                  {
481                                            (void)libusb_close(dev_handle);
482                                            DEBUG_CRITICAL4("Can't claim interface %d/%d: %d",
483                                                    bus_number, device_address, r);
484                                            interface_number = -1;
485                                            continue;
486                                    }
487    
488                                          /* Get Endpoints values*/                                  DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",
489                                          get_end_points(dev, &usbDevice[reader_index]);                                          desc.idVendor, desc.idProduct, keyValue);
490                                    DEBUG_INFO3("Using USB bus/device: %d/%d",
491                                            bus_number, device_address);
492    
493                                          /* store device information */                                  /* check for firmware bugs */
494                                          usbDevice[reader_index].handle = dev_handle;                                  if (ccid_check_firmware(&desc))
495                                          usbDevice[reader_index].dirname = strdup(bus->dirname);                                  {
496                                          usbDevice[reader_index].filename = strdup(dev->filename);                                          (void)libusb_close(dev_handle);
497                                          usbDevice[reader_index].interface = interface;                                          return STATUS_UNSUCCESSFUL;
                                         usbDevice[reader_index].real_nb_opened_slots = 1;  
                                         usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;  
   
                                         /* CCID common informations */  
                                         usbDevice[reader_index].ccid.real_bSeq = 0;  
                                         usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq;  
                                         usbDevice[reader_index].ccid.readerID =  
                                                 (dev->descriptor.idVendor << 16) +  
                                                 dev->descriptor.idProduct;  
                                         usbDevice[reader_index].ccid.dwFeatures = dw2i(usb_interface->altsetting->extra, 40);  
                                         usbDevice[reader_index].ccid.bPINSupport = usb_interface->altsetting->extra[52];  
                                         usbDevice[reader_index].ccid.dwMaxCCIDMessageLength = dw2i(usb_interface->altsetting->extra, 44);  
                                         usbDevice[reader_index].ccid.dwMaxIFSD = dw2i(usb_interface->altsetting->extra, 28);  
                                         usbDevice[reader_index].ccid.dwDefaultClock = dw2i(usb_interface->altsetting->extra, 10);  
                                         usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);  
                                         usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];  
                                         usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;  
                                         usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;  
                                         usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index, dev);  
                                         goto end;  
498                                  }                                  }
499    
500    #ifdef USE_COMPOSITE_AS_MULTISLOT
501                                    /* use the next interface for the next "slot" */
502                                    static_interface++;
503    
504                                    /* reset for a next reader */
505                                    if (static_interface > 2)
506                                            static_interface = 1;
507    #endif
508    
509                                    /* Get Endpoints values*/
510                                    (void)get_end_points(config_desc, &usbDevice[reader_index], num);
511    
512                                    /* store device information */
513                                    usbDevice[reader_index].dev_handle = dev_handle;
514                                    usbDevice[reader_index].bus_number = bus_number;
515                                    usbDevice[reader_index].device_address = device_address;
516                                    usbDevice[reader_index].interface = interface;
517                                    usbDevice[reader_index].real_nb_opened_slots = 1;
518                                    usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
519    
520                                    /* CCID common informations */
521                                    usbDevice[reader_index].ccid.real_bSeq = 0;
522                                    usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq;
523                                    usbDevice[reader_index].ccid.readerID =
524                                            (desc.idVendor << 16) + desc.idProduct;
525                                    usbDevice[reader_index].ccid.dwFeatures = dw2i(usb_interface->altsetting->extra, 40);
526                                    usbDevice[reader_index].ccid.wLcdLayout =
527                                            (usb_interface->altsetting->extra[51] << 8) +
528                                            usb_interface->altsetting->extra[50];
529                                    usbDevice[reader_index].ccid.bPINSupport = usb_interface->altsetting->extra[52];
530                                    usbDevice[reader_index].ccid.dwMaxCCIDMessageLength = dw2i(usb_interface->altsetting->extra, 44);
531                                    usbDevice[reader_index].ccid.dwMaxIFSD = dw2i(usb_interface->altsetting->extra, 28);
532                                    usbDevice[reader_index].ccid.dwDefaultClock = dw2i(usb_interface->altsetting->extra, 10);
533                                    usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);
534                                    usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];
535                                    usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
536                                    usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
537                                    usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index, config_desc, num);
538                                    usbDevice[reader_index].ccid.bInterfaceProtocol = usb_interface->altsetting->bInterfaceProtocol;
539                                    usbDevice[reader_index].ccid.bNumEndpoints = usb_interface->altsetting->bNumEndpoints;
540                                    usbDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT;
541                                    usbDevice[reader_index].ccid.bVoltageSupport = usb_interface->altsetting->extra[5];
542                                    usbDevice[reader_index].ccid.sIFD_serial_number = NULL;
543                                    if (desc.iSerialNumber)
544                                    {
545                                            unsigned char serial[128];
546                                            int ret;
547    
548                                            ret = libusb_get_string_descriptor_ascii(dev_handle,
549                                                            desc.iSerialNumber, serial,
550                                                            sizeof(serial));
551                                            if (ret > 0)
552                                                    usbDevice[reader_index].ccid.sIFD_serial_number
553                                                            = strdup((char *)serial);
554                                    }
555                                    goto end;
556                          }                          }
557                  }                  }
558          }          }
559  end:  end:
560          if (usbDevice[reader_index].handle == NULL)          if (usbDevice[reader_index].dev_handle == NULL)
561                  return STATUS_UNSUCCESSFUL;                  return STATUS_NO_SUCH_DEVICE;
562    
563          /* memorise the current reader_index so we can detect          /* memorise the current reader_index so we can detect
564           * a new OpenUSBByName on a multi slot reader */           * a new OpenUSBByName on a multi slot reader */
# Line 454  status_t WriteUSB(unsigned int reader_in Line 577  status_t WriteUSB(unsigned int reader_in
577          unsigned char *buffer)          unsigned char *buffer)
578  {  {
579          int rv;          int rv;
580            int actual_length;
581          char debug_header[] = "-> 121234 ";          char debug_header[] = "-> 121234 ";
582    
583          sprintf(debug_header, "-> %06X ", (int)reader_index);          (void)snprintf(debug_header, sizeof(debug_header), "-> %06X ",
584                    (int)reader_index);
585    
586          DEBUG_XXD(debug_header, buffer, length);          DEBUG_XXD(debug_header, buffer, length);
587    
588          rv = usb_bulk_write(usbDevice[reader_index].handle,          rv = libusb_bulk_transfer(usbDevice[reader_index].dev_handle,
589                  usbDevice[reader_index].bulk_out, (char *)buffer, length,                  usbDevice[reader_index].bulk_out, buffer, length,
590                  USB_WRITE_TIMEOUT);                  &actual_length, USB_WRITE_TIMEOUT);
591    
592          if (rv < 0)          if (rv < 0)
593          {          {
594                  DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",                  DEBUG_CRITICAL4("libusb_bulk_write(%d/%d): %s",
595                          usbDevice[reader_index].dirname, usbDevice[reader_index].filename,                          usbDevice[reader_index].bus_number,
596                          strerror(errno));                          usbDevice[reader_index].device_address, strerror(errno));
597    
598                  if (ENODEV == errno)                  if (ENODEV == errno)
599                          return STATUS_NO_SUCH_DEVICE;                          return STATUS_NO_SUCH_DEVICE;
# Line 489  status_t ReadUSB(unsigned int reader_ind Line 614  status_t ReadUSB(unsigned int reader_ind
614          unsigned char *buffer)          unsigned char *buffer)
615  {  {
616          int rv;          int rv;
617            int actual_length;
618          char debug_header[] = "<- 121234 ";          char debug_header[] = "<- 121234 ";
619          _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);          _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
620            int duplicate_frame = 0;
621    
622  read_again:  read_again:
623          sprintf(debug_header, "<- %06X ", (int)reader_index);          (void)snprintf(debug_header, sizeof(debug_header), "<- %06X ",
624                    (int)reader_index);
625    
626          rv = usb_bulk_read(usbDevice[reader_index].handle,          rv = libusb_bulk_transfer(usbDevice[reader_index].dev_handle,
627                  usbDevice[reader_index].bulk_in, (char *)buffer, *length,                  usbDevice[reader_index].bulk_in, buffer, *length,
628                  usbDevice[reader_index].ccid.readTimeout * 1000);                  &actual_length, usbDevice[reader_index].ccid.readTimeout);
629    
630          if (rv < 0)          if (rv < 0)
631          {          {
632                  *length = 0;                  *length = 0;
633                  DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",                  DEBUG_CRITICAL4("libusb_bulk_read(%d/%d): %s",
634                          usbDevice[reader_index].dirname, usbDevice[reader_index].filename,                          usbDevice[reader_index].bus_number,
635                          strerror(errno));                          usbDevice[reader_index].device_address, strerror(errno));
636    
637                  if (ENODEV == errno)                  if (ENODEV == errno)
638                          return STATUS_NO_SUCH_DEVICE;                          return STATUS_NO_SUCH_DEVICE;
# Line 512  read_again: Line 640  read_again:
640                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
641          }          }
642    
643          *length = rv;          *length = actual_length;
644    
645          DEBUG_XXD(debug_header, buffer, *length);          DEBUG_XXD(debug_header, buffer, *length);
646    
# Line 520  read_again: Line 648  read_again:
648          if ((*length >= BSEQ_OFFSET)          if ((*length >= BSEQ_OFFSET)
649                  && (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1))                  && (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1))
650          {          {
651                    duplicate_frame++;
652                    if (duplicate_frame > 10)
653                    {
654                            DEBUG_CRITICAL("Too many duplicate frame detected");
655                            return STATUS_UNSUCCESSFUL;
656                    }
657                  DEBUG_INFO("Duplicate frame detected");                  DEBUG_INFO("Duplicate frame detected");
658                  goto read_again;                  goto read_again;
659          }          }
# Line 536  read_again: Line 670  read_again:
670  status_t CloseUSB(unsigned int reader_index)  status_t CloseUSB(unsigned int reader_index)
671  {  {
672          /* device not opened */          /* device not opened */
673          if (usbDevice[reader_index].handle == NULL)          if (usbDevice[reader_index].dev_handle == NULL)
674                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
675    
676          DEBUG_COMM3("Closing USB device: %s/%s",          DEBUG_COMM3("Closing USB device: %d/%d",
677                  usbDevice[reader_index].dirname,                  usbDevice[reader_index].bus_number,
678                  usbDevice[reader_index].filename);                  usbDevice[reader_index].device_address);
679    
680          if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates          if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates
681                  && (usbDevice[reader_index].ccid.bCurrentSlotIndex == 0))                  && (usbDevice[reader_index].ccid.bCurrentSlotIndex == 0))
# Line 560  status_t CloseUSB(unsigned int reader_in Line 694  status_t CloseUSB(unsigned int reader_in
694    
695                  /* reset so that bSeq starts at 0 again */                  /* reset so that bSeq starts at 0 again */
696                  if (DriverOptions & DRIVER_OPTION_RESET_ON_CLOSE)                  if (DriverOptions & DRIVER_OPTION_RESET_ON_CLOSE)
697                          usb_reset(usbDevice[reader_index].handle);                          (void)libusb_reset_device(usbDevice[reader_index].dev_handle);
698    
699                  usb_release_interface(usbDevice[reader_index].handle,                  (void)libusb_release_interface(usbDevice[reader_index].dev_handle,
700                          usbDevice[reader_index].interface);                          usbDevice[reader_index].interface);
701                  usb_close(usbDevice[reader_index].handle);                  (void)libusb_close(usbDevice[reader_index].dev_handle);
   
                 free(usbDevice[reader_index].dirname);  
                 free(usbDevice[reader_index].filename);  
702          }          }
703    
704          /* mark the resource unused */          /* mark the resource unused */
705          usbDevice[reader_index].handle = NULL;          usbDevice[reader_index].dev_handle = NULL;
         usbDevice[reader_index].dirname = NULL;  
         usbDevice[reader_index].filename = NULL;  
706          usbDevice[reader_index].interface = 0;          usbDevice[reader_index].interface = 0;
707    
708            if (usbDevice[reader_index].ccid.sIFD_serial_number)
709                    free(usbDevice[reader_index].ccid.sIFD_serial_number);
710    
711          return STATUS_SUCCESS;          return STATUS_SUCCESS;
712  } /* CloseUSB */  } /* CloseUSB */
713    
# Line 596  _ccid_descriptor *get_ccid_descriptor(un Line 728  _ccid_descriptor *get_ccid_descriptor(un
728   *                                      get_end_points   *                                      get_end_points
729   *   *
730   ****************************************************************************/   ****************************************************************************/
731  static int get_end_points(struct usb_device *dev, _usbDevice *usbdevice)  static int get_end_points(struct libusb_config_descriptor *desc,
732            _usbDevice *usbdevice, int num)
733  {  {
734          int i;          int i;
735          int bEndpointAddress;          int bEndpointAddress;
736          struct usb_interface *usb_interface = get_ccid_usb_interface(dev);          const struct libusb_interface *usb_interface;
737    
738            usb_interface = get_ccid_usb_interface(desc, &num);
739    
740          /*          /*
741           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
742           */           */
743          for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)          for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
744          {          {
745                  if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)                  /* interrupt end point (if available) */
746                    if (usb_interface->altsetting->endpoint[i].bmAttributes
747                            == LIBUSB_TRANSFER_TYPE_INTERRUPT)
748                    {
749                            usbdevice->interrupt =
750                                    usb_interface->altsetting->endpoint[i].bEndpointAddress;
751                            continue;
752                    }
753    
754                    if (usb_interface->altsetting->endpoint[i].bmAttributes
755                            != LIBUSB_TRANSFER_TYPE_BULK)
756                          continue;                          continue;
757    
758                  bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;                  bEndpointAddress =
759                            usb_interface->altsetting->endpoint[i].bEndpointAddress;
760    
761                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)                  if ((bEndpointAddress & LIBUSB_TRANSFER_TYPE_MASK)
762                            == LIBUSB_ENDPOINT_IN)
763                          usbdevice->bulk_in = bEndpointAddress;                          usbdevice->bulk_in = bEndpointAddress;
764    
765                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)                  if ((bEndpointAddress & LIBUSB_TRANSFER_TYPE_MASK)
766                            == LIBUSB_ENDPOINT_OUT)
767                          usbdevice->bulk_out = bEndpointAddress;                          usbdevice->bulk_out = bEndpointAddress;
768          }          }
769    
# Line 628  static int get_end_points(struct usb_dev Line 776  static int get_end_points(struct usb_dev
776   *                                      get_ccid_usb_interface   *                                      get_ccid_usb_interface
777   *   *
778   ****************************************************************************/   ****************************************************************************/
779  /*@null@*/ EXTERNAL struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)  /*@null@*/ EXTERNAL const struct libusb_interface * get_ccid_usb_interface(
780            struct libusb_config_descriptor *desc, int *num)
781  {  {
782          struct usb_interface *usb_interface = NULL;          const struct libusb_interface *usb_interface = NULL;
783          int i;          int i;
784    #ifdef O2MICRO_OZ776_PATCH
785            int readerID;
786    #endif
787    
788          /* if multiple interfaces use the first one with CCID class type */          /* if multiple interfaces use the first one with CCID class type */
789          for (i=0; i<dev->config->bNumInterfaces; i++)          for (i = *num; i < desc->bNumInterfaces; i++)
790          {          {
791                  /* CCID Class? */                  /* CCID Class? */
792                  if (dev->config->interface[i].altsetting->bInterfaceClass == 0xb                  if (desc->interface[i].altsetting->bInterfaceClass == 0xb
793  #ifdef ALLOW_PROPRIETARY_CLASS  #ifdef ALLOW_PROPRIETARY_CLASS
794                          || dev->config->interface[i].altsetting->bInterfaceClass == 0xff                          || desc->interface[i].altsetting->bInterfaceClass == 0xff
795  #endif  #endif
796                          )                          )
797                  {                  {
798                          usb_interface = &dev->config->interface[i];                          usb_interface = &desc->interface[i];
799                            /* store the interface number for further reference */
800                            *num = i;
801                          break;                          break;
802                  }                  }
803          }          }
804    
805  #ifdef O2MICRO_OZ776_PATCH  #ifdef O2MICRO_OZ776_PATCH
806            readerID = (dev->descriptor.idVendor << 16) + dev->descriptor.idProduct;
807          if (usb_interface != NULL          if (usb_interface != NULL
808                  && (OZ776 == (dev->descriptor.idVendor << 16)                  && ((OZ776 == readerID) || (OZ776_7772 == readerID)
809                  + dev->descriptor.idProduct)                  || (REINER_SCT == readerID) || (BLUDRIVEII_CCID == readerID))
810                  && (0 == usb_interface->altsetting->extralen)) /* this is the bug */                  && (0 == usb_interface->altsetting->extra_length)) /* this is the bug */
811          {          {
812                  for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)                  int j;
813                    for (j=0; j<usb_interface->altsetting->bNumEndpoints; j++)
814                  {                  {
815                          /* find the extra[] array */                          /* find the extra[] array */
816                          if (54 == usb_interface->altsetting->endpoint[i].extralen)                          if (54 == usb_interface->altsetting->endpoint[j].extra_length)
817                          {                          {
818                                  /* get the extra[] from the endpoint */                                  /* get the extra[] from the endpoint */
819                                  usb_interface->altsetting->extralen = 54;                                  usb_interface->altsetting->extra_length = 54;
820                                  usb_interface->altsetting->extra =                                  usb_interface->altsetting->extra =
821                                          usb_interface->altsetting->endpoint[i].extra;                                          usb_interface->altsetting->endpoint[j].extra;
822                                    /* avoid double free on close */
823                                    usb_interface->altsetting->endpoint[j].extra = NULL;
824                                    usb_interface->altsetting->endpoint[j].extra_length = 0;
825                                  break;                                  break;
826                          }                          }
827                  }                  }
# Line 678  static int get_end_points(struct usb_dev Line 837  static int get_end_points(struct usb_dev
837   *                                      ccid_check_firmware   *                                      ccid_check_firmware
838   *   *
839   ****************************************************************************/   ****************************************************************************/
840  int ccid_check_firmware(struct usb_device *dev)  int ccid_check_firmware(struct libusb_device_descriptor *desc)
841  {  {
842          int i;          unsigned int i;
843    
844          for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)          for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)
845          {          {
846                  if (dev->descriptor.idVendor != Bogus_firmwares[i].vendor)                  if (desc->idVendor != Bogus_firmwares[i].vendor)
847                                  continue;                          continue;
848    
849                  if (dev->descriptor.idProduct != Bogus_firmwares[i].product)                  if (desc->idProduct != Bogus_firmwares[i].product)
850                          continue;                          continue;
851    
852                  /* firmware too old and buggy */                  /* firmware too old and buggy */
853                  if (dev->descriptor.bcdDevice < Bogus_firmwares[i].firmware)                  if (desc->bcdDevice < Bogus_firmwares[i].firmware)
854                  {                  {
855                          if (DriverOptions & DRIVER_OPTION_USE_BOGUS_FIRMWARE)                          if (DriverOptions & DRIVER_OPTION_USE_BOGUS_FIRMWARE)
856                          {                          {
857                                  DEBUG_INFO3("Firmware (%X.%02X) is bogus! but you choosed to use it",                                  DEBUG_INFO3("Firmware (%X.%02X) is bogus! but you choosed to use it",
858                                          dev->descriptor.bcdDevice >> 8,                                          desc->bcdDevice >> 8, desc->bcdDevice & 0xFF);
                                         dev->descriptor.bcdDevice & 0xFF);  
859                                  return FALSE;                                  return FALSE;
860                          }                          }
861                          else                          else
862                          {                          {
863                                  DEBUG_CRITICAL3("Firmware (%X.%02X) is bogus! Upgrade the reader firmware or get a new reader.",                                  DEBUG_CRITICAL3("Firmware (%X.%02X) is bogus! Upgrade the reader firmware or get a new reader.",
864                                          dev->descriptor.bcdDevice >> 8,                                          desc->bcdDevice >> 8, desc->bcdDevice & 0xFF);
                                         dev->descriptor.bcdDevice & 0xFF);  
865                                  return TRUE;                                  return TRUE;
866                          }                          }
867                  }                  }
# Line 714  int ccid_check_firmware(struct usb_devic Line 871  int ccid_check_firmware(struct usb_devic
871          return FALSE;          return FALSE;
872  } /* ccid_check_firmware */  } /* ccid_check_firmware */
873    
874    
875  /*****************************************************************************  /*****************************************************************************
876   *   *
877   *                                      get_data_rates   *                                      get_data_rates
878   *   *
879   ****************************************************************************/   ****************************************************************************/
880  static unsigned int *get_data_rates(unsigned int reader_index,  static unsigned int *get_data_rates(unsigned int reader_index,
881          struct usb_device *dev)          struct libusb_config_descriptor *desc, int num)
882  {  {
883          int n, i, len;          int n, i, len;
884          unsigned char buffer[256*sizeof(int)];  /* maximum is 256 records */          unsigned char buffer[256*sizeof(int)];  /* maximum is 256 records */
# Line 736  static unsigned int *get_data_rates(unsi Line 894  static unsigned int *get_data_rates(unsi
894          /* we got an error? */          /* we got an error? */
895          if (n <= 0)          if (n <= 0)
896          {          {
897                  DEBUG_INFO2("IFD does not support GET_DATA_RATES request: %s",                  DEBUG_INFO2("IFD does not support GET_DATA_RATES request: %d", n);
                         strerror(errno));  
898                  return NULL;                  return NULL;
899          }          }
900    
# Line 752  static unsigned int *get_data_rates(unsi Line 909  static unsigned int *get_data_rates(unsi
909          n /= sizeof(int);          n /= sizeof(int);
910    
911          /* we do not get the expected number of data rates */          /* we do not get the expected number of data rates */
912          len = get_ccid_usb_interface(dev)->altsetting->extra[27]; /* bNumDataRatesSupported */          len = get_ccid_usb_interface(desc, &num)->altsetting->extra[27]; /* bNumDataRatesSupported */
913          if ((n != len) && len)          if ((n != len) && len)
914          {          {
915                  DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);                  DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);
# Line 780  static unsigned int *get_data_rates(unsi Line 937  static unsigned int *get_data_rates(unsi
937          int_array[i] = 0;          int_array[i] = 0;
938    
939          return int_array;          return int_array;
940  }  } /* get_data_rates */
941    
942    
943    /*****************************************************************************
944     *
945     *                                      ControlUSB
946     *
947     ****************************************************************************/
948  int ControlUSB(int reader_index, int requesttype, int request, int value,  int ControlUSB(int reader_index, int requesttype, int request, int value,
949          unsigned char *bytes, unsigned int size)          unsigned char *bytes, unsigned int size)
950  {  {
# Line 792  int ControlUSB(int reader_index, int req Line 955  int ControlUSB(int reader_index, int req
955          if (0 == (requesttype & 0x80))          if (0 == (requesttype & 0x80))
956                  DEBUG_XXD("send: ", bytes, size);                  DEBUG_XXD("send: ", bytes, size);
957    
958          ret = usb_control_msg(usbDevice[reader_index].handle, requesttype,          ret = libusb_control_transfer(usbDevice[reader_index].dev_handle,
959                  request, value, usbDevice[reader_index].interface, (char *)bytes, size,                  requesttype, request, value, usbDevice[reader_index].interface,
960                  usbDevice[reader_index].ccid.readTimeout * 1000);                  bytes, size, usbDevice[reader_index].ccid.readTimeout);
961    
962          if (requesttype & 0x80)          if (requesttype & 0x80)
963                  DEBUG_XXD("receive: ", bytes, ret);                  DEBUG_XXD("receive: ", bytes, ret);
964    
965          return ret;          return ret;
966  }  } /* ControlUSB */
967    
968    /*****************************************************************************
969     *
970     *                                      InterruptRead
971     *
972     ****************************************************************************/
973    int InterruptRead(int reader_index, int timeout /* in ms */)
974    {
975            int ret, actual_length;
976            unsigned char buffer[8];
977    
978            DEBUG_PERIODIC2("before (%d)", reader_index);
979            ret = libusb_interrupt_transfer(usbDevice[reader_index].dev_handle,
980                    usbDevice[reader_index].interrupt, buffer, sizeof(buffer),
981                    &actual_length, timeout);
982            DEBUG_PERIODIC3("after (%d) (%d)", reader_index, ret);
983    
984            if (ret < 0)
985            {
986                    /* if libusb_interrupt_transfer() times out we get EILSEQ or EAGAIN */
987                    if ((errno != EILSEQ) && (errno != EAGAIN) && (errno != ENODEV) && (errno != 0))
988                            DEBUG_COMM4("libusb_interrupt_transfer(%d/%d): %s",
989                                    usbDevice[reader_index].bus_number,
990                                    usbDevice[reader_index].device_address, strerror(errno));
991            }
992            else
993                    DEBUG_XXD("NotifySlotChange: ", (const unsigned char *)buffer, actual_length);
994    
995            return ret;
996    } /* InterruptRead */
997    

Legend:
Removed from v.2469  
changed lines
  Added in v.5010

  ViewVC Help
Powered by ViewVC 1.1.5