/[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 694 by rousseau, Thu Feb 12 16:09:32 2004 UTC revision 1804 by rousseau, Tue Jan 17 19:57:11 2006 UTC
# Line 2  Line 2 
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-2004   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
16      along with this program; if not, write to the Free Software      License along with this library; if not, write to the Free Software
17      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
18  */  */
19    
20  /*  /*
# Line 26  Line 26 
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
30    # include <sys/types.h>
31    # endif
32  #include <usb.h>  #include <usb.h>
33    
34  #include "pcscdefines.h"  #include "ccid.h"
35  #include "config.h"  #include "config.h"
36  #include "debug.h"  #include "debug.h"
37    #include "defs.h"
38  #include "utils.h"  #include "utils.h"
39  #include "parser.h"  #include "parser.h"
40  #include "ccid.h"  #include "ccid_ifdhandler.h"
41    
42    
 /* 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 */  
   
43  /* write timeout  /* write timeout
44   * 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 */
45  #define USB_WRITE_TIMEOUT (5 * 1000)  /* 5 seconds timeout */  #define USB_WRITE_TIMEOUT (5 * 1000)  /* 5 seconds timeout */
46    
47    /*
48     * Proprietary USB Class (0xFF) are (or are not) accepted
49     * A proprietary class is used for devices released before the final CCID
50     * specifications were ready.
51     * We should not have problems with non CCID devices becasue the
52     * Manufacturer and Product ID are also used to identify the device */
53    #define ALLOW_PROPRIETARY_CLASS
54    
55    /*
56     * The O2Micro OZ776S reader has a wrong USB descriptor
57     * The extra[] field is associated with the last endpoint instead of the
58     * main USB descriptor
59     */
60    #define O2MICRO_OZ776_PATCH
61    
62  #define BUS_DEVICE_STRSIZE 32  #define BUS_DEVICE_STRSIZE 32
63    
# Line 53  typedef struct Line 65  typedef struct
65  {  {
66          usb_dev_handle *handle;          usb_dev_handle *handle;
67          struct usb_device *dev;          struct usb_device *dev;
68            int interface;
69    
70          /*          /*
71           * Endpoints           * Endpoints
# Line 60  typedef struct Line 73  typedef struct
73          int bulk_in;          int bulk_in;
74          int bulk_out;          int bulk_out;
75    
76            /* Number of slots using the same device */
77            int real_nb_opened_slots;
78            int *nb_opened_slots;
79    
80          /*          /*
81           * CCID infos common to USB and serial           * CCID infos common to USB and serial
82           */           */
# Line 70  typedef struct Line 87  typedef struct
87  /* The _usbDevice structure must be defined before including ccid_usb.h */  /* The _usbDevice structure must be defined before including ccid_usb.h */
88  #include "ccid_usb.h"  #include "ccid_usb.h"
89    
90  static _usbDevice usbDevice[PCSCLITE_MAX_READERS] = {  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device);
91          [ 0 ... (PCSCLITE_MAX_READERS-1) ] = { NULL, NULL, 0, 0 }  int ccid_check_firmware(struct usb_device *dev);
92  };  static unsigned int *get_data_rates(unsigned int reader_index);
93    
94    /* ne need to initialize to 0 since it is static */
95    static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];
96    
97  #define PCSCLITE_MANUKEY_NAME                   "ifdVendorID"  #define PCSCLITE_MANUKEY_NAME                   "ifdVendorID"
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            { 0x0b97, 0x7762, 0x0111 },     /* Oz776S */ /* the firmware version if not correct since I don't have received a working reader yet */
110            { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */
111            { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */
112            { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */
113            { 0x04e6, 0xe003, 0x0504 },     /* SPR 532 */
114            { 0x0D46, 0x3001, 0x0037 },     /* KAAN Base */
115            { 0x0D46, 0x3002, 0x0037 },     /* KAAN Advanced */
116    };
117    
118    
119  /*****************************************************************************  /*****************************************************************************
120   *   *
121   *                                      OpenUSB   *                                      OpenUSB
122   *   *
123   ****************************************************************************/   ****************************************************************************/
124  status_t OpenUSB(int lun, int Channel)  status_t OpenUSB(unsigned int reader_index, /*@unused@*/ int Channel)
125  {  {
126          return OpenUSBByName(lun, NULL);          return OpenUSBByName(reader_index, NULL);
127  } /* OpenUSB */  } /* OpenUSB */
128    
129    
# Line 95  status_t OpenUSB(int lun, int Channel) Line 132  status_t OpenUSB(int lun, int Channel)
132   *                                      OpenUSBByName   *                                      OpenUSBByName
133   *   *
134   ****************************************************************************/   ****************************************************************************/
135  status_t OpenUSBByName(int lun, char *device)  status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
136  {  {
137          static struct usb_bus *busses = NULL;          static struct usb_bus *busses = NULL;
         int reader = LunToReaderIndex(lun);  
138          int alias = 0;          int alias = 0;
139          struct usb_bus *bus;          struct usb_bus *bus;
140          struct usb_dev_handle *dev_handle;          struct usb_dev_handle *dev_handle;
141          char keyValue[TOKEN_MAX_VALUE_SIZE];          char keyValue[TOKEN_MAX_VALUE_SIZE];
142          int vendorID, productID;          unsigned int vendorID, productID;
143          char infofile[FILENAME_MAX];          char infofile[FILENAME_MAX];
144          int device_vendor, device_product;          unsigned int device_vendor, device_product;
145            char *dirname = NULL, *filename = NULL;
146            static int previous_reader_index = -1;
147    
148          DEBUG_COMM3("Lun: %X, Device: %s", lun, device);          DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);
149    
150          /* device name specified */          /* device name specified */
151          if (device)          if (device)
152          {          {
153                    /* format: usb:%04x/%04x, vendor, product */
154                  if (strncmp("usb:", device, 4) != 0)                  if (strncmp("usb:", device, 4) != 0)
155                  {                  {
156                          DEBUG_CRITICAL2("device name does not start with \"usb:\": %s",                          DEBUG_CRITICAL2("device name does not start with \"usb:\": %s",
# Line 124  status_t OpenUSBByName(int lun, char *de Line 163  status_t OpenUSBByName(int lun, char *de
163                          DEBUG_CRITICAL2("device name can't be parsed: %s", device);                          DEBUG_CRITICAL2("device name can't be parsed: %s", device);
164                          return STATUS_UNSUCCESSFUL;                          return STATUS_UNSUCCESSFUL;
165                  }                  }
166    
167                    /* format usb:%04x/%04x:libusb:%s
168                     * with %s set to %s:%s, dirname, filename */
169                    if ((dirname = strstr(device, "libusb:")) != NULL)
170                    {
171                            /* dirname points to the first char after libusb: */
172                            dirname += strlen("libusb:");
173    
174                            /* search the : (separation) char */
175                            filename = strchr(dirname, ':');
176    
177                            if (filename)
178                            {
179                                    /* end the dirname string */
180                                    *filename = '\0';
181    
182                                    /* filename points to the first char after : */
183                                    filename++;
184                            }
185                            else
186                            {
187                                    /* parse failed */
188                                    dirname = NULL;
189    
190                                    DEBUG_CRITICAL2("can't parse using libusb scheme: %s", device);
191                            }
192                    }
193          }          }
194    
195          if (busses == NULL)          if (busses == NULL)
# Line 140  status_t OpenUSBByName(int lun, char *de Line 206  status_t OpenUSBByName(int lun, char *de
206                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
207          }          }
208    
209          /* is the lun already used? */          /* is the reader_index already used? */
210          if (usbDevice[reader].handle != NULL)          if (usbDevice[reader_index].handle != NULL)
211          {          {
212                  DEBUG_CRITICAL2("USB driver with lun %X already in use", lun);                  DEBUG_CRITICAL2("USB driver with index %X already in use",
213                            reader_index);
214                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
215          }          }
216    
# Line 153  status_t OpenUSBByName(int lun, char *de Line 220  status_t OpenUSBByName(int lun, char *de
220    
221          /* general driver info */          /* general driver info */
222          if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))
223                  DEBUG_CRITICAL2("Manufacturer: %s", keyValue);          {
224                    DEBUG_INFO2("Manufacturer: %s", keyValue);
225            }
226          else          else
227          {          {
228                  DEBUG_CRITICAL2("LTPBundleFindValueWithKey error. Can't find %s?",                  DEBUG_INFO2("LTPBundleFindValueWithKey error. Can't find %s?",
229                          infofile);                          infofile);
230                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
231          }          }
232          if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))
233                  DEBUG_CRITICAL2("ProductString: %s", keyValue);          {
234                    DEBUG_INFO2("ProductString: %s", keyValue);
235            }
236          else          else
237                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
238          if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))
239                  DEBUG_CRITICAL2("Copyright: %s", keyValue);          {
240                    DEBUG_INFO2("Copyright: %s", keyValue);
241            }
242          else          else
243                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
244          vendorID = strlen(keyValue);          vendorID = strlen(keyValue);
# Line 176  status_t OpenUSBByName(int lun, char *de Line 249  status_t OpenUSBByName(int lun, char *de
249          /* for any supported reader */          /* for any supported reader */
250          while (LTPBundleFindValueWithKey(infofile, PCSCLITE_MANUKEY_NAME, keyValue, alias) == 0)          while (LTPBundleFindValueWithKey(infofile, PCSCLITE_MANUKEY_NAME, keyValue, alias) == 0)
251          {          {
252                  vendorID = strtoul(keyValue, 0, 16);                  vendorID = strtoul(keyValue, NULL, 0);
253    
254                  if (LTPBundleFindValueWithKey(infofile, PCSCLITE_PRODKEY_NAME, keyValue, alias))                  if (LTPBundleFindValueWithKey(infofile, PCSCLITE_PRODKEY_NAME, keyValue, alias))
255                          goto end;                          goto end;
256                  productID = strtoul(keyValue, 0, 16);                  productID = strtoul(keyValue, NULL, 0);
257    
258                  if (LTPBundleFindValueWithKey(infofile, PCSCLITE_NAMEKEY_NAME, keyValue, alias))                  if (LTPBundleFindValueWithKey(infofile, PCSCLITE_NAMEKEY_NAME, keyValue, alias))
259                          goto end;                          goto end;
# Line 201  status_t OpenUSBByName(int lun, char *de Line 274  status_t OpenUSBByName(int lun, char *de
274                          /* any device on this bus */                          /* any device on this bus */
275                          for (dev = bus->devices; dev; dev = dev->next)                          for (dev = bus->devices; dev; dev = dev->next)
276                          {                          {
277                                    /* device defined by name? */
278                                    if (dirname && (strcmp(dirname, bus->dirname)
279                                            || strcmp(filename, dev->filename)))
280                                            continue;
281    
282                                  if (dev->descriptor.idVendor == vendorID                                  if (dev->descriptor.idVendor == vendorID
283                                          && dev->descriptor.idProduct == productID)                                          && dev->descriptor.idProduct == productID)
284                                  {                                  {
# Line 211  status_t OpenUSBByName(int lun, char *de Line 289  status_t OpenUSBByName(int lun, char *de
289                                          /* is it already opened? */                                          /* is it already opened? */
290                                          already_used = FALSE;                                          already_used = FALSE;
291    
292                                          for (r=0; r<PCSCLITE_MAX_READERS; r++)                                          for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
293                                          {                                          {
294                                                  if (usbDevice[r].dev)                                                  if (usbDevice[r].dev)
295                                                  {                                                  {
# Line 226  status_t OpenUSBByName(int lun, char *de Line 304  status_t OpenUSBByName(int lun, char *de
304                                          /* this reader is already managed by us */                                          /* this reader is already managed by us */
305                                          if (already_used)                                          if (already_used)
306                                          {                                          {
307                                                  DEBUG_INFO3("USB device %s/%s already in use. Checking next one.",                                                  if ((previous_reader_index != -1)
308                                                          bus->dirname, dev->filename);                                                          && usbDevice[previous_reader_index].dev
309                                                            && (strcmp(usbDevice[previous_reader_index].dev->bus->dirname, bus->dirname)  == 0)
310                                                            && (strcmp(usbDevice[previous_reader_index].dev->filename, dev->filename) == 0)
311                                                            && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)
312                                                    {
313                                                            /* we reuse the same device
314                                                             * and the reader is multi-slot */
315                                                            usbDevice[reader_index] = usbDevice[previous_reader_index];
316                                                            *usbDevice[reader_index].nb_opened_slots += 1;
317                                                            usbDevice[reader_index].ccid.bCurrentSlotIndex++;
318                                                            DEBUG_INFO2("Opening slot: %d",
319                                                                    usbDevice[reader_index].ccid.bCurrentSlotIndex);
320                                                            goto end;
321                                                    }
322                                                    else
323                                                    {
324                                                            DEBUG_INFO3("USB device %s/%s already in use."
325                                                                    " Checking next one.",
326                                                                    bus->dirname, dev->filename);
327                                                    }
328    
329                                                  continue;                                                  continue;
330                                          }                                          }
# Line 247  status_t OpenUSBByName(int lun, char *de Line 344  status_t OpenUSBByName(int lun, char *de
344                                          /* now we found a free reader and we try to use it */                                          /* now we found a free reader and we try to use it */
345                                          if (dev->config == NULL)                                          if (dev->config == NULL)
346                                          {                                          {
347                                                    usb_close(dev_handle);
348                                                  DEBUG_CRITICAL3("No dev->config found for %s/%s",                                                  DEBUG_CRITICAL3("No dev->config found for %s/%s",
349                                                           bus->dirname, dev->filename);                                                           bus->dirname, dev->filename);
350                                                  return STATUS_UNSUCCESSFUL;                                                  return STATUS_UNSUCCESSFUL;
# Line 255  status_t OpenUSBByName(int lun, char *de Line 353  status_t OpenUSBByName(int lun, char *de
353                                          usb_interface = get_ccid_usb_interface(dev);                                          usb_interface = get_ccid_usb_interface(dev);
354                                          if (usb_interface == NULL)                                          if (usb_interface == NULL)
355                                          {                                          {
356                                                    usb_close(dev_handle);
357                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",
358                                                          bus->dirname, dev->filename);                                                          bus->dirname, dev->filename);
359                                                  return STATUS_UNSUCCESSFUL;                                                  return STATUS_UNSUCCESSFUL;
# Line 262  status_t OpenUSBByName(int lun, char *de Line 361  status_t OpenUSBByName(int lun, char *de
361    
362                                          if (usb_interface->altsetting->extralen != 54)                                          if (usb_interface->altsetting->extralen != 54)
363                                          {                                          {
364                                                    usb_close(dev_handle);
365                                                  DEBUG_CRITICAL4("Extra field for %s/%s has a wrong length: %d", bus->dirname, dev->filename, usb_interface->altsetting->extralen);                                                  DEBUG_CRITICAL4("Extra field for %s/%s has a wrong length: %d", bus->dirname, dev->filename, usb_interface->altsetting->extralen);
366                                                  return STATUS_UNSUCCESSFUL;                                                  return STATUS_UNSUCCESSFUL;
367                                          }                                          }
# Line 269  status_t OpenUSBByName(int lun, char *de Line 369  status_t OpenUSBByName(int lun, char *de
369                                          interface = usb_interface->altsetting->bInterfaceNumber;                                          interface = usb_interface->altsetting->bInterfaceNumber;
370                                          if (usb_claim_interface(dev_handle, interface) < 0)                                          if (usb_claim_interface(dev_handle, interface) < 0)
371                                          {                                          {
372                                                    usb_close(dev_handle);
373                                                  DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",                                                  DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",
374                                                          bus->dirname, dev->filename, strerror(errno));                                                          bus->dirname, dev->filename, strerror(errno));
375                                                  return STATUS_UNSUCCESSFUL;                                                  return STATUS_UNSUCCESSFUL;
# Line 280  status_t OpenUSBByName(int lun, char *de Line 381  status_t OpenUSBByName(int lun, char *de
381                                          DEBUG_INFO3("Using USB bus/device: %s/%s",                                          DEBUG_INFO3("Using USB bus/device: %s/%s",
382                                                   bus->dirname, dev->filename);                                                   bus->dirname, dev->filename);
383    
384                                            /* check for firmware bugs */
385                                            if (ccid_check_firmware(dev))
386                                            {
387                                                    usb_close(dev_handle);
388                                                    return STATUS_UNSUCCESSFUL;
389                                            }
390    
391                                          /* Get Endpoints values*/                                          /* Get Endpoints values*/
392                                          get_end_points(dev, &usbDevice[reader]);                                          get_end_points(dev, &usbDevice[reader_index]);
393    
394                                          /* store device information */                                          /* store device information */
395                                          usbDevice[reader].handle = dev_handle;                                          usbDevice[reader_index].handle = dev_handle;
396                                          usbDevice[reader].dev = dev;                                          usbDevice[reader_index].dev = dev;
397                                            usbDevice[reader_index].interface = interface;
398                                            usbDevice[reader_index].real_nb_opened_slots = 1;
399                                            usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
400    
401                                          /* CCID common informations */                                          /* CCID common informations */
402                                          usbDevice[reader].ccid.bSeq = 0;                                          usbDevice[reader_index].ccid.real_bSeq = 0;
403                                          usbDevice[reader].ccid.readerID =                                          usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq;
404                                            usbDevice[reader_index].ccid.readerID =
405                                                  (dev->descriptor.idVendor << 16) +                                                  (dev->descriptor.idVendor << 16) +
406                                                  dev->descriptor.idProduct;                                                  dev->descriptor.idProduct;
407                                          usbDevice[reader].ccid.dwFeatures = dw2i(usb_interface->altsetting->extra, 40);                                          usbDevice[reader_index].ccid.dwFeatures = dw2i(usb_interface->altsetting->extra, 40);
408                                          usbDevice[reader].ccid.dwMaxCCIDMessageLength = dw2i(usb_interface->altsetting->extra, 44);                                          usbDevice[reader_index].ccid.bPINSupport = usb_interface->altsetting->extra[52];
409                                          usbDevice[reader].ccid.dwMaxIFSD = dw2i(usb_interface->altsetting->extra, 28);                                          usbDevice[reader_index].ccid.dwMaxCCIDMessageLength = dw2i(usb_interface->altsetting->extra, 44);
410                                          usbDevice[reader].ccid.dwDefaultClock = dw2i(usb_interface->altsetting->extra, 10);                                          usbDevice[reader_index].ccid.dwMaxIFSD = dw2i(usb_interface->altsetting->extra, 28);
411                                          usbDevice[reader].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);                                          usbDevice[reader_index].ccid.dwDefaultClock = dw2i(usb_interface->altsetting->extra, 10);
412                                            usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);
413                                            usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];
414                                            usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
415                                            usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
416                                            usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index);
417                                          goto end;                                          goto end;
418                                  }                                  }
419                          }                          }
420                  }                  }
421          }          }
422  end:  end:
423          if (usbDevice[reader].handle == NULL)          if (usbDevice[reader_index].handle == NULL)
424                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
425    
426            /* memorise the current reader_index so we can detect
427             * a new OpenUSBByName on a multi slot reader */
428            previous_reader_index = reader_index;
429    
430          return STATUS_SUCCESS;          return STATUS_SUCCESS;
431  } /* OpenUSBByName */  } /* OpenUSBByName */
432    
# Line 316  end: Line 436  end:
436   *                                      WriteUSB   *                                      WriteUSB
437   *   *
438   ****************************************************************************/   ****************************************************************************/
439  status_t WriteUSB(int lun, int length, unsigned char *buffer)  status_t WriteUSB(unsigned int reader_index, unsigned int length,
440            unsigned char *buffer)
441  {  {
442          int rv;          int rv;
         int reader = LunToReaderIndex(lun);  
 #ifdef DEBUG_LEVEL_COMM  
443          char debug_header[] = "-> 121234 ";          char debug_header[] = "-> 121234 ";
444    
445          sprintf(debug_header, "-> %06X ", (int)lun);          sprintf(debug_header, "-> %06X ", (int)reader_index);
 #endif  
446    
 #ifdef DEBUG_LEVEL_COMM  
447          DEBUG_XXD(debug_header, buffer, length);          DEBUG_XXD(debug_header, buffer, length);
 #endif  
448    
449          rv = usb_bulk_write(usbDevice[reader].handle, usbDevice[reader].bulk_out, buffer, length, USB_WRITE_TIMEOUT);          rv = usb_bulk_write(usbDevice[reader_index].handle,
450                    usbDevice[reader_index].bulk_out, (char *)buffer, length,
451                    USB_WRITE_TIMEOUT);
452    
453          if (rv < 0)          if (rv < 0)
454          {          {
455                  DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",                  if (usbDevice[reader_index].dev->bus)
456                          usbDevice[reader].dev->bus->dirname,                  {
457                          usbDevice[reader].dev->filename, strerror(errno));                          DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",
458                                    usbDevice[reader_index].dev->bus->dirname,
459                                    usbDevice[reader_index].dev->filename, strerror(errno));
460                    }
461                    else
462                            DEBUG_CRITICAL2("usb_bulk_write(no device): %s", strerror(errno));
463    
464                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
465          }          }
466    
# Line 349  status_t WriteUSB(int lun, int length, u Line 473  status_t WriteUSB(int lun, int length, u
473   *                                      ReadUSB   *                                      ReadUSB
474   *   *
475   ****************************************************************************/   ****************************************************************************/
476  status_t ReadUSB(int lun, int * length, unsigned char *buffer)  status_t ReadUSB(unsigned int reader_index, unsigned int * length,
477            unsigned char *buffer)
478  {  {
479          int rv;          int rv;
         int reader = LunToReaderIndex(lun);  
 #ifdef DEBUG_LEVEL_COMM  
480          char debug_header[] = "<- 121234 ";          char debug_header[] = "<- 121234 ";
481    
482          sprintf(debug_header, "<- %06X ", (int)lun);          sprintf(debug_header, "<- %06X ", (int)reader_index);
 #endif  
   
483    
484          rv = usb_bulk_read(usbDevice[reader].handle, usbDevice[reader].bulk_in, buffer, *length, USB_READ_TIMEOUT);          rv = usb_bulk_read(usbDevice[reader_index].handle,
485          *length = rv;                  usbDevice[reader_index].bulk_in, (char *)buffer, *length,
486                    usbDevice[reader_index].ccid.readTimeout * 1000);
487    
488          if (rv < 0)          if (rv < 0)
489          {          {
490                    *length = 0;
491                  DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",                  DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",
492                          usbDevice[reader].dev->bus->dirname,                          usbDevice[reader_index].dev->bus->dirname,
493                          usbDevice[reader].dev->filename, strerror(errno));                          usbDevice[reader_index].dev->filename, strerror(errno));
494                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
495          }          }
496    
497  #ifdef DEBUG_LEVEL_COMM          *length = rv;
498    
499          DEBUG_XXD(debug_header, buffer, *length);          DEBUG_XXD(debug_header, buffer, *length);
 #endif  
500    
501          return STATUS_SUCCESS;          return STATUS_SUCCESS;
502  } /* ReadUSB */  } /* ReadUSB */
# Line 384  status_t ReadUSB(int lun, int * length, Line 507  status_t ReadUSB(int lun, int * length,
507   *                                      CloseUSB   *                                      CloseUSB
508   *   *
509   ****************************************************************************/   ****************************************************************************/
510  status_t CloseUSB(int lun)  status_t CloseUSB(unsigned int reader_index)
511  {  {
         struct usb_interface *usb_interface;  
         int interface;  
         int reader = LunToReaderIndex(lun);  
   
512          /* device not opened */          /* device not opened */
513          if (usbDevice[reader].dev == NULL)          if (usbDevice[reader_index].dev == NULL)
514                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
515    
516          DEBUG_COMM3("Closing USB device: %s/%s",          DEBUG_COMM3("Closing USB device: %s/%s",
517                  usbDevice[reader].dev->bus->dirname, usbDevice[reader].dev->filename);                  usbDevice[reader_index].dev->bus->dirname,
518                    usbDevice[reader_index].dev->filename);
519    
520          usb_interface = get_ccid_usb_interface(usbDevice[reader].dev);          /* one slot closed */
521          interface = usb_interface ?          (*usbDevice[reader_index].nb_opened_slots)--;
522                  usb_interface->altsetting->bInterfaceNumber :  
523                  usbDevice[reader].dev->config->interface->altsetting->bInterfaceNumber;          /* release the allocated ressources for the last slot only */
524            if (0 == *usbDevice[reader_index].nb_opened_slots)
525          usb_release_interface(usbDevice[reader].handle, interface);          {
526                    DEBUG_COMM("Last slot closed. Release resources");
527    
528          usb_reset(usbDevice[reader].handle);                  if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates)
529          usb_close(usbDevice[reader].handle);                          free(usbDevice[reader_index].ccid.arrayOfSupportedDataRates);
530    
531                    /* reset so that bSeq starts at 0 again */
532                    if (DriverOptions & DRIVER_OPTION_RESET_ON_CLOSE)
533                            usb_reset(usbDevice[reader_index].handle);
534    
535                    usb_release_interface(usbDevice[reader_index].handle,
536                            usbDevice[reader_index].interface);
537                    usb_close(usbDevice[reader_index].handle);
538            }
539    
540          /* mark the resource unused */          /* mark the resource unused */
541          usbDevice[reader].handle = NULL;          usbDevice[reader_index].handle = NULL;
542          usbDevice[reader].dev = NULL;          usbDevice[reader_index].dev = NULL;
543            usbDevice[reader_index].interface = 0;
544    
545          return STATUS_SUCCESS;          return STATUS_SUCCESS;
546  } /* CloseUSB */  } /* CloseUSB */
# Line 420  status_t CloseUSB(int lun) Line 551  status_t CloseUSB(int lun)
551   *                                      get_ccid_descriptor   *                                      get_ccid_descriptor
552   *   *
553   ****************************************************************************/   ****************************************************************************/
554  _ccid_descriptor *get_ccid_descriptor(int lun)  _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
555  {  {
556          return &usbDevice[LunToReaderIndex(lun)].ccid;          return &usbDevice[reader_index].ccid;
557  } /* get_ccid_descriptor */  } /* get_ccid_descriptor */
558    
559    
# Line 431  _ccid_descriptor *get_ccid_descriptor(in Line 562  _ccid_descriptor *get_ccid_descriptor(in
562   *                                      get_desc   *                                      get_desc
563   *   *
564   ****************************************************************************/   ****************************************************************************/
565  int get_desc(int channel, usb_dev_handle **handle, struct  int get_desc(int lun, usb_dev_handle **handle, struct
566          usb_device **dev)          usb_device **dev)
567  {  {
568          if (channel < 0 || channel > PCSCLITE_MAX_READERS)          int reader_index;
                 return 1;  
569    
570          *handle = usbDevice[channel].handle;          if (-1 == (reader_index = LunToReaderIndex(lun)))
571          *dev = usbDevice[channel].dev;                  return FALSE;
572    
573          return 0;          *handle = usbDevice[reader_index].handle;
574            *dev = usbDevice[reader_index].dev;
575    
576            return TRUE;
577  } /* get_desc */  } /* get_desc */
578    
579    
# Line 449  int get_desc(int channel, usb_dev_handle Line 582  int get_desc(int channel, usb_dev_handle
582   *                                      get_end_points   *                                      get_end_points
583   *   *
584   ****************************************************************************/   ****************************************************************************/
585  int get_end_points(struct usb_device *dev, _usbDevice *usb_device)  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device)
586  {  {
587          int i;          int i;
588          int bEndpointAddress;          int bEndpointAddress;
# Line 481  int get_end_points(struct usb_device *de Line 614  int get_end_points(struct usb_device *de
614   *                                      get_ccid_usb_interface   *                                      get_ccid_usb_interface
615   *   *
616   ****************************************************************************/   ****************************************************************************/
617  struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)  /*@null@*/ struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)
618  {  {
619          struct usb_interface *usb_interface = NULL;          struct usb_interface *usb_interface = NULL;
620    
# Line 491  struct usb_interface * get_ccid_usb_inte Line 624  struct usb_interface * get_ccid_usb_inte
624                  int ii;                  int ii;
625                  for (ii=0; ii<dev->config->bNumInterfaces; ii++)                  for (ii=0; ii<dev->config->bNumInterfaces; ii++)
626                  {                  {
627                          if (dev->config->interface[ii].altsetting->bInterfaceClass == 0xb)                          /* CCID Class? */
628                            if (dev->config->interface[ii].altsetting->bInterfaceClass == 0xb
629    #ifdef ALLOW_PROPRIETARY_CLASS
630                                    || dev->config->interface[ii].altsetting->bInterfaceClass == 0xff
631    #endif
632                                    )
633                          {                          {
634                                  usb_interface = &dev->config->interface[ii];                                  usb_interface = &dev->config->interface[ii];
635                                  break;                                  break;
# Line 499  struct usb_interface * get_ccid_usb_inte Line 637  struct usb_interface * get_ccid_usb_inte
637                  }                  }
638          }          }
639          else          else
640                  /* we keep this in case a reader reports a bad class value */                  /* only one interface found */
641                  usb_interface = dev->config->interface;                  usb_interface = dev->config->interface;
642    
643    #ifdef O2MICRO_OZ776_PATCH
644            if (usb_interface != NULL
645                    && (OZ776 == (dev->descriptor.idVendor << 16)
646                    + dev->descriptor.idProduct)
647                    && (0 == usb_interface->altsetting->extralen)) /* this is the bug */
648            {
649                    int i;
650    
651                    for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
652                    {
653                            /* find the extra[] array */
654                            if (54 == usb_interface->altsetting->endpoint[i].extralen)
655                            {
656                                    /* get the extra[] from the endpoint */
657                                    usb_interface->altsetting->extralen = 54;
658                                    usb_interface->altsetting->extra =
659                                            usb_interface->altsetting->endpoint[i].extra;
660                                    break;
661                            }
662                    }
663            }
664    #endif
665    
666          return usb_interface;          return usb_interface;
667  } /* get_ccid_usb_interface */  } /* get_ccid_usb_interface */
668    
669    
670    /*****************************************************************************
671     *
672     *                                      ccid_check_firmware
673     *
674     ****************************************************************************/
675    int ccid_check_firmware(struct usb_device *dev)
676    {
677            int i;
678    
679            for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)
680            {
681                    if (dev->descriptor.idVendor != Bogus_firmwares[i].vendor)
682                                    continue;
683    
684                    if (dev->descriptor.idProduct != Bogus_firmwares[i].product)
685                            continue;
686    
687                    /* firmware too old and buggy */
688                    if (dev->descriptor.bcdDevice < Bogus_firmwares[i].firmware)
689                    {
690                            if (DriverOptions & DRIVER_OPTION_USE_BOGUS_FIRMWARE)
691                            {
692                                    DEBUG_INFO3("Firmware (%X.%02X) is bogus! but you choosed to use it",
693                                            dev->descriptor.bcdDevice >> 8,
694                                            dev->descriptor.bcdDevice & 0xFF);
695                                    return FALSE;
696                            }
697                            else
698                            {
699                                    DEBUG_CRITICAL3("Firmware (%X.%02X) is bogus! Upgrade the reader firmware or get a new reader.",
700                                            dev->descriptor.bcdDevice >> 8,
701                                            dev->descriptor.bcdDevice & 0xFF);
702                                    return TRUE;
703                            }
704                    }
705            }
706    
707            /* by default the firmware is not bogus */
708            return FALSE;
709    } /* ccid_check_firmware */
710    
711    /*****************************************************************************
712     *
713     *                                      get_data_rates
714     *
715     ****************************************************************************/
716    static unsigned int *get_data_rates(unsigned int reader_index)
717    {
718            int n, i, len;
719            unsigned char buffer[256*sizeof(int)];  /* maximum is 256 records */
720            unsigned int *int_array;
721    
722            /* See CCID 3.7.3 page 25 */
723            n = usb_control_msg(usbDevice[reader_index].handle,
724                    0xA1, /* request type */
725                    0x03, /* GET_DATA_RATES */
726                    0x00, /* value */
727                    usbDevice[reader_index].interface, /* interface */
728                    (char *)buffer,
729                    sizeof(buffer),
730                    usbDevice[reader_index].ccid.readTimeout * 1000);
731    
732            /* we got an error? */
733            if (n <= 0)
734            {
735                    DEBUG_INFO2("IFD does not support GET_DATA_RATES request: %s",
736                            strerror(errno));
737                    return NULL;
738            }
739    
740            /* we got a strange value */
741            if (n % 4)
742            {
743                    DEBUG_INFO2("Wrong GET DATA RATES size: %d", n);
744                    return NULL;
745            }
746    
747            /* allocate the buffer (including the end marker) */
748            n /= sizeof(int);
749    
750            /* we do not get the expected number of data rates */
751            len = get_ccid_usb_interface(usbDevice[reader_index].dev)
752                    ->altsetting->extra[27]; /* bNumDataRatesSupported */
753            if ((n != len) && len)
754            {
755                    DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);
756    
757                    /* we got more data than expected */
758                    if (n > len)
759                            n = len;
760            }
761    
762            int_array = calloc(n+1, sizeof(int));
763            if (NULL == int_array)
764            {
765                    DEBUG_CRITICAL("Memory allocation failed");
766                    return NULL;
767            }
768    
769            /* convert in correct endianess */
770            for (i=0; i<n; i++)
771            {
772                    int_array[i] = dw2i(buffer, i*4);
773                    DEBUG_INFO2("declared: %d bps", int_array[i]);
774            }
775    
776            /* end of array marker */
777            int_array[i] = 0;
778    
779            return int_array;
780    }
781    

Legend:
Removed from v.694  
changed lines
  Added in v.1804

  ViewVC Help
Powered by ViewVC 1.1.5