/[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 3310 by rousseau, Sat Feb 7 16:23:54 2009 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-2008   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 <usb.h>
33    #include <ifdhandler.h>
34    
35    #include "misc.h"
36  #include "ccid.h"  #include "ccid.h"
37  #include "config.h"  #include "config.h"
38  #include "debug.h"  #include "debug.h"
# Line 40  Line 42 
42  #include "ccid_ifdhandler.h"  #include "ccid_ifdhandler.h"
43    
44    
 /* 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 */  
   
45  /* write timeout  /* write timeout
46   * 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 */
47  #define USB_WRITE_TIMEOUT (5 * 1000)  /* 5 seconds timeout */  #define USB_WRITE_TIMEOUT (5 * 1000)  /* 5 seconds timeout */
# Line 58  Line 54 
54   * Manufacturer and Product ID are also used to identify the device */   * Manufacturer and Product ID are also used to identify the device */
55  #define ALLOW_PROPRIETARY_CLASS  #define ALLOW_PROPRIETARY_CLASS
56    
 /*  
  * 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  
   
57  #define BUS_DEVICE_STRSIZE 32  #define BUS_DEVICE_STRSIZE 32
58    
59  typedef struct  typedef struct
60  {  {
61          usb_dev_handle *handle;          usb_dev_handle *handle;
62          struct usb_device *dev;          char *dirname;
63            char *filename;
64          int interface;          int interface;
65    
66          /*          /*
# Line 78  typedef struct Line 68  typedef struct
68           */           */
69          int bulk_in;          int bulk_in;
70          int bulk_out;          int bulk_out;
71            int interrupt;
72    
73            /* Number of slots using the same device */
74            int real_nb_opened_slots;
75            int *nb_opened_slots;
76    
77          /*          /*
78           * CCID infos common to USB and serial           * CCID infos common to USB and serial
# Line 89  typedef struct Line 84  typedef struct
84  /* The _usbDevice structure must be defined before including ccid_usb.h */  /* The _usbDevice structure must be defined before including ccid_usb.h */
85  #include "ccid_usb.h"  #include "ccid_usb.h"
86    
87  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device);  static int get_end_points(struct usb_device *dev, _usbDevice *usbdevice);
88  int ccid_check_firmware(struct usb_device *dev);  int ccid_check_firmware(struct usb_device *dev);
89    static unsigned int *get_data_rates(unsigned int reader_index,
90            struct usb_device *dev);
91    
92  /* ne need to initialize to 0 since it is static */  /* ne need to initialize to 0 since it is static */
93  static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];  static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];
# Line 107  struct _bogus_firmware Line 104  struct _bogus_firmware
104  };  };
105    
106  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 */  
107          { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */          { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */
108          { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */          { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */
109          { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */          { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */
110          { 0x04e6, 0xe003, 0x0504 },     /* SPR 532 */          { 0x04e6, 0xe003, 0x0510 },     /* SPR 532 */
111          { 0x0D46, 0x3001, 0x0037 },     /* KAAN Base */          { 0x0D46, 0x3001, 0x0037 },     /* KAAN Base */
112          { 0x0D46, 0x3002, 0x0037 },     /* KAAN Advanced */          { 0x0D46, 0x3002, 0x0037 },     /* KAAN Advanced */
113            { 0x09C3, 0x0008, 0x0203 },     /* ActivCard V2 */
114            { 0x0DC3, 0x1004, 0x0502 },     /* ASE IIIe USBv2 */
115            { 0x0DC3, 0x1102, 0x0607 },     /* ASE IIIe KB USB */
116            { 0x058F, 0x9520, 0x0102 },     /* Alcor AU9520-G */
117    
118            /* the firmware version is not correct since I do not have received a
119             * working reader yet */
120    #ifndef O2MICRO_OZ776_PATCH
121            { 0x0b97, 0x7762, 0x0111 },     /* Oz776S */
122    #endif
123  };  };
124    
125    /* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
126    unsigned int SerialCustomDataRates[] = { GEMPLUS_CUSTOM_DATA_RATES, 0 };
127    
128    
129  /*****************************************************************************  /*****************************************************************************
130   *   *
# Line 140  status_t OpenUSBByName(unsigned int read Line 149  status_t OpenUSBByName(unsigned int read
149          struct usb_bus *bus;          struct usb_bus *bus;
150          struct usb_dev_handle *dev_handle;          struct usb_dev_handle *dev_handle;
151          char keyValue[TOKEN_MAX_VALUE_SIZE];          char keyValue[TOKEN_MAX_VALUE_SIZE];
152          int vendorID, productID;          unsigned int vendorID, productID;
153          char infofile[FILENAME_MAX];          char infofile[FILENAME_MAX];
154    #ifndef __APPLE__
155          unsigned int device_vendor, device_product;          unsigned int device_vendor, device_product;
156    #endif
157          char *dirname = NULL, *filename = NULL;          char *dirname = NULL, *filename = NULL;
158          static int previous_reader_index = -1;          static int previous_reader_index = -1;
159    
160          DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);          DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);
161    
162    #ifndef __APPLE__
163          /* device name specified */          /* device name specified */
164          if (device)          if (device)
165          {          {
# Line 192  status_t OpenUSBByName(unsigned int read Line 204  status_t OpenUSBByName(unsigned int read
204                          }                          }
205                  }                  }
206          }          }
207    #endif
208    
209          if (busses == NULL)          if (busses == NULL)
210                  usb_init();                  usb_init();
211    
212          usb_find_busses();          (void)usb_find_busses();
213          usb_find_devices();          (void)usb_find_devices();
214    
215          busses = usb_get_busses();          busses = usb_get_busses();
216    
# Line 216  status_t OpenUSBByName(unsigned int read Line 229  status_t OpenUSBByName(unsigned int read
229          }          }
230    
231          /* Info.plist full patch filename */          /* Info.plist full patch filename */
232          snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",          (void)snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
233                  PCSCLITE_HP_DROPDIR, BUNDLE);                  PCSCLITE_HP_DROPDIR, BUNDLE);
234    
235          /* general driver info */          /* general driver info */
236          if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))
237          {          {
238                  DEBUG_CRITICAL2("Manufacturer: %s", keyValue);                  DEBUG_INFO2("Manufacturer: %s", keyValue);
239          }          }
240          else          else
241          {          {
242                  DEBUG_CRITICAL2("LTPBundleFindValueWithKey error. Can't find %s?",                  DEBUG_INFO2("LTPBundleFindValueWithKey error. Can't find %s?",
243                          infofile);                          infofile);
244                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
245          }          }
246          if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))
247          {          {
248                  DEBUG_CRITICAL2("ProductString: %s", keyValue);                  DEBUG_INFO2("ProductString: %s", keyValue);
249          }          }
250          else          else
251                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
252          if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))
253          {          {
254                  DEBUG_CRITICAL2("Copyright: %s", keyValue);                  DEBUG_INFO2("Copyright: %s", keyValue);
255          }          }
256          else          else
257                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
258          vendorID = strlen(keyValue);          vendorID = strlen(keyValue);
259          alias = 0x1D;          alias = 0x1C;
260          for (; vendorID--;)          for (; vendorID--;)
261                  alias ^= keyValue[vendorID];                  alias ^= keyValue[vendorID];
262    
# Line 262  status_t OpenUSBByName(unsigned int read Line 275  status_t OpenUSBByName(unsigned int read
275                  /* go to next supported reader for next round */                  /* go to next supported reader for next round */
276                  alias++;                  alias++;
277    
278    #ifndef __APPLE__
279                  /* 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 */
280                  if (device                  if (device
281                          && (vendorID != device_vendor || productID != device_product))                          && (vendorID != device_vendor || productID != device_product))
282                          continue;                          continue;
283    #else
284                    /* Leopard puts the friendlyname in the device argument */
285                    if (device && strcmp(device, keyValue))
286                            continue;
287    #endif
288    
289                  /* on any USB buses */                  /* on any USB buses */
290                  for (bus = busses; bus; bus = bus->next)                  for (bus = busses; bus; bus = bus->next)
# Line 290  status_t OpenUSBByName(unsigned int read Line 309  status_t OpenUSBByName(unsigned int read
309                                          /* is it already opened? */                                          /* is it already opened? */
310                                          already_used = FALSE;                                          already_used = FALSE;
311    
312                                            DEBUG_COMM3("Checking device: %s/%s",
313                                                    bus->dirname, dev->filename);
314                                          for (r=0; r<CCID_DRIVER_MAX_READERS; r++)                                          for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
315                                          {                                          {
316                                                  if (usbDevice[r].dev)                                                  if (usbDevice[r].handle)
317                                                  {                                                  {
                                                         DEBUG_COMM3("Checking device: %s/%s",  
                                                                 bus->dirname, dev->filename);  
318                                                          /* same busname, same filename */                                                          /* same busname, same filename */
319                                                          if (strcmp(usbDevice[r].dev->bus->dirname, bus->dirname) == 0 && strcmp(usbDevice[r].dev->filename, dev->filename) == 0)                                                          if (strcmp(usbDevice[r].dirname, bus->dirname) == 0 && strcmp(usbDevice[r].filename, dev->filename) == 0)
320                                                                  already_used = TRUE;                                                                  already_used = TRUE;
321                                                  }                                                  }
322                                          }                                          }
# Line 306  status_t OpenUSBByName(unsigned int read Line 325  status_t OpenUSBByName(unsigned int read
325                                          if (already_used)                                          if (already_used)
326                                          {                                          {
327                                                  if ((previous_reader_index != -1)                                                  if ((previous_reader_index != -1)
328                                                          && (strcmp(usbDevice[previous_reader_index].dev->bus->dirname, bus->dirname)  == 0)                                                          && usbDevice[previous_reader_index].handle
329                                                          && (strcmp(usbDevice[previous_reader_index].dev->filename, dev->filename) == 0)                                                          && (strcmp(usbDevice[previous_reader_index].dirname, bus->dirname)  == 0)
330                                                            && (strcmp(usbDevice[previous_reader_index].filename, dev->filename) == 0)
331                                                          && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)                                                          && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)
332                                                  {                                                  {
333                                                          /* we reuse the same device                                                          /* we reuse the same device
334                                                           * and the reader is multi-slot */                                                           * and the reader is multi-slot */
335                                                          usbDevice[reader_index] = usbDevice[previous_reader_index];                                                          usbDevice[reader_index] = usbDevice[previous_reader_index];
336                                                          usbDevice[reader_index].ccid.pbSeq = usbDevice[previous_reader_index].ccid.pbSeq;                                                          /* the other slots do not have the same data rates */
337                                                            if ((GEMCOREPOSPRO == usbDevice[reader_index].ccid.readerID)
338                                                                    || (GEMCORESIMPRO == usbDevice[reader_index].ccid.readerID))
339                                                            {
340                                                                    usbDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates;
341                                                                    usbDevice[reader_index].ccid.dwMaxDataRate = 125000;
342                                                            }
343    
344                                                            *usbDevice[reader_index].nb_opened_slots += 1;
345                                                          usbDevice[reader_index].ccid.bCurrentSlotIndex++;                                                          usbDevice[reader_index].ccid.bCurrentSlotIndex++;
346                                                            usbDevice[reader_index].ccid.dwSlotStatus =
347                                                                    IFD_ICC_PRESENT;
348                                                          DEBUG_INFO2("Opening slot: %d",                                                          DEBUG_INFO2("Opening slot: %d",
349                                                                  usbDevice[reader_index].ccid.bCurrentSlotIndex);                                                                  usbDevice[reader_index].ccid.bCurrentSlotIndex);
350                                                          goto end;                                                          goto end;
# Line 344  status_t OpenUSBByName(unsigned int read Line 374  status_t OpenUSBByName(unsigned int read
374                                          /* now we found a free reader and we try to use it */                                          /* now we found a free reader and we try to use it */
375                                          if (dev->config == NULL)                                          if (dev->config == NULL)
376                                          {                                          {
377                                                    (void)usb_close(dev_handle);
378                                                  DEBUG_CRITICAL3("No dev->config found for %s/%s",                                                  DEBUG_CRITICAL3("No dev->config found for %s/%s",
379                                                           bus->dirname, dev->filename);                                                           bus->dirname, dev->filename);
380                                                  return STATUS_UNSUCCESSFUL;                                                  return STATUS_UNSUCCESSFUL;
# Line 352  status_t OpenUSBByName(unsigned int read Line 383  status_t OpenUSBByName(unsigned int read
383                                          usb_interface = get_ccid_usb_interface(dev);                                          usb_interface = get_ccid_usb_interface(dev);
384                                          if (usb_interface == NULL)                                          if (usb_interface == NULL)
385                                          {                                          {
386                                                    (void)usb_close(dev_handle);
387                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",
388                                                          bus->dirname, dev->filename);                                                          bus->dirname, dev->filename);
389                                                  return STATUS_UNSUCCESSFUL;                                                  return STATUS_UNSUCCESSFUL;
390                                          }                                          }
391    
392                                          if (usb_interface->altsetting->extralen != 54)                                          if (usb_interface->altsetting->extralen != 54)
393                                          {                                          {
394                                                    (void)usb_close(dev_handle);
395                                                  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);
396                                                  return STATUS_UNSUCCESSFUL;                                                  return STATUS_UNSUCCESSFUL;
397                                          }                                          }
# Line 366  status_t OpenUSBByName(unsigned int read Line 399  status_t OpenUSBByName(unsigned int read
399                                          interface = usb_interface->altsetting->bInterfaceNumber;                                          interface = usb_interface->altsetting->bInterfaceNumber;
400                                          if (usb_claim_interface(dev_handle, interface) < 0)                                          if (usb_claim_interface(dev_handle, interface) < 0)
401                                          {                                          {
402                                                    (void)usb_close(dev_handle);
403                                                  DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",                                                  DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",
404                                                          bus->dirname, dev->filename, strerror(errno));                                                          bus->dirname, dev->filename, strerror(errno));
405                                                  return STATUS_UNSUCCESSFUL;                                                  return STATUS_UNSUCCESSFUL;
# Line 379  status_t OpenUSBByName(unsigned int read Line 413  status_t OpenUSBByName(unsigned int read
413    
414                                          /* check for firmware bugs */                                          /* check for firmware bugs */
415                                          if (ccid_check_firmware(dev))                                          if (ccid_check_firmware(dev))
416                                            {
417                                                    (void)usb_close(dev_handle);
418                                                  return STATUS_UNSUCCESSFUL;                                                  return STATUS_UNSUCCESSFUL;
419                                            }
420    
421                                          /* Get Endpoints values*/                                          /* Get Endpoints values*/
422                                          get_end_points(dev, &usbDevice[reader_index]);                                          (void)get_end_points(dev, &usbDevice[reader_index]);
423    
424                                          /* store device information */                                          /* store device information */
425                                          usbDevice[reader_index].handle = dev_handle;                                          usbDevice[reader_index].handle = dev_handle;
426                                          usbDevice[reader_index].dev = dev;                                          usbDevice[reader_index].dirname = strdup(bus->dirname);
427                                            usbDevice[reader_index].filename = strdup(dev->filename);
428                                          usbDevice[reader_index].interface = interface;                                          usbDevice[reader_index].interface = interface;
429                                            usbDevice[reader_index].real_nb_opened_slots = 1;
430                                            usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
431    
432                                          /* CCID common informations */                                          /* CCID common informations */
433                                          usbDevice[reader_index].ccid.real_bSeq = 0;                                          usbDevice[reader_index].ccid.real_bSeq = 0;
# Line 403  status_t OpenUSBByName(unsigned int read Line 443  status_t OpenUSBByName(unsigned int read
443                                          usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);                                          usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);
444                                          usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];                                          usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];
445                                          usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;                                          usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
446                                            usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
447                                            usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index, dev);
448                                            usbDevice[reader_index].ccid.bInterfaceProtocol = usb_interface->altsetting->bInterfaceProtocol;
449                                            usbDevice[reader_index].ccid.bNumEndpoints = usb_interface->altsetting->bNumEndpoints;
450                                            usbDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT;
451                                          goto end;                                          goto end;
452                                  }                                  }
453                          }                          }
# Line 429  status_t WriteUSB(unsigned int reader_in Line 474  status_t WriteUSB(unsigned int reader_in
474          unsigned char *buffer)          unsigned char *buffer)
475  {  {
476          int rv;          int rv;
 #ifdef DEBUG_LEVEL_COMM  
477          char debug_header[] = "-> 121234 ";          char debug_header[] = "-> 121234 ";
478    
479          sprintf(debug_header, "-> %06X ", (int)reader_index);          (void)snprintf(debug_header, sizeof(debug_header), "-> %06X ",
480  #endif                  (int)reader_index);
481    
 #ifdef DEBUG_LEVEL_COMM  
482          DEBUG_XXD(debug_header, buffer, length);          DEBUG_XXD(debug_header, buffer, length);
 #endif  
483    
484          rv = usb_bulk_write(usbDevice[reader_index].handle,          rv = usb_bulk_write(usbDevice[reader_index].handle,
485                  usbDevice[reader_index].bulk_out, (char *)buffer, length,                  usbDevice[reader_index].bulk_out, (char *)buffer, length,
# Line 446  status_t WriteUSB(unsigned int reader_in Line 488  status_t WriteUSB(unsigned int reader_in
488          if (rv < 0)          if (rv < 0)
489          {          {
490                  DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",                  DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",
491                          usbDevice[reader_index].dev->bus->dirname,                          usbDevice[reader_index].dirname, usbDevice[reader_index].filename,
492                          usbDevice[reader_index].dev->filename, strerror(errno));                          strerror(errno));
493    
494                    if (ENODEV == errno)
495                            return STATUS_NO_SUCH_DEVICE;
496    
497                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
498          }          }
499    
# Line 464  status_t ReadUSB(unsigned int reader_ind Line 510  status_t ReadUSB(unsigned int reader_ind
510          unsigned char *buffer)          unsigned char *buffer)
511  {  {
512          int rv;          int rv;
 #ifdef DEBUG_LEVEL_COMM  
513          char debug_header[] = "<- 121234 ";          char debug_header[] = "<- 121234 ";
514            _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
515            int duplicate_frame = 0;
516    
517          sprintf(debug_header, "<- %06X ", (int)reader_index);  read_again:
518  #endif          (void)snprintf(debug_header, sizeof(debug_header), "<- %06X ",
519                    (int)reader_index);
520    
521          rv = usb_bulk_read(usbDevice[reader_index].handle,          rv = usb_bulk_read(usbDevice[reader_index].handle,
522                  usbDevice[reader_index].bulk_in, (char *)buffer, *length,                  usbDevice[reader_index].bulk_in, (char *)buffer, *length,
523                  USB_READ_TIMEOUT);                  usbDevice[reader_index].ccid.readTimeout * 1000);
524    
525          if (rv < 0)          if (rv < 0)
526          {          {
527                  *length = 0;                  *length = 0;
528                  DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",                  DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",
529                          usbDevice[reader_index].dev->bus->dirname,                          usbDevice[reader_index].dirname, usbDevice[reader_index].filename,
530                          usbDevice[reader_index].dev->filename, strerror(errno));                          strerror(errno));
531    
532                    if (ENODEV == errno)
533                            return STATUS_NO_SUCH_DEVICE;
534    
535                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
536          }          }
537    
538          *length = rv;          *length = rv;
539    
 #ifdef DEBUG_LEVEL_COMM  
540          DEBUG_XXD(debug_header, buffer, *length);          DEBUG_XXD(debug_header, buffer, *length);
541  #endif  
542    #define BSEQ_OFFSET 6
543            if ((*length >= BSEQ_OFFSET)
544                    && (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1))
545            {
546                    duplicate_frame++;
547                    if (duplicate_frame > 10)
548                    {
549                            DEBUG_CRITICAL("Too many duplicate frame detected");
550                            return STATUS_UNSUCCESSFUL;
551                    }
552                    DEBUG_INFO("Duplicate frame detected");
553                    goto read_again;
554            }
555    
556          return STATUS_SUCCESS;          return STATUS_SUCCESS;
557  } /* ReadUSB */  } /* ReadUSB */
# Line 501  status_t ReadUSB(unsigned int reader_ind Line 565  status_t ReadUSB(unsigned int reader_ind
565  status_t CloseUSB(unsigned int reader_index)  status_t CloseUSB(unsigned int reader_index)
566  {  {
567          /* device not opened */          /* device not opened */
568          if (usbDevice[reader_index].dev == NULL)          if (usbDevice[reader_index].handle == NULL)
569                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
570    
571          DEBUG_COMM3("Closing USB device: %s/%s",          DEBUG_COMM3("Closing USB device: %s/%s",
572                  usbDevice[reader_index].dev->bus->dirname,                  usbDevice[reader_index].dirname,
573                  usbDevice[reader_index].dev->filename);                  usbDevice[reader_index].filename);
574    
575            if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates
576                    && (usbDevice[reader_index].ccid.bCurrentSlotIndex == 0))
577            {
578                    free(usbDevice[reader_index].ccid.arrayOfSupportedDataRates);
579                    usbDevice[reader_index].ccid.arrayOfSupportedDataRates = NULL;
580            }
581    
582            /* one slot closed */
583            (*usbDevice[reader_index].nb_opened_slots)--;
584    
585            /* release the allocated ressources for the last slot only */
586            if (0 == *usbDevice[reader_index].nb_opened_slots)
587            {
588                    DEBUG_COMM("Last slot closed. Release resources");
589    
590                    /* reset so that bSeq starts at 0 again */
591                    if (DriverOptions & DRIVER_OPTION_RESET_ON_CLOSE)
592                            (void)usb_reset(usbDevice[reader_index].handle);
593    
594          /* reset so that bSeq starts at 0 again */                  (void)usb_release_interface(usbDevice[reader_index].handle,
595          usb_reset(usbDevice[reader_index].handle);                          usbDevice[reader_index].interface);
596                    (void)usb_close(usbDevice[reader_index].handle);
597    
598          usb_release_interface(usbDevice[reader_index].handle,                  free(usbDevice[reader_index].dirname);
599                  usbDevice[reader_index].interface);                  free(usbDevice[reader_index].filename);
600          usb_close(usbDevice[reader_index].handle);          }
601    
602          /* mark the resource unused */          /* mark the resource unused */
603          usbDevice[reader_index].handle = NULL;          usbDevice[reader_index].handle = NULL;
604          usbDevice[reader_index].dev = NULL;          usbDevice[reader_index].dirname = NULL;
605            usbDevice[reader_index].filename = NULL;
606          usbDevice[reader_index].interface = 0;          usbDevice[reader_index].interface = 0;
607    
608          return STATUS_SUCCESS;          return STATUS_SUCCESS;
# Line 537  _ccid_descriptor *get_ccid_descriptor(un Line 622  _ccid_descriptor *get_ccid_descriptor(un
622    
623  /*****************************************************************************  /*****************************************************************************
624   *   *
  *                                      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 */  
   
   
 /*****************************************************************************  
  *  
625   *                                      get_end_points   *                                      get_end_points
626   *   *
627   ****************************************************************************/   ****************************************************************************/
628  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device)  static int get_end_points(struct usb_device *dev, _usbDevice *usbdevice)
629  {  {
630          int i;          int i;
631          int bEndpointAddress;          int bEndpointAddress;
632          struct usb_interface *usb_interface = get_ccid_usb_interface(dev);          struct usb_interface *usb_interface = get_ccid_usb_interface(dev);
633    
634          /*          /*
635           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
636           */           */
637          for (i=0; i<3; i++)          for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
638          {          {
639                    /* interrupt end point (if available) */
640                    if (usb_interface->altsetting->endpoint[i].bmAttributes == USB_ENDPOINT_TYPE_INTERRUPT)
641                    {
642                            usbdevice->interrupt = usb_interface->altsetting->endpoint[i].bEndpointAddress;
643                            continue;
644                    }
645    
646                  if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)                  if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)
647                          continue;                          continue;
648    
649                  bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;                  bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;
650    
651                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
652                          usb_device->bulk_in = bEndpointAddress;                          usbdevice->bulk_in = bEndpointAddress;
653    
654                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)
655                          usb_device->bulk_out = bEndpointAddress;                          usbdevice->bulk_out = bEndpointAddress;
656          }          }
657    
658          return 0;          return 0;
# Line 592  static int get_end_points(struct usb_dev Line 664  static int get_end_points(struct usb_dev
664   *                                      get_ccid_usb_interface   *                                      get_ccid_usb_interface
665   *   *
666   ****************************************************************************/   ****************************************************************************/
667  /*@null@*/ struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)  /*@null@*/ EXTERNAL struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)
668  {  {
669          struct usb_interface *usb_interface = NULL;          struct usb_interface *usb_interface = NULL;
670            int i;
671    #ifdef O2MICRO_OZ776_PATCH
672            int readerID;
673    #endif
674    
675          /* if multiple interfaces use the first one with CCID class type */          /* if multiple interfaces use the first one with CCID class type */
676          if (dev->config->bNumInterfaces > 1)          for (i=0; dev->config && i<dev->config->bNumInterfaces; i++)
677          {          {
678                  int ii;                  /* CCID Class? */
679                  for (ii=0; ii<dev->config->bNumInterfaces; ii++)                  if (dev->config->interface[i].altsetting->bInterfaceClass == 0xb
                 {  
                         /* CCID Class? */  
                         if (dev->config->interface[ii].altsetting->bInterfaceClass == 0xb  
680  #ifdef ALLOW_PROPRIETARY_CLASS  #ifdef ALLOW_PROPRIETARY_CLASS
681                                  || dev->config->interface[ii].altsetting->bInterfaceClass == 0xff                          || dev->config->interface[i].altsetting->bInterfaceClass == 0xff
682  #endif  #endif
683                                  )                          )
684                          {                  {
685                                  usb_interface = &dev->config->interface[ii];                          usb_interface = &dev->config->interface[i];
686                                  break;                          break;
                         }  
687                  }                  }
688          }          }
         else  
                 /* only one interface found */  
                 usb_interface = dev->config->interface;  
689    
690  #ifdef O2MICRO_OZ776_PATCH  #ifdef O2MICRO_OZ776_PATCH
691            readerID = (dev->descriptor.idVendor << 16) + dev->descriptor.idProduct;
692          if (usb_interface != NULL          if (usb_interface != NULL
693                  && (OZ776 == (dev->descriptor.idVendor << 16)                  && ((OZ776 == readerID) || (OZ776_7772 == readerID)
694                  + dev->descriptor.idProduct)                  || (REINER_SCT == readerID) || (BLUDRIVEII_CCID == readerID))
695                  && (0 == usb_interface->altsetting->extralen)) /* this is the bug */                  && (0 == usb_interface->altsetting->extralen)) /* this is the bug */
696          {          {
                 int i;  
   
697                  for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)                  for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
698                  {                  {
699                          /* find the extra[] array */                          /* find the extra[] array */
# Line 635  static int get_end_points(struct usb_dev Line 703  static int get_end_points(struct usb_dev
703                                  usb_interface->altsetting->extralen = 54;                                  usb_interface->altsetting->extralen = 54;
704                                  usb_interface->altsetting->extra =                                  usb_interface->altsetting->extra =
705                                          usb_interface->altsetting->endpoint[i].extra;                                          usb_interface->altsetting->endpoint[i].extra;
706                                    /* avoid double free on close */
707                                    usb_interface->altsetting->endpoint[i].extra = NULL;
708                                    usb_interface->altsetting->endpoint[i].extralen = 0;
709                                  break;                                  break;
710                          }                          }
711                  }                  }
# Line 652  static int get_end_points(struct usb_dev Line 723  static int get_end_points(struct usb_dev
723   ****************************************************************************/   ****************************************************************************/
724  int ccid_check_firmware(struct usb_device *dev)  int ccid_check_firmware(struct usb_device *dev)
725  {  {
726          int i;          unsigned int i;
727    
728          for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)          for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)
729          {          {
# Line 686  int ccid_check_firmware(struct usb_devic Line 757  int ccid_check_firmware(struct usb_devic
757          return FALSE;          return FALSE;
758  } /* ccid_check_firmware */  } /* ccid_check_firmware */
759    
760    
761    /*****************************************************************************
762     *
763     *                                      get_data_rates
764     *
765     ****************************************************************************/
766    static unsigned int *get_data_rates(unsigned int reader_index,
767            struct usb_device *dev)
768    {
769            int n, i, len;
770            unsigned char buffer[256*sizeof(int)];  /* maximum is 256 records */
771            unsigned int *int_array;
772    
773            /* See CCID 3.7.3 page 25 */
774            n = ControlUSB(reader_index,
775                    0xA1, /* request type */
776                    0x03, /* GET_DATA_RATES */
777                    0x00, /* value */
778                    buffer, sizeof(buffer));
779    
780            /* we got an error? */
781            if (n <= 0)
782            {
783                    DEBUG_INFO2("IFD does not support GET_DATA_RATES request: %s",
784                            strerror(errno));
785                    return NULL;
786            }
787    
788            /* we got a strange value */
789            if (n % 4)
790            {
791                    DEBUG_INFO2("Wrong GET DATA RATES size: %d", n);
792                    return NULL;
793            }
794    
795            /* allocate the buffer (including the end marker) */
796            n /= sizeof(int);
797    
798            /* we do not get the expected number of data rates */
799            len = get_ccid_usb_interface(dev)->altsetting->extra[27]; /* bNumDataRatesSupported */
800            if ((n != len) && len)
801            {
802                    DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);
803    
804                    /* we got more data than expected */
805                    if (n > len)
806                            n = len;
807            }
808    
809            int_array = calloc(n+1, sizeof(int));
810            if (NULL == int_array)
811            {
812                    DEBUG_CRITICAL("Memory allocation failed");
813                    return NULL;
814            }
815    
816            /* convert in correct endianess */
817            for (i=0; i<n; i++)
818            {
819                    int_array[i] = dw2i(buffer, i*4);
820                    DEBUG_INFO2("declared: %d bps", int_array[i]);
821            }
822    
823            /* end of array marker */
824            int_array[i] = 0;
825    
826            return int_array;
827    } /* get_data_rates */
828    
829    
830    /*****************************************************************************
831     *
832     *                                      ControlUSB
833     *
834     ****************************************************************************/
835    int ControlUSB(int reader_index, int requesttype, int request, int value,
836            unsigned char *bytes, unsigned int size)
837    {
838            int ret;
839    
840            DEBUG_COMM2("request: 0x%02X", request);
841    
842            if (0 == (requesttype & 0x80))
843                    DEBUG_XXD("send: ", bytes, size);
844    
845            ret = usb_control_msg(usbDevice[reader_index].handle, requesttype,
846                    request, value, usbDevice[reader_index].interface, (char *)bytes, size,
847                    usbDevice[reader_index].ccid.readTimeout * 1000);
848    
849            if (requesttype & 0x80)
850                    DEBUG_XXD("receive: ", bytes, ret);
851    
852            return ret;
853    } /* ControlUSB */
854    
855    /*****************************************************************************
856     *
857     *                                      InterruptRead
858     *
859     *
860     ****************************************************************************/
861    int InterruptRead(int reader_index)
862    {
863            int ret;
864            char buffer[8];
865            int timeout = 2*1000; /* 2 seconds */
866    
867            DEBUG_COMM("before");
868            ret = usb_interrupt_read(usbDevice[reader_index].handle,
869                    usbDevice[reader_index].interrupt, buffer, sizeof(buffer), timeout);
870            DEBUG_COMM2("after %d", ret);
871    
872            if (ret < 0)
873            {
874                    /* if usb_interrupt_read() times out we get EILSEQ or EAGAIN */
875                    if ((errno != EILSEQ) && (errno != EAGAIN) && (errno != ENODEV) && (errno != 0))
876                            DEBUG_COMM4("usb_interrupt_read(%s/%s): %s",
877                                            usbDevice[reader_index].dirname,
878                                            usbDevice[reader_index].filename, strerror(errno));
879            }
880            else
881                    DEBUG_XXD("NotifySlotChange: ", buffer, ret);
882    
883            return ret;
884    } /* InterruptRead */
885    

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

  ViewVC Help
Powered by ViewVC 1.1.5