/[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 1079 by rousseau, Fri Jul 16 09:07:26 2004 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 program is free software; you can redistribute it and/or modify      This library is free software; you can redistribute it and/or
6      it under the terms of the GNU General Public License as published by      modify it under the terms of the GNU Lesser General Public
7      the Free Software Foundation; either version 2 of the License, or      License as published by the Free Software Foundation; either
8      (at your option) any later version.      version 2.1 of the License, or (at your option) any later version.
9    
10      This program is distributed in the hope that it will be useful,      This library is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      GNU General Public License for more details.      Lesser General Public License for more details.
14    
15      You should have received a copy of the GNU General Public License          You should have received a copy of the GNU Lesser General Public License
16      along with this program; 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 24  Line 24 
24  #define __CCID_USB__  #define __CCID_USB__
25    
26  #include <stdio.h>  #include <stdio.h>
27  #include <string.h>  #include <string.h>
28  #include <errno.h>  #include <errno.h>
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"
37  #include "ccid.h"  #include "ccid.h"
38  #include "config.h"  #include "config.h"
39  #include "debug.h"  #include "debug.h"
# Line 40  Line 43 
43  #include "ccid_ifdhandler.h"  #include "ccid_ifdhandler.h"
44    
45    
 /* read timeout  
  * we must wait enough so that the card can finish its calculation  
  * the card, and then the reader should send TIME REQUEST bytes  
  * so this timeout should never occur */  
 #define USB_READ_TIMEOUT (60 * 1000)    /* 1 minute timeout */  
   
46  /* write timeout  /* write timeout
47   * we don't have to wait a long time since the card was doing nothing */   * we don't have to wait a long time since the card was doing nothing */
48  #define USB_WRITE_TIMEOUT (5 * 1000)  /* 5 seconds timeout */  #define USB_WRITE_TIMEOUT (5 * 1000)  /* 5 seconds timeout */
# Line 62  Line 59 
59    
60  typedef struct  typedef struct
61  {  {
62          usb_dev_handle *handle;          libusb_device_handle *dev_handle;
63          struct usb_device *dev;          uint8_t bus_number;
64            uint8_t device_address;
65            int interface;
66    
67          /*          /*
68           * Endpoints           * Endpoints
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 */
75            int real_nb_opened_slots;
76            int *nb_opened_slots;
77    
78          /*          /*
79           * CCID infos common to USB and serial           * CCID infos common to USB and serial
# Line 81  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 *usb_device);  static int get_end_points(struct libusb_config_descriptor *desc,
89            _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,
92            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 90  static _usbDevice usbDevice[CCID_DRIVER_ Line 98  static _usbDevice usbDevice[CCID_DRIVER_
98  #define PCSCLITE_PRODKEY_NAME                   "ifdProductID"  #define PCSCLITE_PRODKEY_NAME                   "ifdProductID"
99  #define PCSCLITE_NAMEKEY_NAME                   "ifdFriendlyName"  #define PCSCLITE_NAMEKEY_NAME                   "ifdFriendlyName"
100    
101    struct _bogus_firmware
102    {
103            int vendor;             /* idVendor */
104            int product;    /* idProduct */
105            int firmware;   /* bcdDevice: previous firmwares have bugs */
106    };
107    
108    static struct _bogus_firmware Bogus_firmwares[] = {
109            { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */
110            { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */
111            { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */
112            { 0x04e6, 0xe003, 0x0510 },     /* SPR 532 */
113            { 0x0D46, 0x3001, 0x0037 },     /* KAAN Base */
114            { 0x0D46, 0x3002, 0x0037 },     /* KAAN Advanced */
115            { 0x09C3, 0x0008, 0x0203 },     /* ActivCard V2 */
116            { 0x0DC3, 0x1004, 0x0502 },     /* ASE IIIe USBv2 */
117            { 0x0DC3, 0x1102, 0x0607 },     /* ASE IIIe KB USB */
118            { 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 */
132    unsigned int SerialCustomDataRates[] = { GEMPLUS_CUSTOM_DATA_RATES, 0 };
133    
134    
135  /*****************************************************************************  /*****************************************************************************
136   *   *
137   *                                      OpenUSB   *                                      OpenUSB
138   *   *
139   ****************************************************************************/   ****************************************************************************/
140  status_t OpenUSB(unsigned int lun, /*@unused@*/ int Channel)  status_t OpenUSB(unsigned int reader_index, /*@unused@*/ int Channel)
141  {  {
142          return OpenUSBByName(lun, NULL);          (void)Channel;
143    
144            return OpenUSBByName(reader_index, NULL);
145  } /* OpenUSB */  } /* OpenUSB */
146    
147    
# Line 107  status_t OpenUSB(unsigned int lun, /*@un Line 150  status_t OpenUSB(unsigned int lun, /*@un
150   *                                      OpenUSBByName   *                                      OpenUSBByName
151   *   *
152   ****************************************************************************/   ****************************************************************************/
153  status_t OpenUSBByName(unsigned int lun, /*@null@*/ char *device)  status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
154  {  {
         static struct usb_bus *busses = NULL;  
         unsigned int reader = LunToReaderIndex(lun);  
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          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;
166            libusb_device **devs, *dev;
167            ssize_t cnt;
168    
169          DEBUG_COMM3("Lun: %X, Device: %s", lun, 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 139  status_t OpenUSBByName(unsigned int lun, Line 188  status_t OpenUSBByName(unsigned int lun,
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();  
230    
231          if (busses == NULL)          /* is the reader_index already used? */
232            if (usbDevice[reader_index].dev_handle != NULL)
233          {          {
234                  DEBUG_CRITICAL("No USB busses found");                  DEBUG_CRITICAL2("USB driver with index %X already in use",
235                  return STATUS_UNSUCCESSFUL;                          reader_index);
         }  
   
         /* is the lun already used? */  
         if (usbDevice[reader].handle != NULL)  
         {  
                 DEBUG_CRITICAL2("USB driver with lun %X already in use", lun);  
236                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
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 */
244          if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))
245          {          {
246                  DEBUG_CRITICAL2("Manufacturer: %s", keyValue);                  DEBUG_INFO2("Manufacturer: %s", keyValue);
247          }          }
248          else          else
249          {          {
250                  DEBUG_CRITICAL2("LTPBundleFindValueWithKey error. Can't find %s?",                  DEBUG_INFO2("LTPBundleFindValueWithKey error. Can't find %s?",
251                          infofile);                          infofile);
252                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
253          }          }
254          if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))
255          {          {
256                  DEBUG_CRITICAL2("ProductString: %s", keyValue);                  DEBUG_INFO2("ProductString: %s", keyValue);
257          }          }
258          else          else
259                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
260          if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))
261          {          {
262                  DEBUG_CRITICAL2("Copyright: %s", keyValue);                  DEBUG_INFO2("Copyright: %s", keyValue);
263          }          }
264          else          else
265                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
266          vendorID = strlen(keyValue);          vendorID = strlen(keyValue);
267          alias = 0x1D;          alias = 0x1C;
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 235  status_t OpenUSBByName(unsigned int lun, Line 290  status_t OpenUSBByName(unsigned int lun,
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 (dev->descriptor.idVendor == vendorID                          if (desc.idVendor == vendorID && desc.idProduct == productID)
322                                          && dev->descriptor.idProduct == productID)                          {
323                                  {                                  int already_used;
324                                          int r, already_used;                                  const struct libusb_interface *usb_interface = NULL;
325                                          struct usb_interface *usb_interface = NULL;                                  int interface;
326                                          int interface;                                  int num = 0;
327    
328                                          /* is it already opened? */  #ifdef USE_COMPOSITE_AS_MULTISLOT
329                                          already_used = FALSE;                                  static int static_interface = 1;
330    
331                                          for (r=0; r<CCID_DRIVER_MAX_READERS; r++)                                  {
332                                          {                                          /* simulate a composite device as when libhal is
333                                                  if (usbDevice[r].dev)                                           * used */
334                                                  {                                          int readerID = (vendorID << 16) + productID;
                                                         DEBUG_COMM3("Checking device: %s/%s",  
                                                                 bus->dirname, dev->filename);  
                                                         /* same busname, same filename */  
                                                         if (strcmp(usbDevice[r].dev->bus->dirname, bus->dirname) == 0 && strcmp(usbDevice[r].dev->filename, dev->filename) == 0)  
                                                                 already_used = TRUE;  
                                                 }  
                                         }  
335    
336                                          /* this reader is already managed by us */                                          if ((GEMALTOPROXDU == readerID)
337                                          if (already_used)                                                  || (GEMALTOPROXSU == readerID))
338                                          {                                          {
339                                                  DEBUG_INFO3("USB device %s/%s already in use. Checking next one.",                                                          /*
340                                                          bus->dirname, dev->filename);                                                           * We can't talk to the two CCID interfaces
341                                                             * at the same time (the reader enters a
342                                                             * dead lock). So we simulate a multi slot
343                                                             * 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                                                  continue;                                                  /* 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                                          DEBUG_COMM3("Trying to open USB bus/device: %s/%s",                                  DEBUG_COMM3("Checking device: %d/%d",
368                                                   bus->dirname, dev->filename);                                          bus_number, device_address);
369                                    for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
370                                    {
371                                            if (usbDevice[r].dev_handle)
372                                            {
373                                                    /* same bus, same address */
374                                                    if (usbDevice[r].bus_number == bus_number
375                                                            && usbDevice[r].device_address == device_address)
376                                                            already_used = TRUE;
377                                            }
378                                    }
379    
380                                          dev_handle = usb_open(dev);                                  /* this reader is already managed by us */
381                                          if (dev_handle == NULL)                                  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                                                  DEBUG_CRITICAL4("Can't usb_open(%s/%s): %s",                                                  /* we reuse the same device
390                                                          bus->dirname, dev->filename, strerror(errno));                                                   * 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                                                            usbDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates;
397                                                            usbDevice[reader_index].ccid.dwMaxDataRate = 125000;
398                                                    }
399    
400                                                  continue;                                                  *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
                                         /* now we found a free reader and we try to use it */  
                                         if (dev->config == NULL)  
409                                          {                                          {
410                                                  DEBUG_CRITICAL3("No dev->config found for %s/%s",                                                  /* if an interface number is given by HAL we
411                                                           bus->dirname, dev->filename);                                                   * continue with this device. */
412                                                  return STATUS_UNSUCCESSFUL;                                                  if (-1 == interface_number)
413                                                    {
414                                                            DEBUG_INFO3("USB device %d/%d already in use."
415                                                                    " Checking next one.",
416                                                                    bus_number, device_address);
417                                                            continue;
418                                                    }
419                                          }                                          }
420                                    }
421    
422                                          usb_interface = get_ccid_usb_interface(dev);                                  DEBUG_COMM3("Trying to open USB bus/device: %d/%d",
423                                          if (usb_interface == NULL)                                          bus_number, device_address);
                                         {  
                                                 DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",  
                                                         bus->dirname, dev->filename);  
                                                 return STATUS_UNSUCCESSFUL;  
                                         }  
424    
425                                          if (usb_interface->altsetting->extralen != 54)                                  r = libusb_open(dev, &dev_handle);
426                                          {                                  if (r < 0)
427                                                  DEBUG_CRITICAL4("Extra field for %s/%s has a wrong length: %d", bus->dirname, dev->filename, usb_interface->altsetting->extralen);                                  {
428                                                  return STATUS_UNSUCCESSFUL;                                          DEBUG_CRITICAL4("Can't libusb_open(%d/%d): %d",
429                                          }                                                  bus_number, device_address, r);
430    
431                                          interface = usb_interface->altsetting->bInterfaceNumber;                                          continue;
432                                          if (usb_claim_interface(dev_handle, interface) < 0)                                  }
433                                          {  
434                                                  DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",  again:
435                                                          bus->dirname, dev->filename, strerror(errno));                                  r = libusb_get_active_config_descriptor(dev, &config_desc);
436                                                  return STATUS_UNSUCCESSFUL;                                  if (r < 0)
437                                          }                                  {
438                                            (void)libusb_close(dev_handle);
439                                            DEBUG_CRITICAL3("Can't get config descriptor on %d/%d",
440                                                    bus_number, device_address);
441                                            continue;
442                                    }
443    
444                                    usb_interface = get_ccid_usb_interface(config_desc, &num);
445                                    if (usb_interface == NULL)
446                                    {
447                                            (void)libusb_close(dev_handle);
448                                            if (0 == num)
449                                                    DEBUG_CRITICAL3("Can't find a CCID interface on %d/%d",
450                                                            bus_number, device_address);
451                                            interface_number = -1;
452                                            continue;
453                                    }
454    
455                                    if (usb_interface->altsetting->extra_length != 54)
456                                    {
457                                            (void)libusb_close(dev_handle);
458                                            DEBUG_CRITICAL4("Extra field for %d/%d has a wrong length: %d",
459                                                    bus_number, device_address,
460                                                    usb_interface->altsetting->extra_length);
461                                            return STATUS_UNSUCCESSFUL;
462                                    }
463    
464                                    interface = usb_interface->altsetting->bInterfaceNumber;
465                                    if (interface_number >= 0 && interface != interface_number)
466                                    {
467                                            /* an interface was specified and it is not the
468                                             * current one */
469                                            DEBUG_INFO3("Wrong interface for USB device %d/%d."
470                                                    " Checking next one.", bus_number, device_address);
471    
472                                            /* check for another CCID interface on the same device */
473                                            num++;
474    
475                                            goto again;
476                                    }
477    
478                                    r = libusb_claim_interface(dev_handle, interface);
479                                    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                                    DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",
489                                            desc.idVendor, desc.idProduct, keyValue);
490                                    DEBUG_INFO3("Using USB bus/device: %d/%d",
491                                            bus_number, device_address);
492    
493                                          DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",                                  /* check for firmware bugs */
494                                                  dev->descriptor.idVendor,                                  if (ccid_check_firmware(&desc))
495                                                  dev->descriptor.idProduct, keyValue);                                  {
496                                          DEBUG_INFO3("Using USB bus/device: %s/%s",                                          (void)libusb_close(dev_handle);
497                                                   bus->dirname, dev->filename);                                          return STATUS_UNSUCCESSFUL;
498                                    }
499                                          /* Get Endpoints values*/  
500                                          get_end_points(dev, &usbDevice[reader]);  #ifdef USE_COMPOSITE_AS_MULTISLOT
501                                    /* use the next interface for the next "slot" */
502                                          /* store device information */                                  static_interface++;
503                                          usbDevice[reader].handle = dev_handle;  
504                                          usbDevice[reader].dev = dev;                                  /* reset for a next reader */
505                                    if (static_interface > 2)
506                                          /* CCID common informations */                                          static_interface = 1;
507                                          usbDevice[reader].ccid.bSeq = 0;  #endif
508                                          usbDevice[reader].ccid.readerID =  
509                                                  (dev->descriptor.idVendor << 16) +                                  /* Get Endpoints values*/
510                                                  dev->descriptor.idProduct;                                  (void)get_end_points(config_desc, &usbDevice[reader_index], num);
511                                          usbDevice[reader].ccid.dwFeatures = dw2i(usb_interface->altsetting->extra, 40);  
512                                          usbDevice[reader].ccid.bPINSupport = usb_interface->altsetting->extra[52];                                  /* store device information */
513                                          usbDevice[reader].ccid.dwMaxCCIDMessageLength = dw2i(usb_interface->altsetting->extra, 44);                                  usbDevice[reader_index].dev_handle = dev_handle;
514                                          usbDevice[reader].ccid.dwMaxIFSD = dw2i(usb_interface->altsetting->extra, 28);                                  usbDevice[reader_index].bus_number = bus_number;
515                                          usbDevice[reader].ccid.dwDefaultClock = dw2i(usb_interface->altsetting->extra, 10);                                  usbDevice[reader_index].device_address = device_address;
516                                          usbDevice[reader].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);                                  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                                          goto end;                                          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].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
564             * a new OpenUSBByName on a multi slot reader */
565            previous_reader_index = reader_index;
566    
567          return STATUS_SUCCESS;          return STATUS_SUCCESS;
568  } /* OpenUSBByName */  } /* OpenUSBByName */
# Line 369  end: Line 573  end:
573   *                                      WriteUSB   *                                      WriteUSB
574   *   *
575   ****************************************************************************/   ****************************************************************************/
576  status_t WriteUSB(unsigned int lun, unsigned int length, unsigned char *buffer)  status_t WriteUSB(unsigned int reader_index, unsigned int length,
577            unsigned char *buffer)
578  {  {
579          int rv;          int rv;
580          unsigned int reader = LunToReaderIndex(lun);          int actual_length;
 #ifdef DEBUG_LEVEL_COMM  
581          char debug_header[] = "-> 121234 ";          char debug_header[] = "-> 121234 ";
582    
583          sprintf(debug_header, "-> %06X ", (int)lun);          (void)snprintf(debug_header, sizeof(debug_header), "-> %06X ",
584  #endif                  (int)reader_index);
585    
 #ifdef DEBUG_LEVEL_COMM  
586          DEBUG_XXD(debug_header, buffer, length);          DEBUG_XXD(debug_header, buffer, length);
 #endif  
587    
588          rv = usb_bulk_write(usbDevice[reader].handle, usbDevice[reader].bulk_out,          rv = libusb_bulk_transfer(usbDevice[reader_index].dev_handle,
589                  (char *)buffer, length, USB_WRITE_TIMEOUT);                  usbDevice[reader_index].bulk_out, buffer, length,
590                    &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].dev->bus->dirname,                          usbDevice[reader_index].bus_number,
596                          usbDevice[reader].dev->filename, strerror(errno));                          usbDevice[reader_index].device_address, strerror(errno));
597    
598                    if (ENODEV == errno)
599                            return STATUS_NO_SUCH_DEVICE;
600    
601                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
602          }          }
603    
# Line 403  status_t WriteUSB(unsigned int lun, unsi Line 610  status_t WriteUSB(unsigned int lun, unsi
610   *                                      ReadUSB   *                                      ReadUSB
611   *   *
612   ****************************************************************************/   ****************************************************************************/
613  status_t ReadUSB(unsigned int lun, unsigned int * length, unsigned char *buffer)  status_t ReadUSB(unsigned int reader_index, unsigned int * length,
614            unsigned char *buffer)
615  {  {
616          int rv;          int rv;
617          unsigned int reader = LunToReaderIndex(lun);          int actual_length;
 #ifdef DEBUG_LEVEL_COMM  
618          char debug_header[] = "<- 121234 ";          char debug_header[] = "<- 121234 ";
619            _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
620            int duplicate_frame = 0;
621    
622          sprintf(debug_header, "<- %06X ", (int)lun);  read_again:
623  #endif          (void)snprintf(debug_header, sizeof(debug_header), "<- %06X ",
624                    (int)reader_index);
625          rv = usb_bulk_read(usbDevice[reader].handle, usbDevice[reader].bulk_in,  
626                  (char *)buffer, *length, USB_READ_TIMEOUT);          rv = libusb_bulk_transfer(usbDevice[reader_index].dev_handle,
627                    usbDevice[reader_index].bulk_in, buffer, *length,
628                    &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].dev->bus->dirname,                          usbDevice[reader_index].bus_number,
635                          usbDevice[reader].dev->filename, strerror(errno));                          usbDevice[reader_index].device_address, strerror(errno));
636    
637                    if (ENODEV == errno)
638                            return STATUS_NO_SUCH_DEVICE;
639    
640                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
641          }          }
642    
643          *length = rv;          *length = actual_length;
644    
 #ifdef DEBUG_LEVEL_COMM  
645          DEBUG_XXD(debug_header, buffer, *length);          DEBUG_XXD(debug_header, buffer, *length);
646  #endif  
647    #define BSEQ_OFFSET 6
648            if ((*length >= BSEQ_OFFSET)
649                    && (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");
658                    goto read_again;
659            }
660    
661          return STATUS_SUCCESS;          return STATUS_SUCCESS;
662  } /* ReadUSB */  } /* ReadUSB */
# Line 440  status_t ReadUSB(unsigned int lun, unsig Line 667  status_t ReadUSB(unsigned int lun, unsig
667   *                                      CloseUSB   *                                      CloseUSB
668   *   *
669   ****************************************************************************/   ****************************************************************************/
670  status_t CloseUSB(unsigned int lun)  status_t CloseUSB(unsigned int reader_index)
671  {  {
         struct usb_interface *usb_interface;  
         int interface;  
         unsigned int reader = LunToReaderIndex(lun);  
   
672          /* device not opened */          /* device not opened */
673          if (usbDevice[reader].dev == 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].dev->bus->dirname, usbDevice[reader].dev->filename);                  usbDevice[reader_index].bus_number,
678                    usbDevice[reader_index].device_address);
679    
680          usb_interface = get_ccid_usb_interface(usbDevice[reader].dev);          if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates
681          interface = usb_interface ?                  && (usbDevice[reader_index].ccid.bCurrentSlotIndex == 0))
682                  usb_interface->altsetting->bInterfaceNumber :          {
683                  usbDevice[reader].dev->config->interface->altsetting->bInterfaceNumber;                  free(usbDevice[reader_index].ccid.arrayOfSupportedDataRates);
684                    usbDevice[reader_index].ccid.arrayOfSupportedDataRates = NULL;
685          /* reset so that bSeq starts at 0 again */          }
         usb_reset(usbDevice[reader].handle);  
686    
687          usb_release_interface(usbDevice[reader].handle, interface);          /* one slot closed */
688          usb_close(usbDevice[reader].handle);          (*usbDevice[reader_index].nb_opened_slots)--;
689    
690            /* release the allocated ressources for the last slot only */
691            if (0 == *usbDevice[reader_index].nb_opened_slots)
692            {
693                    DEBUG_COMM("Last slot closed. Release resources");
694    
695                    /* reset so that bSeq starts at 0 again */
696                    if (DriverOptions & DRIVER_OPTION_RESET_ON_CLOSE)
697                            (void)libusb_reset_device(usbDevice[reader_index].dev_handle);
698    
699                    (void)libusb_release_interface(usbDevice[reader_index].dev_handle,
700                            usbDevice[reader_index].interface);
701                    (void)libusb_close(usbDevice[reader_index].dev_handle);
702            }
703    
704          /* mark the resource unused */          /* mark the resource unused */
705          usbDevice[reader].handle = NULL;          usbDevice[reader_index].dev_handle = NULL;
706          usbDevice[reader].dev = NULL;          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 */
# Line 477  status_t CloseUSB(unsigned int lun) Line 717  status_t CloseUSB(unsigned int lun)
717   *                                      get_ccid_descriptor   *                                      get_ccid_descriptor
718   *   *
719   ****************************************************************************/   ****************************************************************************/
720  _ccid_descriptor *get_ccid_descriptor(unsigned int lun)  _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
721  {  {
722          return &usbDevice[LunToReaderIndex(lun)].ccid;          return &usbDevice[reader_index].ccid;
723  } /* get_ccid_descriptor */  } /* get_ccid_descriptor */
724    
725    
726  /*****************************************************************************  /*****************************************************************************
727   *   *
  *                                      get_desc  
  *  
  ****************************************************************************/  
 int get_desc(int channel, usb_dev_handle **handle, struct  
         usb_device **dev)  
 {  
         if (channel < 0 || channel > CCID_DRIVER_MAX_READERS)  
                 return 1;  
   
         *handle = usbDevice[channel].handle;  
         *dev = usbDevice[channel].dev;  
   
         return 0;  
 } /* get_desc */  
   
   
 /*****************************************************************************  
  *  
728   *                                      get_end_points   *                                      get_end_points
729   *   *
730   ****************************************************************************/   ****************************************************************************/
731  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device)  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<3; 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;                          continue;
752                    }
753    
754                  bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;                  if (usb_interface->altsetting->endpoint[i].bmAttributes
755                            != LIBUSB_TRANSFER_TYPE_BULK)
756                            continue;
757    
758                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)                  bEndpointAddress =
759                          usb_device->bulk_in = bEndpointAddress;                          usb_interface->altsetting->endpoint[i].bEndpointAddress;
760    
761                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)                  if ((bEndpointAddress & LIBUSB_TRANSFER_TYPE_MASK)
762                          usb_device->bulk_out = bEndpointAddress;                          == LIBUSB_ENDPOINT_IN)
763                            usbdevice->bulk_in = bEndpointAddress;
764    
765                    if ((bEndpointAddress & LIBUSB_TRANSFER_TYPE_MASK)
766                            == LIBUSB_ENDPOINT_OUT)
767                            usbdevice->bulk_out = bEndpointAddress;
768          }          }
769    
770          return 0;          return 0;
# Line 538  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@*/ 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;
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          if (dev->config->bNumInterfaces > 1)          for (i = *num; i < desc->bNumInterfaces; i++)
790          {          {
791                  int ii;                  /* CCID Class? */
792                  for (ii=0; ii<dev->config->bNumInterfaces; ii++)                  if (desc->interface[i].altsetting->bInterfaceClass == 0xb
                 {  
                         /* CCID Class? */  
                         if (dev->config->interface[ii].altsetting->bInterfaceClass == 0xb  
793  #ifdef ALLOW_PROPRIETARY_CLASS  #ifdef ALLOW_PROPRIETARY_CLASS
794                                  || dev->config->interface[ii].altsetting->bInterfaceClass == 0xff                          || desc->interface[i].altsetting->bInterfaceClass == 0xff
795  #endif  #endif
796                                  )                          )
797                    {
798                            usb_interface = &desc->interface[i];
799                            /* store the interface number for further reference */
800                            *num = i;
801                            break;
802                    }
803            }
804    
805    #ifdef O2MICRO_OZ776_PATCH
806            readerID = (dev->descriptor.idVendor << 16) + dev->descriptor.idProduct;
807            if (usb_interface != NULL
808                    && ((OZ776 == readerID) || (OZ776_7772 == readerID)
809                    || (REINER_SCT == readerID) || (BLUDRIVEII_CCID == readerID))
810                    && (0 == usb_interface->altsetting->extra_length)) /* this is the bug */
811            {
812                    int j;
813                    for (j=0; j<usb_interface->altsetting->bNumEndpoints; j++)
814                    {
815                            /* find the extra[] array */
816                            if (54 == usb_interface->altsetting->endpoint[j].extra_length)
817                          {                          {
818                                  usb_interface = &dev->config->interface[ii];                                  /* get the extra[] from the endpoint */
819                                    usb_interface->altsetting->extra_length = 54;
820                                    usb_interface->altsetting->extra =
821                                            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                  }                  }
828          }          }
829          else  #endif
                 /* we keep this in case a reader reports a bad class value */  
                 usb_interface = dev->config->interface;  
830    
831          return usb_interface;          return usb_interface;
832  } /* get_ccid_usb_interface */  } /* get_ccid_usb_interface */
833    
834    
835    /*****************************************************************************
836     *
837     *                                      ccid_check_firmware
838     *
839     ****************************************************************************/
840    int ccid_check_firmware(struct libusb_device_descriptor *desc)
841    {
842            unsigned int i;
843    
844            for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)
845            {
846                    if (desc->idVendor != Bogus_firmwares[i].vendor)
847                            continue;
848    
849                    if (desc->idProduct != Bogus_firmwares[i].product)
850                            continue;
851    
852                    /* firmware too old and buggy */
853                    if (desc->bcdDevice < Bogus_firmwares[i].firmware)
854                    {
855                            if (DriverOptions & DRIVER_OPTION_USE_BOGUS_FIRMWARE)
856                            {
857                                    DEBUG_INFO3("Firmware (%X.%02X) is bogus! but you choosed to use it",
858                                            desc->bcdDevice >> 8, desc->bcdDevice & 0xFF);
859                                    return FALSE;
860                            }
861                            else
862                            {
863                                    DEBUG_CRITICAL3("Firmware (%X.%02X) is bogus! Upgrade the reader firmware or get a new reader.",
864                                            desc->bcdDevice >> 8, desc->bcdDevice & 0xFF);
865                                    return TRUE;
866                            }
867                    }
868            }
869    
870            /* by default the firmware is not bogus */
871            return FALSE;
872    } /* ccid_check_firmware */
873    
874    
875    /*****************************************************************************
876     *
877     *                                      get_data_rates
878     *
879     ****************************************************************************/
880    static unsigned int *get_data_rates(unsigned int reader_index,
881            struct libusb_config_descriptor *desc, int num)
882    {
883            int n, i, len;
884            unsigned char buffer[256*sizeof(int)];  /* maximum is 256 records */
885            unsigned int *int_array;
886    
887            /* See CCID 3.7.3 page 25 */
888            n = ControlUSB(reader_index,
889                    0xA1, /* request type */
890                    0x03, /* GET_DATA_RATES */
891                    0x00, /* value */
892                    buffer, sizeof(buffer));
893    
894            /* we got an error? */
895            if (n <= 0)
896            {
897                    DEBUG_INFO2("IFD does not support GET_DATA_RATES request: %d", n);
898                    return NULL;
899            }
900    
901            /* we got a strange value */
902            if (n % 4)
903            {
904                    DEBUG_INFO2("Wrong GET DATA RATES size: %d", n);
905                    return NULL;
906            }
907    
908            /* allocate the buffer (including the end marker) */
909            n /= sizeof(int);
910    
911            /* we do not get the expected number of data rates */
912            len = get_ccid_usb_interface(desc, &num)->altsetting->extra[27]; /* bNumDataRatesSupported */
913            if ((n != len) && len)
914            {
915                    DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);
916    
917                    /* we got more data than expected */
918                    if (n > len)
919                            n = len;
920            }
921    
922            int_array = calloc(n+1, sizeof(int));
923            if (NULL == int_array)
924            {
925                    DEBUG_CRITICAL("Memory allocation failed");
926                    return NULL;
927            }
928    
929            /* convert in correct endianess */
930            for (i=0; i<n; i++)
931            {
932                    int_array[i] = dw2i(buffer, i*4);
933                    DEBUG_INFO2("declared: %d bps", int_array[i]);
934            }
935    
936            /* end of array marker */
937            int_array[i] = 0;
938    
939            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,
949            unsigned char *bytes, unsigned int size)
950    {
951            int ret;
952    
953            DEBUG_COMM2("request: 0x%02X", request);
954    
955            if (0 == (requesttype & 0x80))
956                    DEBUG_XXD("send: ", bytes, size);
957    
958            ret = libusb_control_transfer(usbDevice[reader_index].dev_handle,
959                    requesttype, request, value, usbDevice[reader_index].interface,
960                    bytes, size, usbDevice[reader_index].ccid.readTimeout);
961    
962            if (requesttype & 0x80)
963                    DEBUG_XXD("receive: ", bytes, ret);
964    
965            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.1079  
changed lines
  Added in v.5010

  ViewVC Help
Powered by ViewVC 1.1.5