/[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 1327 by rousseau, Sun Feb 20 14:34:42 2005 UTC revision 5205 by rousseau, Tue Aug 31 08:55:56 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.h>
33    #include <stdlib.h>
34    #include <ifdhandler.h>
35    
 #include "ccid.h"  
36  #include "config.h"  #include "config.h"
37    #include "misc.h"
38    #include "ccid.h"
39  #include "debug.h"  #include "debug.h"
40  #include "defs.h"  #include "defs.h"
41  #include "utils.h"  #include "utils.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 58  Line 55 
55   * Manufacturer and Product ID are also used to identify the device */   * Manufacturer and Product ID are also used to identify the device */
56  #define ALLOW_PROPRIETARY_CLASS  #define ALLOW_PROPRIETARY_CLASS
57    
 /*  
  * The O2Micro OZ776S reader has a wrong USB descriptor  
  * The extra[] field is associated with the last endpoint instead of the  
  * main USB descriptor  
  */  
 #define O2MICRO_OZ776_PATCH  
   
58  #define BUS_DEVICE_STRSIZE 32  #define BUS_DEVICE_STRSIZE 32
59    
60    /* Using the default libusb context */
61    /* does not work for libusb <= 1.0.8 */
62    /* #define ctx NULL */
63    libusb_context *ctx = NULL;
64    
65  typedef struct  typedef struct
66  {  {
67          usb_dev_handle *handle;          libusb_device_handle *dev_handle;
68          struct usb_device *dev;          uint8_t bus_number;
69            uint8_t device_address;
70          int interface;          int interface;
71    
72          /*          /*
# Line 78  typedef struct Line 74  typedef struct
74           */           */
75          int bulk_in;          int bulk_in;
76          int bulk_out;          int bulk_out;
77            int interrupt;
78    
79            /* Number of slots using the same device */
80            int real_nb_opened_slots;
81            int *nb_opened_slots;
82    
83          /*          /*
84           * CCID infos common to USB and serial           * CCID infos common to USB and serial
85           */           */
86          _ccid_descriptor ccid;          _ccid_descriptor ccid;
87    
88            /* libusb transfer for the polling (or NULL) */
89            struct libusb_transfer *polling_transfer;
90    
91  } _usbDevice;  } _usbDevice;
92    
93  /* The _usbDevice structure must be defined before including ccid_usb.h */  /* The _usbDevice structure must be defined before including ccid_usb.h */
94  #include "ccid_usb.h"  #include "ccid_usb.h"
95    
96  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device);  static int get_end_points(struct libusb_config_descriptor *desc,
97  int ccid_check_firmware(struct usb_device *dev);          _usbDevice *usbdevice, int num);
98    int ccid_check_firmware(struct libusb_device_descriptor *desc);
99    static unsigned int *get_data_rates(unsigned int reader_index,
100            struct libusb_config_descriptor *desc, int num);
101    
102  /* ne need to initialize to 0 since it is static */  /* ne need to initialize to 0 since it is static */
103  static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];  static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];
# Line 107  struct _bogus_firmware Line 114  struct _bogus_firmware
114  };  };
115    
116  static struct _bogus_firmware Bogus_firmwares[] = {  static struct _bogus_firmware Bogus_firmwares[] = {
         { 0x0b97, 0x7762, 0x0111 },     /* Oz776S */ /* the firmware version if not correct since I don't have received a working reader yet */  
117          { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */          { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */
118          { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */          { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */
119          { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */          { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */
120          { 0x04e6, 0xe003, 0x0504 },     /* SPR 532 */          { 0x04e6, 0xe003, 0x0510 },     /* SPR 532 */
121          { 0x0D46, 0x3001, 0x0037 },     /* KAAN Base */          { 0x0D46, 0x3001, 0x0037 },     /* KAAN Base */
122          { 0x0D46, 0x3002, 0x0037 },     /* KAAN Advanced */          { 0x0D46, 0x3002, 0x0037 },     /* KAAN Advanced */
123            { 0x09C3, 0x0008, 0x0203 },     /* ActivCard V2 */
124            { 0x0DC3, 0x1004, 0x0502 },     /* ASE IIIe USBv2 */
125            { 0x0DC3, 0x1102, 0x0607 },     /* ASE IIIe KB USB */
126            { 0x058F, 0x9520, 0x0102 },     /* Alcor AU9520-G */
127            { 0x072F, 0x2200, 0x0206 }, /* ACS ACR122U-WB-R */
128            { 0x08C3, 0x0402, 0x5000 },     /* Precise Biometrics Precise 200 MC */
129            { 0x08C3, 0x0401, 0x5000 },     /* Precise Biometrics Precise 250 MC */
130            { 0x0B0C, 0x0050, 0x0101 },     /* Todos Argos Mini II */
131    
132            /* the firmware version is not correct since I do not have received a
133             * working reader yet */
134    #ifndef O2MICRO_OZ776_PATCH
135            { 0x0b97, 0x7762, 0x0111 },     /* Oz776S */
136    #endif
137  };  };
138    
139    /* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
140    unsigned int SerialCustomDataRates[] = { GEMPLUS_CUSTOM_DATA_RATES, 0 };
141    
142    
143  /*****************************************************************************  /*****************************************************************************
144   *   *
# Line 124  static struct _bogus_firmware Bogus_firm Line 147  static struct _bogus_firmware Bogus_firm
147   ****************************************************************************/   ****************************************************************************/
148  status_t OpenUSB(unsigned int reader_index, /*@unused@*/ int Channel)  status_t OpenUSB(unsigned int reader_index, /*@unused@*/ int Channel)
149  {  {
150            (void)Channel;
151    
152          return OpenUSBByName(reader_index, NULL);          return OpenUSBByName(reader_index, NULL);
153  } /* OpenUSB */  } /* OpenUSB */
154    
# Line 135  status_t OpenUSB(unsigned int reader_ind Line 160  status_t OpenUSB(unsigned int reader_ind
160   ****************************************************************************/   ****************************************************************************/
161  status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)  status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
162  {  {
         static struct usb_bus *busses = NULL;  
163          int alias = 0;          int alias = 0;
164          struct usb_bus *bus;          struct libusb_device_handle *dev_handle;
         struct usb_dev_handle *dev_handle;  
         char keyValue[TOKEN_MAX_VALUE_SIZE];  
         int vendorID, productID;  
165          char infofile[FILENAME_MAX];          char infofile[FILENAME_MAX];
166    #ifndef __APPLE__
167          unsigned int device_vendor, device_product;          unsigned int device_vendor, device_product;
168          char *dirname = NULL, *filename = NULL;  #endif
169            int interface_number = -1;
170            int i;
171          static int previous_reader_index = -1;          static int previous_reader_index = -1;
172            libusb_device **devs, *dev;
173            ssize_t cnt;
174            list_t plist, *values, *ifdVendorID, *ifdProductID, *ifdFriendlyName;
175            int rv;
176    
177          DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);          DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);
178    
179    #ifndef __APPLE__
180          /* device name specified */          /* device name specified */
181          if (device)          if (device)
182          {          {
183                    char *dirname;
184    
185                  /* format: usb:%04x/%04x, vendor, product */                  /* format: usb:%04x/%04x, vendor, product */
186                  if (strncmp("usb:", device, 4) != 0)                  if (strncmp("usb:", device, 4) != 0)
187                  {                  {
# Line 165  status_t OpenUSBByName(unsigned int read Line 196  status_t OpenUSBByName(unsigned int read
196                          return STATUS_UNSUCCESSFUL;                          return STATUS_UNSUCCESSFUL;
197                  }                  }
198    
199                  /* format usb:%04x/%04x:libusb:%s                  /* format usb:%04x/%04x:libhal:%s
200                   * with %s set to %s:%s, dirname, filename */                   * with %s set to
201                  if ((dirname = strstr(device, "libusb:")) != NULL)                   * /org/freedesktop/Hal/devices/usb_device_VID_PID_SERIAL_ifX
202                     * VID is VendorID
203                     * PID is ProductID
204                     * SERIAL is device serial number
205                     * X is the interface number
206                     */
207                    if ((dirname = strstr(device, "libhal:")) != NULL)
208                  {                  {
209                          /* dirname points to the first char after libusb: */                          const char *p;
                         dirname += strlen("libusb:");  
210    
211                          /* search the : (separation) char */  #define HAL_HEADER "usb_device_"
                         filename = strchr(dirname, ':');  
212    
213                          if (filename)                          /* parse the hal string */
214                            if (
215                                    /* search the last '/' char */
216                                    (p = strrchr(dirname, '/'))
217    
218                                    /* if the string starts with "usb_device_" we continue */
219                                    && (0 == strncmp(++p, HAL_HEADER, sizeof(HAL_HEADER)-1))
220                                    /* skip the HAL header */
221                                    && (p += sizeof(HAL_HEADER)-1)
222    
223                                    /* search the last '_' */
224                                    && (p = strrchr(++p, '_'))
225                                    && (0 == strncmp(++p, "if", 2))
226                               )
227                          {                          {
228                                  /* end the dirname string */                                  /* convert the interface number */
229                                  *filename = '\0';                                  interface_number = atoi(p+2);
   
                                 /* filename points to the first char after : */  
                                 filename++;  
230                          }                          }
231                          else                          else
232                          {                                  DEBUG_CRITICAL2("can't parse using libhal scheme: %s", device);
                                 /* parse failed */  
                                 dirname = NULL;  
   
                                 DEBUG_CRITICAL2("can't parse using libusb scheme: %s", device);  
                         }  
233                  }                  }
234          }          }
235    #endif
         if (busses == 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;  
         }  
236    
237          /* is the reader_index already used? */          /* is the reader_index already used? */
238          if (usbDevice[reader_index].handle != NULL)          if (usbDevice[reader_index].dev_handle != NULL)
239          {          {
240                  DEBUG_CRITICAL2("USB driver with index %X already in use",                  DEBUG_CRITICAL2("USB driver with index %X already in use",
241                          reader_index);                          reader_index);
# Line 216  status_t OpenUSBByName(unsigned int read Line 243  status_t OpenUSBByName(unsigned int read
243          }          }
244    
245          /* Info.plist full patch filename */          /* Info.plist full patch filename */
246          snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",          (void)snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
247                  PCSCLITE_HP_DROPDIR, BUNDLE);                  PCSCLITE_HP_DROPDIR, BUNDLE);
248    
249            rv = bundleParse(infofile, &plist);
250            if (rv)
251                    return STATUS_UNSUCCESSFUL;
252    
253    #define GET_KEY(key, values) \
254            rv = LTPBundleFindValueWithKey(&plist, key, &values); \
255            if (rv) \
256            { \
257                    DEBUG_CRITICAL2("Value/Key not defined for " key " in %s", infofile); \
258                    bundleRelease(&plist); \
259                    return STATUS_UNSUCCESSFUL; \
260            } \
261            else \
262                    DEBUG_INFO2(key ": %s", list_get_at(values, 0));
263    
264          /* general driver info */          /* general driver info */
265          if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))          GET_KEY("ifdManufacturerString", values)
266          {          GET_KEY("ifdProductString", values)
267                  DEBUG_CRITICAL2("Manufacturer: %s", keyValue);          GET_KEY("Copyright", values)
268          }  
269          else          if (NULL == ctx)
270                    libusb_init(&ctx);
271    
272            cnt = libusb_get_device_list(ctx, &devs);
273            if (cnt < 0)
274          {          {
275                  DEBUG_CRITICAL2("LTPBundleFindValueWithKey error. Can't find %s?",                  DEBUG_CRITICAL("libusb_get_device_list() failed\n");
                         infofile);  
276                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
277          }          }
278          if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))  
279          {  #define GET_KEYS(key, values) \
280                  DEBUG_CRITICAL2("ProductString: %s", keyValue);          rv = LTPBundleFindValueWithKey(&plist, key, values); \
281          }          if (rv) \
282          else          { \
283                  return STATUS_UNSUCCESSFUL;                  DEBUG_CRITICAL2("Value/Key not defined for " key " in %s", infofile); \
284          if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))                  bundleRelease(&plist); \
285          {                  return STATUS_UNSUCCESSFUL; \
                 DEBUG_CRITICAL2("Copyright: %s", keyValue);  
286          }          }
287          else  
288                  return STATUS_UNSUCCESSFUL;          GET_KEYS("ifdVendorID", &ifdVendorID)
289          vendorID = strlen(keyValue);          GET_KEYS("ifdProductID", &ifdProductID);
290          alias = 0x1D;          GET_KEYS("ifdFriendlyName", &ifdFriendlyName)
         for (; vendorID--;)  
                 alias ^= keyValue[vendorID];  
291    
292          /* for any supported reader */          /* for any supported reader */
293          while (LTPBundleFindValueWithKey(infofile, PCSCLITE_MANUKEY_NAME, keyValue, alias) == 0)          for (alias=0; alias<list_size(ifdVendorID); alias++)
294          {          {
295                  vendorID = strtoul(keyValue, NULL, 0);                  unsigned int vendorID, productID;
296                    char *friendlyName;
297    
298                  if (LTPBundleFindValueWithKey(infofile, PCSCLITE_PRODKEY_NAME, keyValue, alias))                  vendorID = strtoul(list_get_at(ifdVendorID, alias), NULL, 0);
299                          goto end;                  productID = strtoul(list_get_at(ifdProductID, alias), NULL, 0);
300                  productID = strtoul(keyValue, NULL, 0);                  friendlyName = list_get_at(ifdFriendlyName, alias);
   
                 if (LTPBundleFindValueWithKey(infofile, PCSCLITE_NAMEKEY_NAME, keyValue, alias))  
                         goto end;  
   
                 /* go to next supported reader for next round */  
                 alias++;  
301    
302    #ifndef __APPLE__
303                  /* 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 */
304                  if (device                  if (device
305                          && (vendorID != device_vendor || productID != device_product))                          && (vendorID != device_vendor || productID != device_product))
306                          continue;                          continue;
307    #else
308                    /* Leopard puts the friendlyname in the device argument */
309                    if (device && strcmp(device, friendlyName))
310                            continue;
311    #endif
312    
313                  /* on any USB buses */                  /* for every device */
314                  for (bus = busses; bus; bus = bus->next)                  i = 0;
315                    while ((dev = devs[i++]) != NULL)
316                  {                  {
317                          struct usb_device *dev;                          struct libusb_device_descriptor desc;
318                            struct libusb_config_descriptor *config_desc;
319                            uint8_t bus_number = libusb_get_bus_number(dev);
320                            uint8_t device_address = libusb_get_device_address(dev);
321    
322                          /* any device on this bus */                          int r = libusb_get_device_descriptor(dev, &desc);
323                          for (dev = bus->devices; dev; dev = dev->next)                          if (r < 0)
324                          {                          {
325                                  /* device defined by name? */                                  DEBUG_INFO3("failed to get device descriptor for %d/%d",
326                                  if (dirname && (strcmp(dirname, bus->dirname)                                          bus_number, device_address);
327                                          || strcmp(filename, dev->filename)))                                  continue;
328                                          continue;                          }
329    
330                            if (desc.idVendor == vendorID && desc.idProduct == productID)
331                            {
332                                    int already_used;
333                                    const struct libusb_interface *usb_interface = NULL;
334                                    int interface;
335                                    int num = 0;
336    
337    #ifdef USE_COMPOSITE_AS_MULTISLOT
338                                    static int static_interface = 1;
339    
                                 if (dev->descriptor.idVendor == vendorID  
                                         && dev->descriptor.idProduct == productID)  
340                                  {                                  {
341                                          int r, already_used;                                          /* simulate a composite device as when libhal is
342                                          struct usb_interface *usb_interface = NULL;                                           * used */
343                                          int interface;                                          int readerID = (vendorID << 16) + productID;
344    
345                                          /* is it already opened? */                                          if ((GEMALTOPROXDU == readerID)
346                                          already_used = FALSE;                                                  || (GEMALTOPROXSU == readerID))
347                                            {
348                                                            /*
349                                                             * We can't talk to the two CCID interfaces
350                                                             * at the same time (the reader enters a
351                                                             * dead lock). So we simulate a multi slot
352                                                             * reader. By default multi slot readers
353                                                             * can't use the slots at the same time. See
354                                                             * TAG_IFD_SLOT_THREAD_SAFE
355                                                             *
356                                                             * One side effect is that the two readers
357                                                             * are seen by pcscd as one reader so the
358                                                             * interface name is the same for the two.
359                                                             *
360                    * So we have:
361                    * 0: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 00
362                    * 1: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 01
363                    * instead of
364                    * 0: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 00
365                    * 1: Gemalto Prox-DU [Prox-DU Contactless_09A00795] (09A00795) 01 00
366                                                             */
367    
368                                          for (r=0; r<CCID_DRIVER_MAX_READERS; r++)                                                  /* the CCID interfaces are 1 and 2 */
369                                                    interface_number = static_interface;
370                                            }
371                                    }
372    #endif
373                                    /* is it already opened? */
374                                    already_used = FALSE;
375    
376                                    DEBUG_COMM3("Checking device: %d/%d",
377                                            bus_number, device_address);
378                                    for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
379                                    {
380                                            if (usbDevice[r].dev_handle)
381                                          {                                          {
382                                                  if (usbDevice[r].dev)                                                  /* same bus, same address */
383                                                  {                                                  if (usbDevice[r].bus_number == bus_number
384                                                          DEBUG_COMM3("Checking device: %s/%s",                                                          && usbDevice[r].device_address == device_address)
385                                                                  bus->dirname, dev->filename);                                                          already_used = TRUE;
                                                         /* 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;  
                                                 }  
386                                          }                                          }
387                                    }
388    
389                                          /* this reader is already managed by us */                                  /* this reader is already managed by us */
390                                          if (already_used)                                  if (already_used)
391                                    {
392                                            if ((previous_reader_index != -1)
393                                                    && usbDevice[previous_reader_index].dev_handle
394                                                    && (usbDevice[previous_reader_index].bus_number == bus_number)
395                                                    && (usbDevice[previous_reader_index].device_address == device_address)
396                                                    && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)
397                                          {                                          {
398                                                  if ((previous_reader_index != -1)                                                  /* we reuse the same device
399                                                          && (strcmp(usbDevice[previous_reader_index].dev->bus->dirname, bus->dirname)  == 0)                                                   * and the reader is multi-slot */
400                                                          && (strcmp(usbDevice[previous_reader_index].dev->filename, dev->filename) == 0)                                                  usbDevice[reader_index] = usbDevice[previous_reader_index];
401                                                          && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)                                                  /* the other slots do not have the same data rates */
402                                                    if ((GEMCOREPOSPRO == usbDevice[reader_index].ccid.readerID)
403                                                            || (GEMCORESIMPRO == usbDevice[reader_index].ccid.readerID))
404                                                  {                                                  {
405                                                          /* we reuse the same device                                                          usbDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates;
406                                                           * and the reader is multi-slot */                                                          usbDevice[reader_index].ccid.dwMaxDataRate = 125000;
                                                         usbDevice[reader_index] = usbDevice[previous_reader_index];  
                                                         usbDevice[reader_index].ccid.pbSeq = usbDevice[previous_reader_index].ccid.pbSeq;  
                                                         usbDevice[reader_index].ccid.bCurrentSlotIndex++;  
                                                         DEBUG_INFO2("Opening slot: %d",  
                                                                 usbDevice[reader_index].ccid.bCurrentSlotIndex);  
                                                         goto end;  
407                                                  }                                                  }
408                                                  else  
409                                                    *usbDevice[reader_index].nb_opened_slots += 1;
410                                                    usbDevice[reader_index].ccid.bCurrentSlotIndex++;
411                                                    usbDevice[reader_index].ccid.dwSlotStatus =
412                                                            IFD_ICC_PRESENT;
413                                                    DEBUG_INFO2("Opening slot: %d",
414                                                            usbDevice[reader_index].ccid.bCurrentSlotIndex);
415                                                    goto end;
416                                            }
417                                            else
418                                            {
419                                                    /* if an interface number is given by HAL we
420                                                     * continue with this device. */
421                                                    if (-1 == interface_number)
422                                                  {                                                  {
423                                                          DEBUG_INFO3("USB device %s/%s already in use."                                                          DEBUG_INFO3("USB device %d/%d already in use."
424                                                                  " Checking next one.",                                                                  " Checking next one.",
425                                                                  bus->dirname, dev->filename);                                                                  bus_number, device_address);
426                                                            continue;
427                                                  }                                                  }
   
                                                 continue;  
428                                          }                                          }
429                                    }
430    
431                                          DEBUG_COMM3("Trying to open USB bus/device: %s/%s",                                  DEBUG_COMM3("Trying to open USB bus/device: %d/%d",
432                                                   bus->dirname, dev->filename);                                          bus_number, device_address);
433    
434                                          dev_handle = usb_open(dev);                                  r = libusb_open(dev, &dev_handle);
435                                          if (dev_handle == NULL)                                  if (r < 0)
436                                          {                                  {
437                                                  DEBUG_CRITICAL4("Can't usb_open(%s/%s): %s",                                          DEBUG_CRITICAL4("Can't libusb_open(%d/%d): %d",
438                                                          bus->dirname, dev->filename, strerror(errno));                                                  bus_number, device_address, r);
439    
440                                                  continue;                                          continue;
441                                          }                                  }
442    
443                                          /* now we found a free reader and we try to use it */  again:
444                                          if (dev->config == NULL)                                  r = libusb_get_active_config_descriptor(dev, &config_desc);
445                                          {                                  if (r < 0)
446                                                  DEBUG_CRITICAL3("No dev->config found for %s/%s",                                  {
447                                                           bus->dirname, dev->filename);                                          (void)libusb_close(dev_handle);
448                                                  return STATUS_UNSUCCESSFUL;                                          DEBUG_CRITICAL3("Can't get config descriptor on %d/%d",
449                                          }                                                  bus_number, device_address);
450                                            continue;
451                                    }
452    
453                                          usb_interface = get_ccid_usb_interface(dev);                                  usb_interface = get_ccid_usb_interface(config_desc, &num);
454                                          if (usb_interface == NULL)                                  if (usb_interface == NULL)
455                                          {                                  {
456                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",                                          (void)libusb_close(dev_handle);
457                                                          bus->dirname, dev->filename);                                          if (0 == num)
458                                                  return STATUS_UNSUCCESSFUL;                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %d/%d",
459                                          }                                                          bus_number, device_address);
460                                            interface_number = -1;
461                                            continue;
462                                    }
463    
464                                          if (usb_interface->altsetting->extralen != 54)                                  if (usb_interface->altsetting->extra_length != 54)
465                                          {                                  {
466                                                  DEBUG_CRITICAL4("Extra field for %s/%s has a wrong length: %d", bus->dirname, dev->filename, usb_interface->altsetting->extralen);                                          (void)libusb_close(dev_handle);
467                                                  return STATUS_UNSUCCESSFUL;                                          DEBUG_CRITICAL4("Extra field for %d/%d has a wrong length: %d",
468                                          }                                                  bus_number, device_address,
469                                                    usb_interface->altsetting->extra_length);
470                                            return STATUS_UNSUCCESSFUL;
471                                    }
472    
473                                          interface = usb_interface->altsetting->bInterfaceNumber;                                  interface = usb_interface->altsetting->bInterfaceNumber;
474                                          if (usb_claim_interface(dev_handle, interface) < 0)                                  if (interface_number >= 0 && interface != interface_number)
475                                          {                                  {
476                                                  DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",                                          /* an interface was specified and it is not the
477                                                          bus->dirname, dev->filename, strerror(errno));                                           * current one */
478                                                  return STATUS_UNSUCCESSFUL;                                          DEBUG_INFO3("Wrong interface for USB device %d/%d."
479                                          }                                                  " Checking next one.", bus_number, device_address);
480    
481                                            /* check for another CCID interface on the same device */
482                                            num++;
483    
484                                          DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",                                          goto again;
                                                 dev->descriptor.idVendor,  
                                                 dev->descriptor.idProduct, keyValue);  
                                         DEBUG_INFO3("Using USB bus/device: %s/%s",  
                                                  bus->dirname, dev->filename);  
   
                                         /* check for firmware bugs */  
                                         if (ccid_check_firmware(dev))  
                                                 return STATUS_UNSUCCESSFUL;  
   
                                         /* Get Endpoints values*/  
                                         get_end_points(dev, &usbDevice[reader_index]);  
   
                                         /* store device information */  
                                         usbDevice[reader_index].handle = dev_handle;  
                                         usbDevice[reader_index].dev = dev;  
                                         usbDevice[reader_index].interface = interface;  
   
                                         /* 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;  
                                         goto end;  
485                                  }                                  }
486    
487                                    r = libusb_claim_interface(dev_handle, interface);
488                                    if (r < 0)
489                                    {
490                                            (void)libusb_close(dev_handle);
491                                            DEBUG_CRITICAL4("Can't claim interface %d/%d: %d",
492                                                    bus_number, device_address, r);
493                                            interface_number = -1;
494                                            continue;
495                                    }
496    
497                                    DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",
498                                            desc.idVendor, desc.idProduct, friendlyName);
499                                    DEBUG_INFO3("Using USB bus/device: %d/%d",
500                                            bus_number, device_address);
501    
502                                    /* check for firmware bugs */
503                                    if (ccid_check_firmware(&desc))
504                                    {
505                                            (void)libusb_close(dev_handle);
506                                            return STATUS_UNSUCCESSFUL;
507                                    }
508    
509    #ifdef USE_COMPOSITE_AS_MULTISLOT
510                                    /* use the next interface for the next "slot" */
511                                    static_interface++;
512    
513                                    /* reset for a next reader */
514                                    if (static_interface > 2)
515                                            static_interface = 1;
516    #endif
517    
518                                    /* Get Endpoints values*/
519                                    (void)get_end_points(config_desc, &usbDevice[reader_index], num);
520    
521                                    /* store device information */
522                                    usbDevice[reader_index].dev_handle = dev_handle;
523                                    usbDevice[reader_index].bus_number = bus_number;
524                                    usbDevice[reader_index].device_address = device_address;
525                                    usbDevice[reader_index].interface = interface;
526                                    usbDevice[reader_index].real_nb_opened_slots = 1;
527                                    usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
528                                    usbDevice[reader_index].polling_transfer = NULL;
529    
530                                    /* CCID common informations */
531                                    usbDevice[reader_index].ccid.real_bSeq = 0;
532                                    usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq;
533                                    usbDevice[reader_index].ccid.readerID =
534                                            (desc.idVendor << 16) + desc.idProduct;
535                                    usbDevice[reader_index].ccid.dwFeatures = dw2i(usb_interface->altsetting->extra, 40);
536                                    usbDevice[reader_index].ccid.wLcdLayout =
537                                            (usb_interface->altsetting->extra[51] << 8) +
538                                            usb_interface->altsetting->extra[50];
539                                    usbDevice[reader_index].ccid.bPINSupport = usb_interface->altsetting->extra[52];
540                                    usbDevice[reader_index].ccid.dwMaxCCIDMessageLength = dw2i(usb_interface->altsetting->extra, 44);
541                                    usbDevice[reader_index].ccid.dwMaxIFSD = dw2i(usb_interface->altsetting->extra, 28);
542                                    usbDevice[reader_index].ccid.dwDefaultClock = dw2i(usb_interface->altsetting->extra, 10);
543                                    usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);
544                                    usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];
545                                    usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
546                                    usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
547                                    usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index, config_desc, num);
548                                    usbDevice[reader_index].ccid.bInterfaceProtocol = usb_interface->altsetting->bInterfaceProtocol;
549                                    usbDevice[reader_index].ccid.bNumEndpoints = usb_interface->altsetting->bNumEndpoints;
550                                    usbDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT;
551                                    usbDevice[reader_index].ccid.bVoltageSupport = usb_interface->altsetting->extra[5];
552                                    usbDevice[reader_index].ccid.sIFD_serial_number = NULL;
553                                    if (desc.iSerialNumber)
554                                    {
555                                            unsigned char serial[128];
556                                            int ret;
557    
558                                            ret = libusb_get_string_descriptor_ascii(dev_handle,
559                                                            desc.iSerialNumber, serial,
560                                                            sizeof(serial));
561                                            if (ret > 0)
562                                                    usbDevice[reader_index].ccid.sIFD_serial_number
563                                                            = strdup((char *)serial);
564                                    }
565                                    goto end;
566                          }                          }
567                  }                  }
568          }          }
569  end:  end:
570          if (usbDevice[reader_index].handle == NULL)          if (usbDevice[reader_index].dev_handle == NULL)
571                  return STATUS_UNSUCCESSFUL;          {
572                    /* does not work for libusb <= 1.0.8 */
573                    /* libusb_exit(ctx); */
574                    return STATUS_NO_SUCH_DEVICE;
575            }
576    
577            /* free the libusb allocated list & devices */
578            libusb_free_device_list(devs, 1);
579    
580          /* memorise the current reader_index so we can detect          /* memorise the current reader_index so we can detect
581           * a new OpenUSBByName on a multi slot reader */           * a new OpenUSBByName on a multi slot reader */
# Line 429  status_t WriteUSB(unsigned int reader_in Line 594  status_t WriteUSB(unsigned int reader_in
594          unsigned char *buffer)          unsigned char *buffer)
595  {  {
596          int rv;          int rv;
597  #ifdef DEBUG_LEVEL_COMM          int actual_length;
598          char debug_header[] = "-> 121234 ";          char debug_header[] = "-> 121234 ";
599    
600          sprintf(debug_header, "-> %06X ", (int)reader_index);          (void)snprintf(debug_header, sizeof(debug_header), "-> %06X ",
601  #endif                  (int)reader_index);
602    
 #ifdef DEBUG_LEVEL_COMM  
603          DEBUG_XXD(debug_header, buffer, length);          DEBUG_XXD(debug_header, buffer, length);
 #endif  
604    
605          rv = usb_bulk_write(usbDevice[reader_index].handle,          rv = libusb_bulk_transfer(usbDevice[reader_index].dev_handle,
606                  usbDevice[reader_index].bulk_out, (char *)buffer, length,                  usbDevice[reader_index].bulk_out, buffer, length,
607                  USB_WRITE_TIMEOUT);                  &actual_length, USB_WRITE_TIMEOUT);
608    
609          if (rv < 0)          if (rv < 0)
610          {          {
611                  DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",                  DEBUG_CRITICAL5("write failed (%d/%d): %d %s",
612                          usbDevice[reader_index].dev->bus->dirname,                          usbDevice[reader_index].bus_number,
613                          usbDevice[reader_index].dev->filename, strerror(errno));                          usbDevice[reader_index].device_address, rv, strerror(errno));
614    
615                    if (ENODEV == errno)
616                            return STATUS_NO_SUCH_DEVICE;
617    
618                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
619          }          }
620    
# Line 464  status_t ReadUSB(unsigned int reader_ind Line 631  status_t ReadUSB(unsigned int reader_ind
631          unsigned char *buffer)          unsigned char *buffer)
632  {  {
633          int rv;          int rv;
634  #ifdef DEBUG_LEVEL_COMM          int actual_length;
635          char debug_header[] = "<- 121234 ";          char debug_header[] = "<- 121234 ";
636            _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
637            int duplicate_frame = 0;
638    
639          sprintf(debug_header, "<- %06X ", (int)reader_index);  read_again:
640  #endif          (void)snprintf(debug_header, sizeof(debug_header), "<- %06X ",
641                    (int)reader_index);
642          rv = usb_bulk_read(usbDevice[reader_index].handle,  
643                  usbDevice[reader_index].bulk_in, (char *)buffer, *length,          rv = libusb_bulk_transfer(usbDevice[reader_index].dev_handle,
644                  USB_READ_TIMEOUT);                  usbDevice[reader_index].bulk_in, buffer, *length,
645                    &actual_length, usbDevice[reader_index].ccid.readTimeout);
646    
647          if (rv < 0)          if (rv < 0)
648          {          {
649                  *length = 0;                  *length = 0;
650                  DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",                  DEBUG_CRITICAL5("read failed (%d/%d): %d %s",
651                          usbDevice[reader_index].dev->bus->dirname,                          usbDevice[reader_index].bus_number,
652                          usbDevice[reader_index].dev->filename, strerror(errno));                          usbDevice[reader_index].device_address, rv, strerror(errno));
653    
654                    if (ENODEV == errno)
655                            return STATUS_NO_SUCH_DEVICE;
656    
657                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
658          }          }
659    
660          *length = rv;          *length = actual_length;
661    
 #ifdef DEBUG_LEVEL_COMM  
662          DEBUG_XXD(debug_header, buffer, *length);          DEBUG_XXD(debug_header, buffer, *length);
663  #endif  
664    #define BSEQ_OFFSET 6
665            if ((*length >= BSEQ_OFFSET)
666                    && (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1))
667            {
668                    duplicate_frame++;
669                    if (duplicate_frame > 10)
670                    {
671                            DEBUG_CRITICAL("Too many duplicate frame detected");
672                            return STATUS_UNSUCCESSFUL;
673                    }
674                    DEBUG_INFO("Duplicate frame detected");
675                    goto read_again;
676            }
677    
678          return STATUS_SUCCESS;          return STATUS_SUCCESS;
679  } /* ReadUSB */  } /* ReadUSB */
# Line 501  status_t ReadUSB(unsigned int reader_ind Line 687  status_t ReadUSB(unsigned int reader_ind
687  status_t CloseUSB(unsigned int reader_index)  status_t CloseUSB(unsigned int reader_index)
688  {  {
689          /* device not opened */          /* device not opened */
690          if (usbDevice[reader_index].dev == NULL)          if (usbDevice[reader_index].dev_handle == NULL)
691                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
692    
693          DEBUG_COMM3("Closing USB device: %s/%s",          DEBUG_COMM3("Closing USB device: %d/%d",
694                  usbDevice[reader_index].dev->bus->dirname,                  usbDevice[reader_index].bus_number,
695                  usbDevice[reader_index].dev->filename);                  usbDevice[reader_index].device_address);
696    
697          /* reset so that bSeq starts at 0 again */          if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates
698          usb_reset(usbDevice[reader_index].handle);                  && (usbDevice[reader_index].ccid.bCurrentSlotIndex == 0))
699            {
700          usb_release_interface(usbDevice[reader_index].handle,                  free(usbDevice[reader_index].ccid.arrayOfSupportedDataRates);
701                  usbDevice[reader_index].interface);                  usbDevice[reader_index].ccid.arrayOfSupportedDataRates = NULL;
702          usb_close(usbDevice[reader_index].handle);          }
703    
704            /* one slot closed */
705            (*usbDevice[reader_index].nb_opened_slots)--;
706    
707            /* release the allocated ressources for the last slot only */
708            if (0 == *usbDevice[reader_index].nb_opened_slots)
709            {
710                    DEBUG_COMM("Last slot closed. Release resources");
711    
712                    /* reset so that bSeq starts at 0 again */
713                    if (DriverOptions & DRIVER_OPTION_RESET_ON_CLOSE)
714                            (void)libusb_reset_device(usbDevice[reader_index].dev_handle);
715    
716                    (void)libusb_release_interface(usbDevice[reader_index].dev_handle,
717                            usbDevice[reader_index].interface);
718                    (void)libusb_close(usbDevice[reader_index].dev_handle);
719    
720                    /* does not work for libusb <= 1.0.8 */
721                    /* libusb_exit(ctx); */
722            }
723    
724          /* mark the resource unused */          /* mark the resource unused */
725          usbDevice[reader_index].handle = NULL;          usbDevice[reader_index].dev_handle = NULL;
         usbDevice[reader_index].dev = NULL;  
726          usbDevice[reader_index].interface = 0;          usbDevice[reader_index].interface = 0;
727    
728            if (usbDevice[reader_index].ccid.sIFD_serial_number)
729                    free(usbDevice[reader_index].ccid.sIFD_serial_number);
730    
731          return STATUS_SUCCESS;          return STATUS_SUCCESS;
732  } /* CloseUSB */  } /* CloseUSB */
733    
# Line 537  _ccid_descriptor *get_ccid_descriptor(un Line 745  _ccid_descriptor *get_ccid_descriptor(un
745    
746  /*****************************************************************************  /*****************************************************************************
747   *   *
  *                                      get_desc  
  *  
  ****************************************************************************/  
 int get_desc(int lun, usb_dev_handle **handle, struct  
         usb_device **dev)  
 {  
         int reader_index;  
   
         if (-1 == (reader_index = LunToReaderIndex(lun)))  
                 return FALSE;  
   
         *handle = usbDevice[reader_index].handle;  
         *dev = usbDevice[reader_index].dev;  
   
         return TRUE;  
 } /* get_desc */  
   
   
 /*****************************************************************************  
  *  
748   *                                      get_end_points   *                                      get_end_points
749   *   *
750   ****************************************************************************/   ****************************************************************************/
751  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device)  static int get_end_points(struct libusb_config_descriptor *desc,
752            _usbDevice *usbdevice, int num)
753  {  {
754          int i;          int i;
755          int bEndpointAddress;          int bEndpointAddress;
756          struct usb_interface *usb_interface = get_ccid_usb_interface(dev);          const struct libusb_interface *usb_interface;
757    
758            usb_interface = get_ccid_usb_interface(desc, &num);
759    
760          /*          /*
761           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
762           */           */
763          for (i=0; i<3; i++)          for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
764          {          {
765                  if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)                  /* interrupt end point (if available) */
766                    if (usb_interface->altsetting->endpoint[i].bmAttributes
767                            == LIBUSB_TRANSFER_TYPE_INTERRUPT)
768                    {
769                            usbdevice->interrupt =
770                                    usb_interface->altsetting->endpoint[i].bEndpointAddress;
771                          continue;                          continue;
772                    }
773    
774                  bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;                  if (usb_interface->altsetting->endpoint[i].bmAttributes
775                            != LIBUSB_TRANSFER_TYPE_BULK)
776                            continue;
777    
778                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)                  bEndpointAddress =
779                          usb_device->bulk_in = bEndpointAddress;                          usb_interface->altsetting->endpoint[i].bEndpointAddress;
780    
781                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)                  if ((bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
782                          usb_device->bulk_out = bEndpointAddress;                          == LIBUSB_ENDPOINT_IN)
783                            usbdevice->bulk_in = bEndpointAddress;
784    
785                    if ((bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
786                            == LIBUSB_ENDPOINT_OUT)
787                            usbdevice->bulk_out = bEndpointAddress;
788          }          }
789    
790          return 0;          return 0;
# Line 592  static int get_end_points(struct usb_dev Line 796  static int get_end_points(struct usb_dev
796   *                                      get_ccid_usb_interface   *                                      get_ccid_usb_interface
797   *   *
798   ****************************************************************************/   ****************************************************************************/
799  /*@null@*/ struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)  /*@null@*/ EXTERNAL const struct libusb_interface * get_ccid_usb_interface(
800            struct libusb_config_descriptor *desc, int *num)
801  {  {
802          struct usb_interface *usb_interface = NULL;          const struct libusb_interface *usb_interface = NULL;
803            int i;
804    #ifdef O2MICRO_OZ776_PATCH
805            int readerID;
806    #endif
807    
808          /* if multiple interfaces use the first one with CCID class type */          /* if multiple interfaces use the first one with CCID class type */
809          if (dev->config->bNumInterfaces > 1)          for (i = *num; i < desc->bNumInterfaces; i++)
810          {          {
811                  int ii;                  /* CCID Class? */
812                  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  
813  #ifdef ALLOW_PROPRIETARY_CLASS  #ifdef ALLOW_PROPRIETARY_CLASS
814                                  || dev->config->interface[ii].altsetting->bInterfaceClass == 0xff                          || desc->interface[i].altsetting->bInterfaceClass == 0xff
815  #endif  #endif
816                                  )                          )
817                          {                  {
818                                  usb_interface = &dev->config->interface[ii];                          usb_interface = &desc->interface[i];
819                                  break;                          /* store the interface number for further reference */
820                          }                          *num = i;
821                            break;
822                  }                  }
823          }          }
         else  
                 /* only one interface found */  
                 usb_interface = dev->config->interface;  
824    
825  #ifdef O2MICRO_OZ776_PATCH  #ifdef O2MICRO_OZ776_PATCH
826            readerID = (dev->descriptor.idVendor << 16) + dev->descriptor.idProduct;
827          if (usb_interface != NULL          if (usb_interface != NULL
828                  && (OZ776 == (dev->descriptor.idVendor << 16)                  && ((OZ776 == readerID) || (OZ776_7772 == readerID)
829                  + dev->descriptor.idProduct)                  || (REINER_SCT == readerID) || (BLUDRIVEII_CCID == readerID))
830                  && (0 == usb_interface->altsetting->extralen)) /* this is the bug */                  && (0 == usb_interface->altsetting->extra_length)) /* this is the bug */
831          {          {
832                  int i;                  int j;
833                    for (j=0; j<usb_interface->altsetting->bNumEndpoints; j++)
                 for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)  
834                  {                  {
835                          /* find the extra[] array */                          /* find the extra[] array */
836                          if (54 == usb_interface->altsetting->endpoint[i].extralen)                          if (54 == usb_interface->altsetting->endpoint[j].extra_length)
837                          {                          {
838                                  /* get the extra[] from the endpoint */                                  /* get the extra[] from the endpoint */
839                                  usb_interface->altsetting->extralen = 54;                                  usb_interface->altsetting->extra_length = 54;
840                                  usb_interface->altsetting->extra =                                  usb_interface->altsetting->extra =
841                                          usb_interface->altsetting->endpoint[i].extra;                                          usb_interface->altsetting->endpoint[j].extra;
842                                    /* avoid double free on close */
843                                    usb_interface->altsetting->endpoint[j].extra = NULL;
844                                    usb_interface->altsetting->endpoint[j].extra_length = 0;
845                                  break;                                  break;
846                          }                          }
847                  }                  }
# Line 650  static int get_end_points(struct usb_dev Line 857  static int get_end_points(struct usb_dev
857   *                                      ccid_check_firmware   *                                      ccid_check_firmware
858   *   *
859   ****************************************************************************/   ****************************************************************************/
860  int ccid_check_firmware(struct usb_device *dev)  int ccid_check_firmware(struct libusb_device_descriptor *desc)
861  {  {
862          int i;          unsigned int i;
863    
864          for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)          for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)
865          {          {
866                  if (dev->descriptor.idVendor != Bogus_firmwares[i].vendor)                  if (desc->idVendor != Bogus_firmwares[i].vendor)
867                                  continue;                          continue;
868    
869                  if (dev->descriptor.idProduct != Bogus_firmwares[i].product)                  if (desc->idProduct != Bogus_firmwares[i].product)
870                          continue;                          continue;
871    
872                  /* firmware too old and buggy */                  /* firmware too old and buggy */
873                  if (dev->descriptor.bcdDevice < Bogus_firmwares[i].firmware)                  if (desc->bcdDevice < Bogus_firmwares[i].firmware)
874                  {                  {
875                          if (DriverOptions & DRIVER_OPTION_USE_BOGUS_FIRMWARE)                          if (DriverOptions & DRIVER_OPTION_USE_BOGUS_FIRMWARE)
876                          {                          {
877                                  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",
878                                          dev->descriptor.bcdDevice >> 8,                                          desc->bcdDevice >> 8, desc->bcdDevice & 0xFF);
                                         dev->descriptor.bcdDevice & 0xFF);  
879                                  return FALSE;                                  return FALSE;
880                          }                          }
881                          else                          else
882                          {                          {
883                                  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.",
884                                          dev->descriptor.bcdDevice >> 8,                                          desc->bcdDevice >> 8, desc->bcdDevice & 0xFF);
                                         dev->descriptor.bcdDevice & 0xFF);  
885                                  return TRUE;                                  return TRUE;
886                          }                          }
887                  }                  }
# Line 686  int ccid_check_firmware(struct usb_devic Line 891  int ccid_check_firmware(struct usb_devic
891          return FALSE;          return FALSE;
892  } /* ccid_check_firmware */  } /* ccid_check_firmware */
893    
894    
895    /*****************************************************************************
896     *
897     *                                      get_data_rates
898     *
899     ****************************************************************************/
900    static unsigned int *get_data_rates(unsigned int reader_index,
901            struct libusb_config_descriptor *desc, int num)
902    {
903            int n, i, len;
904            unsigned char buffer[256*sizeof(int)];  /* maximum is 256 records */
905            unsigned int *int_array;
906    
907            /* See CCID 3.7.3 page 25 */
908            n = ControlUSB(reader_index,
909                    0xA1, /* request type */
910                    0x03, /* GET_DATA_RATES */
911                    0x00, /* value */
912                    buffer, sizeof(buffer));
913    
914            /* we got an error? */
915            if (n <= 0)
916            {
917                    DEBUG_INFO2("IFD does not support GET_DATA_RATES request: %d", n);
918                    return NULL;
919            }
920    
921            /* we got a strange value */
922            if (n % 4)
923            {
924                    DEBUG_INFO2("Wrong GET DATA RATES size: %d", n);
925                    return NULL;
926            }
927    
928            /* allocate the buffer (including the end marker) */
929            n /= sizeof(int);
930    
931            /* we do not get the expected number of data rates */
932            len = get_ccid_usb_interface(desc, &num)->altsetting->extra[27]; /* bNumDataRatesSupported */
933            if ((n != len) && len)
934            {
935                    DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);
936    
937                    /* we got more data than expected */
938                    if (n > len)
939                            n = len;
940            }
941    
942            int_array = calloc(n+1, sizeof(int));
943            if (NULL == int_array)
944            {
945                    DEBUG_CRITICAL("Memory allocation failed");
946                    return NULL;
947            }
948    
949            /* convert in correct endianess */
950            for (i=0; i<n; i++)
951            {
952                    int_array[i] = dw2i(buffer, i*4);
953                    DEBUG_INFO2("declared: %d bps", int_array[i]);
954            }
955    
956            /* end of array marker */
957            int_array[i] = 0;
958    
959            return int_array;
960    } /* get_data_rates */
961    
962    
963    /*****************************************************************************
964     *
965     *                                      ControlUSB
966     *
967     ****************************************************************************/
968    int ControlUSB(int reader_index, int requesttype, int request, int value,
969            unsigned char *bytes, unsigned int size)
970    {
971            int ret;
972    
973            DEBUG_COMM2("request: 0x%02X", request);
974    
975            if (0 == (requesttype & 0x80))
976                    DEBUG_XXD("send: ", bytes, size);
977    
978            ret = libusb_control_transfer(usbDevice[reader_index].dev_handle,
979                    requesttype, request, value, usbDevice[reader_index].interface,
980                    bytes, size, usbDevice[reader_index].ccid.readTimeout);
981    
982            if (requesttype & 0x80)
983                    DEBUG_XXD("receive: ", bytes, ret);
984    
985            return ret;
986    } /* ControlUSB */
987    
988    /*****************************************************************************
989     *
990     *                                      Transfer is complete
991     *
992     ****************************************************************************/
993    static void bulk_transfer_cb(struct libusb_transfer *transfer)
994    {
995            int *completed = transfer->user_data;
996            *completed = 1;
997            /* caller interprets results and frees transfer */
998    }
999    
1000    /*****************************************************************************
1001     *
1002     *                                      InterruptRead
1003     *
1004     ****************************************************************************/
1005    int InterruptRead(int reader_index, int timeout /* in ms */)
1006    {
1007            int ret, actual_length;
1008            int return_value = IFD_SUCCESS;
1009            unsigned char buffer[8];
1010            struct libusb_transfer *transfer;
1011            int completed = 0;
1012    
1013            DEBUG_PERIODIC2("before (%d)", reader_index);
1014    
1015            transfer = libusb_alloc_transfer(0);
1016            if (NULL == transfer)
1017                    return LIBUSB_ERROR_NO_MEM;
1018    
1019            libusb_fill_bulk_transfer(transfer,
1020                    usbDevice[reader_index].dev_handle,
1021                    usbDevice[reader_index].interrupt, buffer, sizeof(buffer),
1022                    bulk_transfer_cb, &completed, timeout);
1023            transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT;
1024    
1025            ret = libusb_submit_transfer(transfer);
1026            if (ret < 0) {
1027                    libusb_free_transfer(transfer);
1028                    return ret;
1029            }
1030    
1031            usbDevice[reader_index].polling_transfer = transfer;
1032    
1033            while (!completed)
1034            {
1035                    ret = libusb_handle_events(ctx);
1036                    if (ret < 0)
1037                    {
1038                            if (ret == LIBUSB_ERROR_INTERRUPTED)
1039                                    continue;
1040                            libusb_cancel_transfer(transfer);
1041                            while (!completed)
1042                                    if (libusb_handle_events(ctx) < 0)
1043                                            break;
1044                            libusb_free_transfer(transfer);
1045                            return ret;
1046                    }
1047            }
1048    
1049            actual_length = transfer->actual_length;
1050            ret = transfer->status;
1051    
1052            usbDevice[reader_index].polling_transfer = NULL;
1053            libusb_free_transfer(transfer);
1054    
1055            DEBUG_PERIODIC3("after (%d) (%d)", reader_index, ret);
1056    
1057            switch (ret)
1058            {
1059                    case LIBUSB_TRANSFER_COMPLETED:
1060                            DEBUG_XXD("NotifySlotChange: ", buffer, actual_length);
1061                            break;
1062    
1063                    case LIBUSB_TRANSFER_TIMED_OUT:
1064                            break;
1065    
1066                    default:
1067                            /* if libusb_interrupt_transfer() times out we get EILSEQ or EAGAIN */
1068                            DEBUG_COMM4("InterruptRead (%d/%d): %s",
1069                                    usbDevice[reader_index].bus_number,
1070                                    usbDevice[reader_index].device_address, strerror(errno));
1071                            return_value = IFD_COMMUNICATION_ERROR;
1072            }
1073    
1074            return return_value;
1075    } /* InterruptRead */
1076    
1077    
1078    /*****************************************************************************
1079     *
1080     *                                      Stop the async loop
1081     *
1082     ****************************************************************************/
1083    void InterruptStop(int reader_index)
1084    {
1085            struct libusb_transfer *transfer;
1086    
1087            transfer = usbDevice[reader_index].polling_transfer;
1088            if (transfer)
1089            {
1090                    int ret;
1091    
1092                    ret = libusb_cancel_transfer(transfer);
1093                    if (ret < 0)
1094                            DEBUG_CRITICAL2("libusb_cancel_transfer failed: %d", ret);
1095            }
1096    } /* InterruptStop */
1097    

Legend:
Removed from v.1327  
changed lines
  Added in v.5205

  ViewVC Help
Powered by ViewVC 1.1.5