/[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 2083 by rousseau, Mon Jul 3 12:51:59 2006 UTC revision 2690 by rousseau, Fri Nov 16 13:24:28 2007 UTC
# 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>
# Line 53  Line 53 
53   * Manufacturer and Product ID are also used to identify the device */   * Manufacturer and Product ID are also used to identify the device */
54  #define ALLOW_PROPRIETARY_CLASS  #define ALLOW_PROPRIETARY_CLASS
55    
 /*  
  * 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  
   
56  #define BUS_DEVICE_STRSIZE 32  #define BUS_DEVICE_STRSIZE 32
57    
58  typedef struct  typedef struct
59  {  {
60          usb_dev_handle *handle;          usb_dev_handle *handle;
61          struct usb_device *dev;          char *dirname;
62            char *filename;
63          int interface;          int interface;
64    
65          /*          /*
# Line 88  typedef struct Line 82  typedef struct
82  /* The _usbDevice structure must be defined before including ccid_usb.h */  /* The _usbDevice structure must be defined before including ccid_usb.h */
83  #include "ccid_usb.h"  #include "ccid_usb.h"
84    
85  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device);  static int get_end_points(struct usb_device *dev, _usbDevice *usbdevice);
86  int ccid_check_firmware(struct usb_device *dev);  int ccid_check_firmware(struct usb_device *dev);
87  static unsigned int *get_data_rates(unsigned int reader_index);  static unsigned int *get_data_rates(unsigned int reader_index,
88            struct usb_device *dev);
89    
90  /* ne need to initialize to 0 since it is static */  /* ne need to initialize to 0 since it is static */
91  static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];  static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];
# Line 107  struct _bogus_firmware Line 102  struct _bogus_firmware
102  };  };
103    
104  static struct _bogus_firmware Bogus_firmwares[] = {  static struct _bogus_firmware Bogus_firmwares[] = {
105          { 0x0b97, 0x7762, 0x0111 },     /* Oz776S */ /* the firmware version if not correct since I don't have received a working reader yet */  #ifndef O2MICRO_OZ776_PATCH
106            { 0x0b97, 0x7762, 0x0111 },     /* Oz776S */ /* the firmware version is not correct since I do not have received a working reader yet */
107    #endif
108          { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */          { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */
109          { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */          { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */
110          { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */          { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */
# Line 117  static struct _bogus_firmware Bogus_firm Line 114  static struct _bogus_firmware Bogus_firm
114          { 0x09C3, 0x0008, 0x0203 },     /* ActivCard V2 */          { 0x09C3, 0x0008, 0x0203 },     /* ActivCard V2 */
115          { 0x0DC3, 0x1004, 0x0502 },     /* ASE IIIe USBv2 */          { 0x0DC3, 0x1004, 0x0502 },     /* ASE IIIe USBv2 */
116          { 0x0DC3, 0x1102, 0x0607 },     /* ASE IIIe KB USB */          { 0x0DC3, 0x1102, 0x0607 },     /* ASE IIIe KB USB */
117            { 0x058F, 0x9520, 0x0102 },     /* Alcor AU9520-G */
118            { 0x0C4B, 0x0300, 0x0101 },     /* Reiner-SCT cyberJack pinpad(a) */
119  };  };
120    
121  /* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */  /* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
# Line 296  status_t OpenUSBByName(unsigned int read Line 295  status_t OpenUSBByName(unsigned int read
295                                          /* is it already opened? */                                          /* is it already opened? */
296                                          already_used = FALSE;                                          already_used = FALSE;
297    
298                                            DEBUG_COMM3("Checking device: %s/%s",
299                                                    bus->dirname, dev->filename);
300                                          for (r=0; r<CCID_DRIVER_MAX_READERS; r++)                                          for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
301                                          {                                          {
302                                                  if (usbDevice[r].dev)                                                  if (usbDevice[r].handle)
303                                                  {                                                  {
                                                         DEBUG_COMM3("Checking device: %s/%s",  
                                                                 bus->dirname, dev->filename);  
304                                                          /* same busname, same filename */                                                          /* same busname, same filename */
305                                                          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)
306                                                                  already_used = TRUE;                                                                  already_used = TRUE;
307                                                  }                                                  }
308                                          }                                          }
# Line 312  status_t OpenUSBByName(unsigned int read Line 311  status_t OpenUSBByName(unsigned int read
311                                          if (already_used)                                          if (already_used)
312                                          {                                          {
313                                                  if ((previous_reader_index != -1)                                                  if ((previous_reader_index != -1)
314                                                          && usbDevice[previous_reader_index].dev                                                          && usbDevice[previous_reader_index].handle
315                                                          && (strcmp(usbDevice[previous_reader_index].dev->bus->dirname, bus->dirname)  == 0)                                                          && (strcmp(usbDevice[previous_reader_index].dirname, bus->dirname)  == 0)
316                                                          && (strcmp(usbDevice[previous_reader_index].dev->filename, dev->filename) == 0)                                                          && (strcmp(usbDevice[previous_reader_index].filename, dev->filename) == 0)
317                                                          && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)                                                          && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)
318                                                  {                                                  {
319                                                          /* we reuse the same device                                                          /* we reuse the same device
# Line 372  status_t OpenUSBByName(unsigned int read Line 371  status_t OpenUSBByName(unsigned int read
371                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",
372                                                          bus->dirname, dev->filename);                                                          bus->dirname, dev->filename);
373                                                  return STATUS_UNSUCCESSFUL;                                                  return STATUS_UNSUCCESSFUL;
374                                          }                                          }
375    
376                                          if (usb_interface->altsetting->extralen != 54)                                          if (usb_interface->altsetting->extralen != 54)
377                                          {                                          {
# Line 408  status_t OpenUSBByName(unsigned int read Line 407  status_t OpenUSBByName(unsigned int read
407    
408                                          /* store device information */                                          /* store device information */
409                                          usbDevice[reader_index].handle = dev_handle;                                          usbDevice[reader_index].handle = dev_handle;
410                                          usbDevice[reader_index].dev = dev;                                          usbDevice[reader_index].dirname = strdup(bus->dirname);
411                                            usbDevice[reader_index].filename = strdup(dev->filename);
412                                          usbDevice[reader_index].interface = interface;                                          usbDevice[reader_index].interface = interface;
413                                          usbDevice[reader_index].real_nb_opened_slots = 1;                                          usbDevice[reader_index].real_nb_opened_slots = 1;
414                                          usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;                                          usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
# Line 428  status_t OpenUSBByName(unsigned int read Line 428  status_t OpenUSBByName(unsigned int read
428                                          usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];                                          usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];
429                                          usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;                                          usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
430                                          usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;                                          usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
431                                          usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index);                                          usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index, dev);
432                                            usbDevice[reader_index].ccid.bInterfaceProtocol = usb_interface->altsetting->bInterfaceProtocol;
433                                          goto end;                                          goto end;
434                                  }                                  }
435                          }                          }
# Line 467  status_t WriteUSB(unsigned int reader_in Line 468  status_t WriteUSB(unsigned int reader_in
468    
469          if (rv < 0)          if (rv < 0)
470          {          {
471                  if (usbDevice[reader_index].dev->bus)                  DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",
472                  {                          usbDevice[reader_index].dirname, usbDevice[reader_index].filename,
473                          DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",                          strerror(errno));
474                                  usbDevice[reader_index].dev->bus->dirname,  
475                                  usbDevice[reader_index].dev->filename, strerror(errno));                  if (ENODEV == errno)
476                  }                          return STATUS_NO_SUCH_DEVICE;
                 else  
                         DEBUG_CRITICAL2("usb_bulk_write(no device): %s", strerror(errno));  
477    
478                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
479          }          }
# Line 506  read_again: Line 505  read_again:
505          {          {
506                  *length = 0;                  *length = 0;
507                  DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",                  DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",
508                          usbDevice[reader_index].dev->bus->dirname,                          usbDevice[reader_index].dirname, usbDevice[reader_index].filename,
509                          usbDevice[reader_index].dev->filename, strerror(errno));                          strerror(errno));
510    
511                    if (ENODEV == errno)
512                            return STATUS_NO_SUCH_DEVICE;
513    
514                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
515          }          }
516    
# Line 516  read_again: Line 519  read_again:
519          DEBUG_XXD(debug_header, buffer, *length);          DEBUG_XXD(debug_header, buffer, *length);
520    
521  #define BSEQ_OFFSET 6  #define BSEQ_OFFSET 6
522          if (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1)          if ((*length >= BSEQ_OFFSET)
523                    && (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1))
524          {          {
525                  DEBUG_INFO("Duplicate frame detected");                  DEBUG_INFO("Duplicate frame detected");
526                  goto read_again;                  goto read_again;
# Line 534  read_again: Line 538  read_again:
538  status_t CloseUSB(unsigned int reader_index)  status_t CloseUSB(unsigned int reader_index)
539  {  {
540          /* device not opened */          /* device not opened */
541          if (usbDevice[reader_index].dev == NULL)          if (usbDevice[reader_index].handle == NULL)
542                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
543    
544          DEBUG_COMM3("Closing USB device: %s/%s",          DEBUG_COMM3("Closing USB device: %s/%s",
545                  usbDevice[reader_index].dev->bus->dirname,                  usbDevice[reader_index].dirname,
546                  usbDevice[reader_index].dev->filename);                  usbDevice[reader_index].filename);
547    
548          if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates          if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates
549                  && (usbDevice[reader_index].ccid.bCurrentSlotIndex == 0))                  && (usbDevice[reader_index].ccid.bCurrentSlotIndex == 0))
# Line 563  status_t CloseUSB(unsigned int reader_in Line 567  status_t CloseUSB(unsigned int reader_in
567                  usb_release_interface(usbDevice[reader_index].handle,                  usb_release_interface(usbDevice[reader_index].handle,
568                          usbDevice[reader_index].interface);                          usbDevice[reader_index].interface);
569                  usb_close(usbDevice[reader_index].handle);                  usb_close(usbDevice[reader_index].handle);
570    
571                    free(usbDevice[reader_index].dirname);
572                    free(usbDevice[reader_index].filename);
573          }          }
574    
575          /* mark the resource unused */          /* mark the resource unused */
576          usbDevice[reader_index].handle = NULL;          usbDevice[reader_index].handle = NULL;
577          usbDevice[reader_index].dev = NULL;          usbDevice[reader_index].dirname = NULL;
578            usbDevice[reader_index].filename = NULL;
579          usbDevice[reader_index].interface = 0;          usbDevice[reader_index].interface = 0;
580    
581          return STATUS_SUCCESS;          return STATUS_SUCCESS;
# Line 587  _ccid_descriptor *get_ccid_descriptor(un Line 595  _ccid_descriptor *get_ccid_descriptor(un
595    
596  /*****************************************************************************  /*****************************************************************************
597   *   *
  *                                      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 */  
   
   
 /*****************************************************************************  
  *  
598   *                                      get_end_points   *                                      get_end_points
599   *   *
600   ****************************************************************************/   ****************************************************************************/
601  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device)  static int get_end_points(struct usb_device *dev, _usbDevice *usbdevice)
602  {  {
603          int i;          int i;
604          int bEndpointAddress;          int bEndpointAddress;
605          struct usb_interface *usb_interface = get_ccid_usb_interface(dev);          struct usb_interface *usb_interface = get_ccid_usb_interface(dev);
606    
607          /*          /*
608           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
609           */           */
610          for (i=0; i<3; i++)          for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
611          {          {
612                  if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)                  if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)
613                          continue;                          continue;
# Line 627  static int get_end_points(struct usb_dev Line 615  static int get_end_points(struct usb_dev
615                  bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;                  bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;
616    
617                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
618                          usb_device->bulk_in = bEndpointAddress;                          usbdevice->bulk_in = bEndpointAddress;
619    
620                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)
621                          usb_device->bulk_out = bEndpointAddress;                          usbdevice->bulk_out = bEndpointAddress;
622          }          }
623    
624          return 0;          return 0;
# Line 644  static int get_end_points(struct usb_dev Line 632  static int get_end_points(struct usb_dev
632   ****************************************************************************/   ****************************************************************************/
633  /*@null@*/ EXTERNAL struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)  /*@null@*/ EXTERNAL struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)
634  {  {
635          struct usb_interface *usb_interface = NULL;          struct usb_interface *usb_interface = NULL;
636          int i;          int i;
637    #ifdef O2MICRO_OZ776_PATCH
638            int readerID;
639    #endif
640    
641          /* if multiple interfaces use the first one with CCID class type */          /* if multiple interfaces use the first one with CCID class type */
642          for (i=0; i<dev->config->bNumInterfaces; i++)          for (i=0; dev->config && i<dev->config->bNumInterfaces; i++)
643          {          {
644                  /* CCID Class? */                  /* CCID Class? */
645                  if (dev->config->interface[i].altsetting->bInterfaceClass == 0xb                  if (dev->config->interface[i].altsetting->bInterfaceClass == 0xb
# Line 663  static int get_end_points(struct usb_dev Line 654  static int get_end_points(struct usb_dev
654          }          }
655    
656  #ifdef O2MICRO_OZ776_PATCH  #ifdef O2MICRO_OZ776_PATCH
657            readerID = (dev->descriptor.idVendor << 16) + dev->descriptor.idProduct;
658          if (usb_interface != NULL          if (usb_interface != NULL
659                  && (OZ776 == (dev->descriptor.idVendor << 16)                  && ((OZ776 == readerID) || (OZ776_7772 == readerID)
660                  + dev->descriptor.idProduct)                  || (REINER_SCT == readerID))
661                  && (0 == usb_interface->altsetting->extralen)) /* this is the bug */                  && (0 == usb_interface->altsetting->extralen)) /* this is the bug */
662          {          {
663                  for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)                  for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
# Line 677  static int get_end_points(struct usb_dev Line 669  static int get_end_points(struct usb_dev
669                                  usb_interface->altsetting->extralen = 54;                                  usb_interface->altsetting->extralen = 54;
670                                  usb_interface->altsetting->extra =                                  usb_interface->altsetting->extra =
671                                          usb_interface->altsetting->endpoint[i].extra;                                          usb_interface->altsetting->endpoint[i].extra;
672                                    /* avoid double free on close */
673                                    usb_interface->altsetting->endpoint[i].extra = NULL;
674                                    usb_interface->altsetting->endpoint[i].extralen = 0;
675                                  break;                                  break;
676                          }                          }
677                  }                  }
# Line 733  int ccid_check_firmware(struct usb_devic Line 728  int ccid_check_firmware(struct usb_devic
728   *                                      get_data_rates   *                                      get_data_rates
729   *   *
730   ****************************************************************************/   ****************************************************************************/
731  static unsigned int *get_data_rates(unsigned int reader_index)  static unsigned int *get_data_rates(unsigned int reader_index,
732            struct usb_device *dev)
733  {  {
734          int n, i, len;          int n, i, len;
735          unsigned char buffer[256*sizeof(int)];  /* maximum is 256 records */          unsigned char buffer[256*sizeof(int)];  /* maximum is 256 records */
736          unsigned int *int_array;          unsigned int *int_array;
737    
738          /* See CCID 3.7.3 page 25 */          /* See CCID 3.7.3 page 25 */
739          n = usb_control_msg(usbDevice[reader_index].handle,          n = ControlUSB(reader_index,
740                  0xA1, /* request type */                  0xA1, /* request type */
741                  0x03, /* GET_DATA_RATES */                  0x03, /* GET_DATA_RATES */
742                  0x00, /* value */                  0x00, /* value */
743                  usbDevice[reader_index].interface, /* interface */                  buffer, sizeof(buffer));
                 (char *)buffer,  
                 sizeof(buffer),  
                 usbDevice[reader_index].ccid.readTimeout * 1000);  
744    
745          /* we got an error? */          /* we got an error? */
746          if (n <= 0)          if (n <= 0)
# Line 768  static unsigned int *get_data_rates(unsi Line 761  static unsigned int *get_data_rates(unsi
761          n /= sizeof(int);          n /= sizeof(int);
762    
763          /* we do not get the expected number of data rates */          /* we do not get the expected number of data rates */
764          len = get_ccid_usb_interface(usbDevice[reader_index].dev)          len = get_ccid_usb_interface(dev)->altsetting->extra[27]; /* bNumDataRatesSupported */
                 ->altsetting->extra[27]; /* bNumDataRatesSupported */  
765          if ((n != len) && len)          if ((n != len) && len)
766          {          {
767                  DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);                  DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);
# Line 799  static unsigned int *get_data_rates(unsi Line 791  static unsigned int *get_data_rates(unsi
791          return int_array;          return int_array;
792  }  }
793    
794    int ControlUSB(int reader_index, int requesttype, int request, int value,
795            unsigned char *bytes, unsigned int size)
796    {
797            int ret;
798    
799            DEBUG_COMM2("request: 0x%02X", request);
800    
801            if (0 == (requesttype & 0x80))
802                    DEBUG_XXD("send: ", bytes, size);
803    
804            ret = usb_control_msg(usbDevice[reader_index].handle, requesttype,
805                    request, value, usbDevice[reader_index].interface, (char *)bytes, size,
806                    usbDevice[reader_index].ccid.readTimeout * 1000);
807    
808            if (requesttype & 0x80)
809                    DEBUG_XXD("receive: ", bytes, ret);
810    
811            return ret;
812    }
813    

Legend:
Removed from v.2083  
changed lines
  Added in v.2690

  ViewVC Help
Powered by ViewVC 1.1.5