2 ccid_usb.c: USB access routines using the libusb library
3 Copyright (C) 2003-2010 Ludovic Rousseau
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this library; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 # include <sys/types.h>
31 #include <ifdhandler.h>
40 #include "ccid_ifdhandler.h"
44 * 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 */
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 because the
52 * Manufacturer and Product ID are also used to identify the device */
53 #define ALLOW_PROPRIETARY_CLASS
55 #define BUS_DEVICE_STRSIZE 32
57 /* Using the default libusb context */
58 /* does not work for libusb <= 1.0.8 */
59 /* #define ctx NULL */
60 libusb_context *ctx = NULL;
62 #define CCID_INTERRUPT_SIZE 8
64 struct usbDevice_MultiSlot_Extension
68 /* The multi-threaded polling part */
71 unsigned char buffer[CCID_INTERRUPT_SIZE];
72 pthread_t thread_proc;
73 pthread_mutex_t mutex;
74 pthread_cond_t condition;
75 struct libusb_transfer *transfer;
80 libusb_device_handle *dev_handle;
82 uint8_t device_address;
92 /* Number of slots using the same device */
93 int real_nb_opened_slots;
97 * CCID infos common to USB and serial
99 _ccid_descriptor ccid;
101 /* libusb transfer for the polling (or NULL) */
102 struct libusb_transfer *polling_transfer;
104 /* pointer to the multislot extension (if any) */
105 struct usbDevice_MultiSlot_Extension *multislot_extension;
109 /* The _usbDevice structure must be defined before including ccid_usb.h */
110 #include "ccid_usb.h"
112 /* Specific hooks for multislot readers */
113 static int Multi_InterruptRead(int reader_index, int timeout /* in ms */);
114 static void Multi_InterruptStop(int reader_index);
115 static struct usbDevice_MultiSlot_Extension *Multi_CreateFirstSlot(int reader_index);
116 static struct usbDevice_MultiSlot_Extension *Multi_CreateNextSlot(int physical_reader_index);
117 static void Multi_PollingTerminate(struct usbDevice_MultiSlot_Extension *msExt);
119 static int get_end_points(struct libusb_config_descriptor *desc,
120 _usbDevice *usbdevice, int num);
121 int ccid_check_firmware(struct libusb_device_descriptor *desc);
122 static unsigned int *get_data_rates(unsigned int reader_index,
123 struct libusb_config_descriptor *desc, int num);
125 /* ne need to initialize to 0 since it is static */
126 static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];
128 #define PCSCLITE_MANUKEY_NAME "ifdVendorID"
129 #define PCSCLITE_PRODKEY_NAME "ifdProductID"
130 #define PCSCLITE_NAMEKEY_NAME "ifdFriendlyName"
132 struct _bogus_firmware
134 int vendor; /* idVendor */
135 int product; /* idProduct */
136 int firmware; /* bcdDevice: previous firmwares have bugs */
139 static struct _bogus_firmware Bogus_firmwares[] = {
140 { 0x04e6, 0xe001, 0x0516 }, /* SCR 331 */
141 { 0x04e6, 0x5111, 0x0620 }, /* SCR 331-DI */
142 { 0x04e6, 0xe003, 0x0510 }, /* SPR 532 */
143 { 0x0D46, 0x3001, 0x0037 }, /* KAAN Base */
144 { 0x0D46, 0x3002, 0x0037 }, /* KAAN Advanced */
145 { 0x09C3, 0x0008, 0x0203 }, /* ActivCard V2 */
146 { 0x0DC3, 0x1004, 0x0502 }, /* ASE IIIe USBv2 */
147 { 0x0DC3, 0x1102, 0x0607 }, /* ASE IIIe KB USB */
148 { 0x058F, 0x9520, 0x0102 }, /* Alcor AU9520-G */
149 { 0x072F, 0x2200, 0x0206 }, /* ACS ACR122U-WB-R */
150 { 0x08C3, 0x0402, 0x5000 }, /* Precise Biometrics Precise 200 MC */
151 { 0x08C3, 0x0401, 0x5000 }, /* Precise Biometrics Precise 250 MC */
152 { 0x0B0C, 0x0050, 0x0101 }, /* Todos Argos Mini II */
153 { 0x0DC3, 0x0900, 0x0200 }, /* Athena IDProtect Key v2 */
154 { 0x03F0, 0x0036, 0x0124 }, /* HP USB CCID Smartcard Keyboard */
155 { 0x062D, 0x0001, 0x0102 }, /* THRC Smart Card Reader */
156 { 0x04E6, 0x5291, 0x0112 }, /* SCM SCL010 Contactless Reader */
158 /* the firmware version is not correct since I do not have received a
159 * working reader yet */
160 #ifndef O2MICRO_OZ776_PATCH
161 { 0x0b97, 0x7762, 0x0111 }, /* Oz776S */
165 /* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
166 unsigned int SerialCustomDataRates[] = { GEMPLUS_CUSTOM_DATA_RATES, 0 };
168 /*****************************************************************************
170 * close_libusb_if_needed
172 ****************************************************************************/
173 static void close_libusb_if_needed(void)
175 int i, to_exit = TRUE;
180 /* if at least 1 reader is still in use we do not exit libusb */
181 for (i=0; i<CCID_DRIVER_MAX_READERS; i++)
183 if (usbDevice[i].dev_handle != NULL)
189 DEBUG_INFO1("libusb_exit");
193 } /* close_libusb_if_needed */
195 /*****************************************************************************
199 ****************************************************************************/
200 status_t OpenUSB(unsigned int reader_index, /*@unused@*/ int Channel)
204 return OpenUSBByName(reader_index, NULL);
208 /*****************************************************************************
212 ****************************************************************************/
213 status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
216 struct libusb_device_handle *dev_handle;
217 char infofile[FILENAME_MAX];
219 unsigned int device_vendor, device_product;
220 unsigned int device_bus = 0;
221 unsigned int device_addr = 0;
224 struct timespec sleep_time = { 0, 100 * 1000 * 1000 };
225 int count_libusb = 10;
227 int interface_number = -1;
229 static int previous_reader_index = -1;
230 libusb_device **devs, *dev;
232 list_t plist, *values, *ifdVendorID, *ifdProductID, *ifdFriendlyName;
234 int claim_failed = FALSE;
235 int return_value = STATUS_SUCCESS;
237 DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);
240 /* device name specified */
245 /* format: usb:%04x/%04x, vendor, product */
246 if (strncmp("usb:", device, 4) != 0)
248 DEBUG_CRITICAL2("device name does not start with \"usb:\": %s",
250 return STATUS_UNSUCCESSFUL;
253 if (sscanf(device, "usb:%x/%x", &device_vendor, &device_product) != 2)
255 DEBUG_CRITICAL2("device name can't be parsed: %s", device);
256 return STATUS_UNSUCCESSFUL;
259 /* format usb:%04x/%04x:libudev:%d:%s
261 * 01 (or whatever the interface number is)
263 * /dev/bus/usb/008/004
265 if ((dirname = strstr(device, "libudev:")) != NULL)
267 /* convert the interface number, bus and device ids */
268 if (sscanf(dirname + 8, "%d:/dev/bus/usb/%d/%d", &interface_number, &device_bus, &device_addr) == 3) {
269 DEBUG_COMM2("interface_number: %d", interface_number);
270 DEBUG_COMM3("usb bus/device: %d/%d", device_bus, device_addr);
275 /* format usb:%04x/%04x:libusb-1.0:%d:%d:%d */
276 if ((dirname = strstr(device, "libusb-1.0:")) != NULL)
278 /* convert the interface number, bus and device ids */
279 if (sscanf(dirname + 11, "%d:%d:%d",
280 &device_bus, &device_addr, &interface_number) == 3)
282 DEBUG_COMM2("interface_number: %d", interface_number);
283 DEBUG_COMM3("usb bus/device: %d/%d", device_bus,
291 /* is the reader_index already used? */
292 if (usbDevice[reader_index].dev_handle != NULL)
294 DEBUG_CRITICAL2("USB driver with index %X already in use",
296 return STATUS_UNSUCCESSFUL;
299 /* Info.plist full patch filename */
300 (void)snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
301 PCSCLITE_HP_DROPDIR, BUNDLE);
302 DEBUG_INFO2("Using: %s", infofile);
304 rv = bundleParse(infofile, &plist);
306 return STATUS_UNSUCCESSFUL;
308 #define GET_KEY(key, values) \
309 rv = LTPBundleFindValueWithKey(&plist, key, &values); \
312 DEBUG_CRITICAL2("Value/Key not defined for " key " in %s", infofile); \
313 return_value = STATUS_UNSUCCESSFUL; \
317 DEBUG_INFO2(key ": %s", (char *)list_get_at(values, 0));
319 /* general driver info */
320 GET_KEY("ifdManufacturerString", values)
321 GET_KEY("ifdProductString", values)
322 GET_KEY("Copyright", values)
326 rv = libusb_init(&ctx);
329 DEBUG_CRITICAL2("libusb_init failed: %s", libusb_error_name(rv));
330 return_value = STATUS_UNSUCCESSFUL;
335 #define GET_KEYS(key, values) \
336 rv = LTPBundleFindValueWithKey(&plist, key, values); \
339 DEBUG_CRITICAL2("Value/Key not defined for " key " in %s", infofile); \
340 return_value = STATUS_UNSUCCESSFUL; \
344 GET_KEYS("ifdVendorID", &ifdVendorID)
345 GET_KEYS("ifdProductID", &ifdProductID);
346 GET_KEYS("ifdFriendlyName", &ifdFriendlyName)
348 /* The 3 lists do not have the same size */
349 if ((list_size(ifdVendorID) != list_size(ifdProductID))
350 || (list_size(ifdVendorID) != list_size(ifdFriendlyName)))
352 DEBUG_CRITICAL2("Error parsing %s", infofile);
353 return_value = STATUS_UNSUCCESSFUL;
360 cnt = libusb_get_device_list(ctx, &devs);
363 DEBUG_CRITICAL("libusb_get_device_list() failed\n");
364 return_value = STATUS_UNSUCCESSFUL;
368 /* for any supported reader */
369 for (alias=0; alias<list_size(ifdVendorID); alias++)
371 unsigned int vendorID, productID;
374 vendorID = strtoul(list_get_at(ifdVendorID, alias), NULL, 0);
375 productID = strtoul(list_get_at(ifdProductID, alias), NULL, 0);
376 friendlyName = list_get_at(ifdFriendlyName, alias);
379 /* the device was specified but is not the one we are trying to find */
381 && (vendorID != device_vendor || productID != device_product))
384 /* Leopard puts the friendlyname in the device argument */
385 if (device && strcmp(device, friendlyName))
389 /* for every device */
391 while ((dev = devs[i++]) != NULL)
393 struct libusb_device_descriptor desc;
394 struct libusb_config_descriptor *config_desc;
395 uint8_t bus_number = libusb_get_bus_number(dev);
396 uint8_t device_address = libusb_get_device_address(dev);
399 if ((device_bus || device_addr)
400 && ((bus_number != device_bus)
401 || (device_address != device_addr))) {
402 /* not USB the device we are looking for */
406 DEBUG_COMM3("Try device: %d/%d", bus_number, device_address);
408 int r = libusb_get_device_descriptor(dev, &desc);
411 DEBUG_INFO3("failed to get device descriptor for %d/%d",
412 bus_number, device_address);
416 DEBUG_COMM3("vid/pid : %04X/%04X", desc.idVendor, desc.idProduct);
418 if (desc.idVendor == vendorID && desc.idProduct == productID)
421 const struct libusb_interface *usb_interface = NULL;
424 const unsigned char *device_descriptor;
425 int readerID = (vendorID << 16) + productID;
427 #ifdef USE_COMPOSITE_AS_MULTISLOT
428 /* use the first CCID interface on first call */
429 static int static_interface = -1;
430 int max_interface_number = 2;
432 /* simulate a composite device as when libudev is used */
433 if ((GEMALTOPROXDU == readerID)
434 || (GEMALTOPROXSU == readerID)
435 || (HID_OMNIKEY_5422 == readerID)
436 || (FEITIANR502DUAL == readerID))
439 * We can't talk to the two CCID interfaces
440 * at the same time (the reader enters a
441 * dead lock). So we simulate a multi slot
442 * reader. By default multi slot readers
443 * can't use the slots at the same time. See
444 * TAG_IFD_SLOT_THREAD_SAFE
446 * One side effect is that the two readers
447 * are seen by pcscd as one reader so the
448 * interface name is the same for the two.
451 * 0: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 00
452 * 1: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 01
454 * 0: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 00
455 * 1: Gemalto Prox-DU [Prox-DU Contactless_09A00795] (09A00795) 01 00
458 /* for the Gemalto Prox-DU/SU the interfaces are:
459 * 0: Prox-DU HID (not used)
460 * 1: Prox-DU Contactless (CCID)
461 * 2: Prox-DU Contact (CCID)
463 * For the Feitian R502 the interfaces are:
464 * 0: R502 Contactless Reader (CCID)
465 * 1: R502 Contact Reader (CCID)
466 * 2: R502 SAM1 Reader (CCID)
468 * For the HID Omnikey 5422 the interfaces are:
469 * 0: OMNIKEY 5422CL Smartcard Reader
470 * 1: OMNIKEY 5422 Smartcard Reader
472 interface_number = static_interface;
474 if (HID_OMNIKEY_5422 == readerID)
475 /* only 2 interfaces for this device */
476 max_interface_number = 1;
479 /* is it already opened? */
480 already_used = FALSE;
482 DEBUG_COMM3("Checking device: %d/%d",
483 bus_number, device_address);
484 for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
486 if (usbDevice[r].dev_handle)
488 /* same bus, same address */
489 if (usbDevice[r].bus_number == bus_number
490 && usbDevice[r].device_address == device_address)
495 /* this reader is already managed by us */
498 if ((previous_reader_index != -1)
499 && usbDevice[previous_reader_index].dev_handle
500 && (usbDevice[previous_reader_index].bus_number == bus_number)
501 && (usbDevice[previous_reader_index].device_address == device_address)
502 && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)
504 /* we reuse the same device
505 * and the reader is multi-slot */
506 usbDevice[reader_index] = usbDevice[previous_reader_index];
507 /* The other slots of GemCore SIM Pro firmware
508 * 1.0 do not have the same data rates.
509 * Firmware 2.0 do not have this limitation */
510 if ((GEMCOREPOSPRO == readerID)
511 || ((GEMCORESIMPRO == readerID)
512 && (usbDevice[reader_index].ccid.IFD_bcdDevice < 0x0200)))
514 /* Allocate a memory buffer that will be
515 * released in CloseUSB() */
516 void *ptr = malloc(sizeof SerialCustomDataRates);
519 memcpy(ptr, SerialCustomDataRates,
520 sizeof SerialCustomDataRates);
523 usbDevice[reader_index].ccid.arrayOfSupportedDataRates = ptr;
524 usbDevice[reader_index].ccid.dwMaxDataRate = 125000;
527 *usbDevice[reader_index].nb_opened_slots += 1;
528 usbDevice[reader_index].ccid.bCurrentSlotIndex++;
529 usbDevice[reader_index].ccid.dwSlotStatus =
531 DEBUG_INFO2("Opening slot: %d",
532 usbDevice[reader_index].ccid.bCurrentSlotIndex);
534 /* This is a multislot reader
535 * Init the multislot stuff for this next slot */
536 usbDevice[reader_index].multislot_extension = Multi_CreateNextSlot(previous_reader_index);
541 /* if an interface number is given by HAL we
542 * continue with this device. */
543 if (-1 == interface_number)
545 DEBUG_INFO3("USB device %d/%d already in use."
546 " Checking next one.",
547 bus_number, device_address);
553 DEBUG_COMM3("Trying to open USB bus/device: %d/%d",
554 bus_number, device_address);
556 r = libusb_open(dev, &dev_handle);
559 DEBUG_CRITICAL4("Can't libusb_open(%d/%d): %s",
560 bus_number, device_address, libusb_error_name(r));
566 r = libusb_get_active_config_descriptor(dev, &config_desc);
570 /* Some early Gemalto Ezio CB+ readers have
571 * bDeviceClass, bDeviceSubClass and bDeviceProtocol set
572 * to 0xFF (proprietary) instead of 0x00.
574 * So on Mac OS X the reader configuration is not done
575 * by the OS/kernel and we do it ourself.
577 if ((0xFF == desc.bDeviceClass)
578 && (0xFF == desc.bDeviceSubClass)
579 && (0xFF == desc.bDeviceProtocol))
581 r = libusb_set_configuration(dev_handle, 1);
584 (void)libusb_close(dev_handle);
585 DEBUG_CRITICAL4("Can't set configuration on %d/%d: %s",
586 bus_number, device_address,
587 libusb_error_name(r));
593 r = libusb_get_active_config_descriptor(dev, &config_desc);
597 (void)libusb_close(dev_handle);
598 DEBUG_CRITICAL4("Can't get config descriptor on %d/%d: %s",
599 bus_number, device_address, libusb_error_name(r));
607 usb_interface = get_ccid_usb_interface(config_desc, &num);
608 if (usb_interface == NULL)
610 libusb_free_config_descriptor(config_desc);
611 (void)libusb_close(dev_handle);
613 DEBUG_CRITICAL3("Can't find a CCID interface on %d/%d",
614 bus_number, device_address);
615 interface_number = -1;
619 device_descriptor = get_ccid_device_descriptor(usb_interface);
620 if (NULL == device_descriptor)
622 libusb_free_config_descriptor(config_desc);
623 (void)libusb_close(dev_handle);
624 DEBUG_CRITICAL3("Unable to find the device descriptor for %d/%d",
625 bus_number, device_address);
626 return_value = STATUS_UNSUCCESSFUL;
630 interface = usb_interface->altsetting->bInterfaceNumber;
631 if (interface_number >= 0 && interface != interface_number)
633 libusb_free_config_descriptor(config_desc);
634 /* an interface was specified and it is not the
636 DEBUG_INFO3("Found interface %d but expecting %d",
637 interface, interface_number);
638 DEBUG_INFO3("Wrong interface for USB device %d/%d."
639 " Checking next one.", bus_number, device_address);
641 /* check for another CCID interface on the same device */
647 r = libusb_claim_interface(dev_handle, interface);
650 libusb_free_config_descriptor(config_desc);
651 (void)libusb_close(dev_handle);
652 DEBUG_CRITICAL4("Can't claim interface %d/%d: %s",
653 bus_number, device_address, libusb_error_name(r));
655 interface_number = -1;
659 DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",
660 desc.idVendor, desc.idProduct, friendlyName);
661 DEBUG_INFO3("Using USB bus/device: %d/%d",
662 bus_number, device_address);
664 /* check for firmware bugs */
665 if (ccid_check_firmware(&desc))
667 libusb_free_config_descriptor(config_desc);
668 (void)libusb_close(dev_handle);
669 return_value = STATUS_UNSUCCESSFUL;
673 #ifdef USE_COMPOSITE_AS_MULTISLOT
674 if ((GEMALTOPROXDU == readerID)
675 || (GEMALTOPROXSU == readerID)
676 || (HID_OMNIKEY_5422 == readerID)
677 || (FEITIANR502DUAL == readerID))
679 /* use the next interface for the next "slot" */
680 static_interface = interface + 1;
682 /* reset for a next reader */
683 /* max interface number for all 3 readers is 2 */
684 if (static_interface > max_interface_number)
685 static_interface = -1;
689 /* Get Endpoints values*/
690 (void)get_end_points(config_desc, &usbDevice[reader_index], num);
692 /* store device information */
693 usbDevice[reader_index].dev_handle = dev_handle;
694 usbDevice[reader_index].bus_number = bus_number;
695 usbDevice[reader_index].device_address = device_address;
696 usbDevice[reader_index].interface = interface;
697 usbDevice[reader_index].real_nb_opened_slots = 1;
698 usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
699 usbDevice[reader_index].polling_transfer = NULL;
701 /* CCID common informations */
702 usbDevice[reader_index].ccid.real_bSeq = 0;
703 usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq;
704 usbDevice[reader_index].ccid.readerID =
705 (desc.idVendor << 16) + desc.idProduct;
706 usbDevice[reader_index].ccid.dwFeatures = dw2i(device_descriptor, 40);
707 usbDevice[reader_index].ccid.wLcdLayout =
708 (device_descriptor[51] << 8) + device_descriptor[50];
709 usbDevice[reader_index].ccid.bPINSupport = device_descriptor[52];
710 usbDevice[reader_index].ccid.dwMaxCCIDMessageLength = dw2i(device_descriptor, 44);
711 usbDevice[reader_index].ccid.dwMaxIFSD = dw2i(device_descriptor, 28);
712 usbDevice[reader_index].ccid.dwDefaultClock = dw2i(device_descriptor, 10);
713 usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(device_descriptor, 23);
714 usbDevice[reader_index].ccid.bMaxSlotIndex = device_descriptor[4];
715 usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
716 usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
717 if (device_descriptor[27])
718 usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index, config_desc, num);
721 usbDevice[reader_index].ccid.arrayOfSupportedDataRates = NULL;
722 DEBUG_INFO1("bNumDataRatesSupported is 0");
724 usbDevice[reader_index].ccid.bInterfaceProtocol = usb_interface->altsetting->bInterfaceProtocol;
725 usbDevice[reader_index].ccid.bNumEndpoints = usb_interface->altsetting->bNumEndpoints;
726 usbDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT;
727 usbDevice[reader_index].ccid.bVoltageSupport = device_descriptor[5];
728 usbDevice[reader_index].ccid.sIFD_serial_number = NULL;
729 usbDevice[reader_index].ccid.gemalto_firmware_features = NULL;
731 usbDevice[reader_index].ccid.zlp = FALSE;
733 if (desc.iSerialNumber)
735 unsigned char serial[128];
738 ret = libusb_get_string_descriptor_ascii(dev_handle,
739 desc.iSerialNumber, serial,
742 usbDevice[reader_index].ccid.sIFD_serial_number
743 = strdup((char *)serial);
746 usbDevice[reader_index].ccid.sIFD_iManufacturer = NULL;
747 if (desc.iManufacturer)
749 unsigned char iManufacturer[128];
752 ret = libusb_get_string_descriptor_ascii(dev_handle,
753 desc.iManufacturer, iManufacturer,
754 sizeof(iManufacturer));
756 usbDevice[reader_index].ccid.sIFD_iManufacturer
757 = strdup((char *)iManufacturer);
760 usbDevice[reader_index].ccid.IFD_bcdDevice = desc.bcdDevice;
762 /* If this is a multislot reader, init the multislot stuff */
763 if (usbDevice[reader_index].ccid.bMaxSlotIndex)
764 usbDevice[reader_index].multislot_extension = Multi_CreateFirstSlot(reader_index);
766 usbDevice[reader_index].multislot_extension = NULL;
768 libusb_free_config_descriptor(config_desc);
774 if (usbDevice[reader_index].dev_handle == NULL)
776 /* free the libusb allocated list & devices */
777 libusb_free_device_list(devs, 1);
780 /* give some time to libusb to detect the new USB devices on Mac OS X */
781 if (count_libusb > 0)
784 DEBUG_INFO2("Wait after libusb: %d", count_libusb);
785 nanosleep(&sleep_time, NULL);
791 /* free bundle list */
792 bundleRelease(&plist);
795 close_libusb_if_needed();
798 return STATUS_COMM_ERROR;
799 DEBUG_INFO1("Device not found?");
800 return STATUS_NO_SUCH_DEVICE;
803 /* memorise the current reader_index so we can detect
804 * a new OpenUSBByName on a multi slot reader */
805 previous_reader_index = reader_index;
808 /* free the libusb allocated list & devices */
809 libusb_free_device_list(devs, 1);
812 /* free bundle list */
813 bundleRelease(&plist);
815 if (return_value != STATUS_SUCCESS)
816 close_libusb_if_needed();
819 } /* OpenUSBByName */
822 /*****************************************************************************
826 ****************************************************************************/
827 status_t WriteUSB(unsigned int reader_index, unsigned int length,
828 unsigned char *buffer)
832 char debug_header[] = "-> 121234 ";
834 (void)snprintf(debug_header, sizeof(debug_header), "-> %06X ",
838 if (usbDevice[reader_index].ccid.zlp)
839 { /* Zero Length Packet */
842 /* try to read a ZLP so transfer length = 0
843 * timeout of 10 ms */
844 (void)libusb_bulk_transfer(usbDevice[reader_index].dev_handle,
845 usbDevice[reader_index].bulk_in, NULL, 0, &dummy_length, 10);
849 DEBUG_XXD(debug_header, buffer, length);
851 rv = libusb_bulk_transfer(usbDevice[reader_index].dev_handle,
852 usbDevice[reader_index].bulk_out, buffer, length,
853 &actual_length, USB_WRITE_TIMEOUT);
857 DEBUG_CRITICAL5("write failed (%d/%d): %d %s",
858 usbDevice[reader_index].bus_number,
859 usbDevice[reader_index].device_address, rv, libusb_error_name(rv));
861 if (LIBUSB_ERROR_NO_DEVICE == rv)
862 return STATUS_NO_SUCH_DEVICE;
864 return STATUS_UNSUCCESSFUL;
867 return STATUS_SUCCESS;
871 /*****************************************************************************
875 ****************************************************************************/
876 status_t ReadUSB(unsigned int reader_index, unsigned int * length,
877 unsigned char *buffer)
881 char debug_header[] = "<- 121234 ";
882 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
883 int duplicate_frame = 0;
886 (void)snprintf(debug_header, sizeof(debug_header), "<- %06X ",
889 rv = libusb_bulk_transfer(usbDevice[reader_index].dev_handle,
890 usbDevice[reader_index].bulk_in, buffer, *length,
891 &actual_length, usbDevice[reader_index].ccid.readTimeout);
896 DEBUG_CRITICAL5("read failed (%d/%d): %d %s",
897 usbDevice[reader_index].bus_number,
898 usbDevice[reader_index].device_address, rv, libusb_error_name(rv));
900 if (LIBUSB_ERROR_NO_DEVICE == rv)
901 return STATUS_NO_SUCH_DEVICE;
903 return STATUS_UNSUCCESSFUL;
906 *length = actual_length;
908 DEBUG_XXD(debug_header, buffer, *length);
910 #define BSEQ_OFFSET 6
911 if ((*length >= BSEQ_OFFSET)
912 && (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1))
915 if (duplicate_frame > 10)
917 DEBUG_CRITICAL("Too many duplicate frame detected");
918 return STATUS_UNSUCCESSFUL;
920 DEBUG_INFO1("Duplicate frame detected");
924 return STATUS_SUCCESS;
928 /*****************************************************************************
932 ****************************************************************************/
933 status_t CloseUSB(unsigned int reader_index)
935 /* device not opened */
936 if (usbDevice[reader_index].dev_handle == NULL)
937 return STATUS_UNSUCCESSFUL;
939 DEBUG_COMM3("Closing USB device: %d/%d",
940 usbDevice[reader_index].bus_number,
941 usbDevice[reader_index].device_address);
943 /* one slot closed */
944 (*usbDevice[reader_index].nb_opened_slots)--;
946 /* release the allocated ressources for the last slot only */
947 if (0 == *usbDevice[reader_index].nb_opened_slots)
949 struct usbDevice_MultiSlot_Extension *msExt;
951 DEBUG_COMM("Last slot closed. Release resources");
953 msExt = usbDevice[reader_index].multislot_extension;
954 /* If this is a multislot reader, close using the multislot stuff */
957 /* terminate the interrupt waiter thread */
958 Multi_PollingTerminate(msExt);
960 /* wait for the thread to actually terminate */
961 pthread_join(msExt->thread_proc, NULL);
963 /* release the shared objects */
964 pthread_cond_destroy(&msExt->condition);
965 pthread_mutex_destroy(&msExt->mutex);
967 /* Deallocate the extension itself */
971 usbDevice[reader_index].multislot_extension = NULL;
974 if (usbDevice[reader_index].ccid.gemalto_firmware_features)
975 free(usbDevice[reader_index].ccid.gemalto_firmware_features);
977 if (usbDevice[reader_index].ccid.sIFD_serial_number)
978 free(usbDevice[reader_index].ccid.sIFD_serial_number);
980 if (usbDevice[reader_index].ccid.sIFD_iManufacturer)
981 free(usbDevice[reader_index].ccid.sIFD_iManufacturer);
983 if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates)
984 free(usbDevice[reader_index].ccid.arrayOfSupportedDataRates);
986 (void)libusb_release_interface(usbDevice[reader_index].dev_handle,
987 usbDevice[reader_index].interface);
988 (void)libusb_close(usbDevice[reader_index].dev_handle);
991 /* mark the resource unused */
992 usbDevice[reader_index].dev_handle = NULL;
993 usbDevice[reader_index].interface = 0;
995 close_libusb_if_needed();
997 return STATUS_SUCCESS;
1001 /*****************************************************************************
1003 * get_ccid_descriptor
1005 ****************************************************************************/
1006 _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
1008 return &usbDevice[reader_index].ccid;
1009 } /* get_ccid_descriptor */
1012 /*****************************************************************************
1014 * get_ccid_device_descriptor
1016 ****************************************************************************/
1017 const unsigned char *get_ccid_device_descriptor(const struct libusb_interface *usb_interface)
1019 #ifdef O2MICRO_OZ776_PATCH
1020 uint8_t last_endpoint;
1023 if (54 == usb_interface->altsetting->extra_length)
1024 return usb_interface->altsetting->extra;
1026 if (0 != usb_interface->altsetting->extra_length)
1028 /* If extra_length is zero, the descriptor might be at
1029 * the end, but if it's not zero, we have a
1031 DEBUG_CRITICAL2("Extra field has a wrong length: %d",
1032 usb_interface->altsetting->extra_length);
1036 #ifdef O2MICRO_OZ776_PATCH
1037 /* Some devices, such as the Oz776, Reiner SCT and bludrive II
1038 * report the device descriptor at the end of the endpoint
1039 * descriptors; to support those, look for it at the end as well.
1041 last_endpoint = usb_interface->altsetting->bNumEndpoints-1;
1042 if (usb_interface->altsetting->endpoint
1043 && usb_interface->altsetting->endpoint[last_endpoint].extra_length == 54)
1044 return usb_interface->altsetting->endpoint[last_endpoint].extra;
1046 DEBUG_CRITICAL2("Extra field has a wrong length: %d",
1047 usb_interface->altsetting->extra_length);
1051 } /* get_ccid_device_descriptor */
1054 /*****************************************************************************
1058 ****************************************************************************/
1059 static int get_end_points(struct libusb_config_descriptor *desc,
1060 _usbDevice *usbdevice, int num)
1063 int bEndpointAddress;
1064 const struct libusb_interface *usb_interface;
1066 usb_interface = get_ccid_usb_interface(desc, &num);
1069 * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
1071 for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
1073 /* interrupt end point (if available) */
1074 if (usb_interface->altsetting->endpoint[i].bmAttributes
1075 == LIBUSB_TRANSFER_TYPE_INTERRUPT)
1077 usbdevice->interrupt =
1078 usb_interface->altsetting->endpoint[i].bEndpointAddress;
1082 if (usb_interface->altsetting->endpoint[i].bmAttributes
1083 != LIBUSB_TRANSFER_TYPE_BULK)
1087 usb_interface->altsetting->endpoint[i].bEndpointAddress;
1089 if ((bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
1090 == LIBUSB_ENDPOINT_IN)
1091 usbdevice->bulk_in = bEndpointAddress;
1093 if ((bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
1094 == LIBUSB_ENDPOINT_OUT)
1095 usbdevice->bulk_out = bEndpointAddress;
1099 } /* get_end_points */
1102 /*****************************************************************************
1104 * get_ccid_usb_bus_number
1106 ****************************************************************************/
1107 uint8_t get_ccid_usb_bus_number(int reader_index)
1109 return usbDevice[reader_index].bus_number;
1113 /*****************************************************************************
1115 * get_ccid_usb_device_address
1117 ****************************************************************************/
1118 uint8_t get_ccid_usb_device_address(int reader_index)
1120 return usbDevice[reader_index].device_address;
1123 /*****************************************************************************
1125 * get_ccid_usb_interface
1127 ****************************************************************************/
1128 /*@null@*/ const struct libusb_interface * get_ccid_usb_interface(
1129 struct libusb_config_descriptor *desc, int *num)
1131 const struct libusb_interface *usb_interface = NULL;
1134 /* if multiple interfaces use the first one with CCID class type */
1135 for (i = *num; i < desc->bNumInterfaces; i++)
1138 if (desc->interface[i].altsetting->bInterfaceClass == 0xb
1139 #ifdef ALLOW_PROPRIETARY_CLASS
1140 || (desc->interface[i].altsetting->bInterfaceClass == 0xff
1141 && 54 == desc->interface[i].altsetting->extra_length)
1145 usb_interface = &desc->interface[i];
1146 /* store the interface number for further reference */
1152 return usb_interface;
1153 } /* get_ccid_usb_interface */
1156 /*****************************************************************************
1158 * ccid_check_firmware
1160 ****************************************************************************/
1161 int ccid_check_firmware(struct libusb_device_descriptor *desc)
1165 for (i=0; i<COUNT_OF(Bogus_firmwares); i++)
1167 if (desc->idVendor != Bogus_firmwares[i].vendor)
1170 if (desc->idProduct != Bogus_firmwares[i].product)
1173 /* firmware too old and buggy */
1174 if (desc->bcdDevice < Bogus_firmwares[i].firmware)
1176 if (DriverOptions & DRIVER_OPTION_USE_BOGUS_FIRMWARE)
1178 DEBUG_INFO3("Firmware (%X.%02X) is bogus! but you choosed to use it",
1179 desc->bcdDevice >> 8, desc->bcdDevice & 0xFF);
1184 DEBUG_CRITICAL3("Firmware (%X.%02X) is bogus! Upgrade the reader firmware or get a new reader.",
1185 desc->bcdDevice >> 8, desc->bcdDevice & 0xFF);
1191 /* by default the firmware is not bogus */
1193 } /* ccid_check_firmware */
1196 /*****************************************************************************
1200 ****************************************************************************/
1201 static unsigned int *get_data_rates(unsigned int reader_index,
1202 struct libusb_config_descriptor *desc, int num)
1205 unsigned char buffer[256*sizeof(int)]; /* maximum is 256 records */
1206 unsigned int *uint_array;
1208 /* See CCID 3.7.3 page 25 */
1209 n = ControlUSB(reader_index,
1210 0xA1, /* request type */
1211 0x03, /* GET_DATA_RATES */
1213 buffer, sizeof(buffer));
1215 /* we got an error? */
1218 DEBUG_INFO2("IFD does not support GET_DATA_RATES request: %d", n);
1222 /* we got a strange value */
1225 DEBUG_INFO2("Wrong GET DATA RATES size: %d", n);
1229 /* allocate the buffer (including the end marker) */
1232 /* we do not get the expected number of data rates */
1233 len = get_ccid_device_descriptor(get_ccid_usb_interface(desc, &num))[27]; /* bNumDataRatesSupported */
1234 if ((n != len) && len)
1236 DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);
1238 /* we got more data than expected */
1243 uint_array = calloc(n+1, sizeof(uint_array[0]));
1244 if (NULL == uint_array)
1246 DEBUG_CRITICAL("Memory allocation failed");
1250 /* convert in correct endianess */
1253 uint_array[i] = dw2i(buffer, i*4);
1254 DEBUG_INFO2("declared: %d bps", uint_array[i]);
1257 /* end of array marker */
1261 } /* get_data_rates */
1264 /*****************************************************************************
1268 ****************************************************************************/
1269 int ControlUSB(int reader_index, int requesttype, int request, int value,
1270 unsigned char *bytes, unsigned int size)
1274 DEBUG_COMM2("request: 0x%02X", request);
1276 if (0 == (requesttype & 0x80))
1277 DEBUG_XXD("send: ", bytes, size);
1279 ret = libusb_control_transfer(usbDevice[reader_index].dev_handle,
1280 requesttype, request, value, usbDevice[reader_index].interface,
1281 bytes, size, usbDevice[reader_index].ccid.readTimeout);
1285 DEBUG_CRITICAL5("control failed (%d/%d): %d %s",
1286 usbDevice[reader_index].bus_number,
1287 usbDevice[reader_index].device_address, ret, libusb_error_name(ret));
1292 if (requesttype & 0x80)
1293 DEBUG_XXD("receive: ", bytes, ret);
1298 /*****************************************************************************
1300 * Transfer is complete
1302 ****************************************************************************/
1303 static void bulk_transfer_cb(struct libusb_transfer *transfer)
1305 int *completed = transfer->user_data;
1307 /* caller interprets results and frees transfer */
1310 /*****************************************************************************
1314 ****************************************************************************/
1315 int InterruptRead(int reader_index, int timeout /* in ms */)
1317 int ret, actual_length;
1318 int return_value = IFD_SUCCESS;
1319 unsigned char buffer[8];
1320 struct libusb_transfer *transfer;
1323 /* Multislot reader: redirect to Multi_InterrupRead */
1324 if (usbDevice[reader_index].multislot_extension != NULL)
1325 return Multi_InterruptRead(reader_index, timeout);
1327 DEBUG_PERIODIC3("before (%d), timeout: %d ms", reader_index, timeout);
1329 transfer = libusb_alloc_transfer(0);
1330 if (NULL == transfer)
1331 return LIBUSB_ERROR_NO_MEM;
1333 libusb_fill_bulk_transfer(transfer,
1334 usbDevice[reader_index].dev_handle,
1335 usbDevice[reader_index].interrupt, buffer, sizeof(buffer),
1336 bulk_transfer_cb, &completed, timeout);
1337 transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT;
1339 ret = libusb_submit_transfer(transfer);
1341 libusb_free_transfer(transfer);
1342 DEBUG_CRITICAL2("libusb_submit_transfer failed: %s",
1343 libusb_error_name(ret));
1344 return IFD_COMMUNICATION_ERROR;
1347 usbDevice[reader_index].polling_transfer = transfer;
1351 ret = libusb_handle_events_completed(ctx, &completed);
1354 if (ret == LIBUSB_ERROR_INTERRUPTED)
1356 libusb_cancel_transfer(transfer);
1358 if (libusb_handle_events_completed(ctx, &completed) < 0)
1360 libusb_free_transfer(transfer);
1361 DEBUG_CRITICAL2("libusb_handle_events failed: %s",
1362 libusb_error_name(ret));
1363 return IFD_COMMUNICATION_ERROR;
1367 actual_length = transfer->actual_length;
1368 ret = transfer->status;
1370 usbDevice[reader_index].polling_transfer = NULL;
1371 libusb_free_transfer(transfer);
1373 DEBUG_PERIODIC3("after (%d) (%d)", reader_index, ret);
1377 case LIBUSB_TRANSFER_COMPLETED:
1378 DEBUG_XXD("NotifySlotChange: ", buffer, actual_length);
1381 case LIBUSB_TRANSFER_TIMED_OUT:
1385 /* if libusb_interrupt_transfer() times out we get EILSEQ or EAGAIN */
1386 DEBUG_COMM4("InterruptRead (%d/%d): %d",
1387 usbDevice[reader_index].bus_number,
1388 usbDevice[reader_index].device_address, ret);
1389 return_value = IFD_COMMUNICATION_ERROR;
1392 return return_value;
1393 } /* InterruptRead */
1396 /*****************************************************************************
1398 * Stop the async loop
1400 ****************************************************************************/
1401 void InterruptStop(int reader_index)
1403 struct libusb_transfer *transfer;
1405 /* Multislot reader: redirect to Multi_InterrupStop */
1406 if (usbDevice[reader_index].multislot_extension != NULL)
1408 Multi_InterruptStop(reader_index);
1412 transfer = usbDevice[reader_index].polling_transfer;
1413 usbDevice[reader_index].polling_transfer = NULL;
1418 ret = libusb_cancel_transfer(transfer);
1420 DEBUG_CRITICAL2("libusb_cancel_transfer failed: %s",
1421 libusb_error_name(ret));
1423 } /* InterruptStop */
1426 /*****************************************************************************
1430 ****************************************************************************/
1431 static void *Multi_PollingProc(void *p_ext)
1433 struct usbDevice_MultiSlot_Extension *msExt = p_ext;
1434 int rv, status, actual_length;
1435 unsigned char buffer[CCID_INTERRUPT_SIZE];
1436 struct libusb_transfer *transfer;
1439 DEBUG_COMM3("Multi_PollingProc (%d/%d): thread starting",
1440 usbDevice[msExt->reader_index].bus_number,
1441 usbDevice[msExt->reader_index].device_address);
1444 while (!msExt->terminated)
1446 DEBUG_COMM3("Multi_PollingProc (%d/%d): waiting",
1447 usbDevice[msExt->reader_index].bus_number,
1448 usbDevice[msExt->reader_index].device_address);
1450 transfer = libusb_alloc_transfer(0);
1451 if (NULL == transfer)
1453 rv = LIBUSB_ERROR_NO_MEM;
1454 DEBUG_COMM2("libusb_alloc_transfer err %d", rv);
1458 libusb_fill_bulk_transfer(transfer,
1459 usbDevice[msExt->reader_index].dev_handle,
1460 usbDevice[msExt->reader_index].interrupt,
1461 buffer, CCID_INTERRUPT_SIZE,
1462 bulk_transfer_cb, &completed, 0); /* No timeout ! */
1464 transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT;
1466 rv = libusb_submit_transfer(transfer);
1469 libusb_free_transfer(transfer);
1470 DEBUG_COMM2("libusb_submit_transfer err %d", rv);
1474 usbDevice[msExt->reader_index].polling_transfer = transfer;
1477 while (!completed && !msExt->terminated)
1479 rv = libusb_handle_events_completed(ctx, &completed);
1482 DEBUG_COMM2("libusb_handle_events err %d", rv);
1484 if (rv == LIBUSB_ERROR_INTERRUPTED)
1487 libusb_cancel_transfer(transfer);
1489 while (!completed && !msExt->terminated)
1491 if (libusb_handle_events_completed(ctx, &completed) < 0)
1499 usbDevice[msExt->reader_index].polling_transfer = NULL;
1502 libusb_free_transfer(transfer);
1507 actual_length = transfer->actual_length;
1508 status = transfer->status;
1510 libusb_free_transfer(transfer);
1514 case LIBUSB_TRANSFER_COMPLETED:
1515 DEBUG_COMM3("Multi_PollingProc (%d/%d): OK",
1516 usbDevice[msExt->reader_index].bus_number,
1517 usbDevice[msExt->reader_index].device_address);
1518 DEBUG_XXD("NotifySlotChange: ", buffer, actual_length);
1520 /* log the RDR_to_PC_NotifySlotChange data */
1522 for (b=0; b<actual_length-1; b++)
1526 /* 4 slots per byte */
1529 /* 2 bits per slot */
1530 int slot_status = ((buffer[1+b] >> (s*2)) & 3);
1531 const char *present, *change;
1533 present = (slot_status & 1) ? "present" : "absent";
1534 change = (slot_status & 2) ? "status changed" : "no change";
1536 DEBUG_COMM3("slot %d status: %d",
1537 s + b*4, slot_status);
1538 DEBUG_COMM3("ICC %s, %s", present, change);
1544 case LIBUSB_TRANSFER_TIMED_OUT:
1545 DEBUG_COMM3("Multi_PollingProc (%d/%d): Timeout",
1546 usbDevice[msExt->reader_index].bus_number,
1547 usbDevice[msExt->reader_index].device_address);
1551 /* if libusb_interrupt_transfer() times out
1552 * we get EILSEQ or EAGAIN */
1553 DEBUG_COMM4("Multi_PollingProc (%d/%d): %d",
1554 usbDevice[msExt->reader_index].bus_number,
1555 usbDevice[msExt->reader_index].device_address,
1559 /* Tell other slots that there's a new interrupt buffer */
1560 DEBUG_COMM3("Multi_PollingProc (%d/%d): Broadcast to slot(s)",
1561 usbDevice[msExt->reader_index].bus_number,
1562 usbDevice[msExt->reader_index].device_address);
1564 /* Lock the mutex */
1565 pthread_mutex_lock(&msExt->mutex);
1567 /* Set the status and the interrupt buffer */
1568 msExt->status = status;
1569 memset(msExt->buffer, 0, sizeof msExt->buffer);
1570 memcpy(msExt->buffer, buffer, actual_length);
1572 /* Broadcast the condition and unlock */
1573 pthread_cond_broadcast(&msExt->condition);
1574 pthread_mutex_unlock(&msExt->mutex);
1578 msExt->terminated = TRUE;
1582 DEBUG_CRITICAL4("Multi_PollingProc (%d/%d): error %d",
1583 usbDevice[msExt->reader_index].bus_number,
1584 usbDevice[msExt->reader_index].device_address, rv);
1587 /* Wake up the slot threads so they will exit as well */
1589 /* Lock the mutex */
1590 pthread_mutex_lock(&msExt->mutex);
1592 /* Set the status and fill-in the interrupt buffer */
1594 memset(msExt->buffer, 0xFF, sizeof msExt->buffer);
1596 /* Broadcast the condition */
1597 pthread_cond_broadcast(&msExt->condition);
1600 pthread_mutex_unlock(&msExt->mutex);
1603 DEBUG_COMM3("Multi_PollingProc (%d/%d): Thread terminated",
1604 usbDevice[msExt->reader_index].bus_number,
1605 usbDevice[msExt->reader_index].device_address);
1609 } /* Multi_PollingProc */
1612 /*****************************************************************************
1614 * Multi_PollingTerminate
1616 ****************************************************************************/
1617 static void Multi_PollingTerminate(struct usbDevice_MultiSlot_Extension *msExt)
1619 struct libusb_transfer *transfer;
1621 if (msExt && !msExt->terminated)
1623 msExt->terminated = TRUE;
1625 transfer = usbDevice[msExt->reader_index].polling_transfer;
1631 ret = libusb_cancel_transfer(transfer);
1633 DEBUG_CRITICAL2("libusb_cancel_transfer failed: %d", ret);
1636 } /* Multi_PollingTerminate */
1639 /*****************************************************************************
1641 * Multi_InterruptRead
1643 ****************************************************************************/
1644 static int Multi_InterruptRead(int reader_index, int timeout /* in ms */)
1646 struct usbDevice_MultiSlot_Extension *msExt;
1647 unsigned char buffer[CCID_INTERRUPT_SIZE];
1648 struct timespec cond_wait_until;
1649 struct timeval local_time;
1650 int rv, status, interrupt_byte, interrupt_mask;
1652 msExt = usbDevice[reader_index].multislot_extension;
1654 /* When stopped, return 0 so IFDHPolling will return IFD_NO_SUCH_DEVICE */
1655 if ((msExt == NULL) || msExt->terminated)
1658 DEBUG_PERIODIC3("Multi_InterruptRead (%d), timeout: %d ms",
1659 reader_index, timeout);
1661 /* Select the relevant bit in the interrupt buffer */
1662 interrupt_byte = (usbDevice[reader_index].ccid.bCurrentSlotIndex / 4) + 1;
1663 interrupt_mask = 0x02 << (2 * (usbDevice[reader_index].ccid.bCurrentSlotIndex % 4));
1665 /* Wait until the condition is signaled or a timeout occurs */
1666 gettimeofday(&local_time, NULL);
1667 cond_wait_until.tv_sec = local_time.tv_sec;
1668 cond_wait_until.tv_nsec = local_time.tv_usec * 1000;
1670 cond_wait_until.tv_sec += timeout / 1000;
1671 cond_wait_until.tv_nsec += 1000000 * (timeout % 1000);
1674 pthread_mutex_lock(&msExt->mutex);
1676 rv = pthread_cond_timedwait(&msExt->condition, &msExt->mutex,
1681 /* Retrieve interrupt buffer and request result */
1682 memcpy(buffer, msExt->buffer, sizeof buffer);
1683 status = msExt->status;
1686 if (rv == ETIMEDOUT)
1687 status = LIBUSB_TRANSFER_TIMED_OUT;
1691 /* Don't forget to unlock the mutex */
1692 pthread_mutex_unlock(&msExt->mutex);
1694 /* When stopped, return 0 so IFDHPolling will return IFD_NO_SUCH_DEVICE */
1695 if (msExt->terminated)
1699 if (status == LIBUSB_TRANSFER_COMPLETED)
1701 if (0 == (buffer[interrupt_byte] & interrupt_mask))
1703 DEBUG_PERIODIC2("Multi_InterruptRead (%d) -- skipped", reader_index);
1706 DEBUG_PERIODIC2("Multi_InterruptRead (%d), got an interrupt", reader_index);
1710 DEBUG_PERIODIC3("Multi_InterruptRead (%d), status=%d", reader_index, status);
1714 } /* Multi_InterruptRead */
1717 /*****************************************************************************
1719 * Multi_InterruptStop
1721 ****************************************************************************/
1722 static void Multi_InterruptStop(int reader_index)
1724 struct usbDevice_MultiSlot_Extension *msExt;
1725 int interrupt_byte, interrupt_mask;
1727 msExt = usbDevice[reader_index].multislot_extension;
1729 /* Already stopped ? */
1730 if ((NULL == msExt) || msExt->terminated)
1733 DEBUG_PERIODIC2("Stop (%d)", reader_index);
1735 interrupt_byte = (usbDevice[reader_index].ccid.bCurrentSlotIndex / 4) + 1;
1736 interrupt_mask = 0x02 << (2 * (usbDevice[reader_index].ccid.bCurrentSlotIndex % 4));
1738 pthread_mutex_lock(&msExt->mutex);
1740 /* Broacast an interrupt to wake-up the slot's thread */
1741 msExt->buffer[interrupt_byte] |= interrupt_mask;
1742 pthread_cond_broadcast(&msExt->condition);
1744 pthread_mutex_unlock(&msExt->mutex);
1745 } /* Multi_InterruptStop */
1748 /*****************************************************************************
1750 * Multi_CreateFirstSlot
1752 ****************************************************************************/
1753 static struct usbDevice_MultiSlot_Extension *Multi_CreateFirstSlot(int reader_index)
1755 struct usbDevice_MultiSlot_Extension *msExt;
1757 /* Allocate a new extension buffer */
1758 msExt = malloc(sizeof(struct usbDevice_MultiSlot_Extension));
1762 /* Remember the index */
1763 msExt->reader_index = reader_index;
1765 msExt->terminated = FALSE;
1767 msExt->transfer = NULL;
1769 /* Create mutex and condition object for the interrupt polling */
1770 pthread_mutex_init(&msExt->mutex, NULL);
1771 pthread_cond_init(&msExt->condition, NULL);
1773 /* create the thread in charge of the interrupt polling */
1774 pthread_create(&msExt->thread_proc, NULL, Multi_PollingProc, msExt);
1777 } /* Multi_CreateFirstSlot */
1780 /*****************************************************************************
1782 * Multi_CreateNextSlot
1784 ****************************************************************************/
1785 static struct usbDevice_MultiSlot_Extension *Multi_CreateNextSlot(int physical_reader_index)
1787 /* Take the extension buffer from the main slot */
1788 return usbDevice[physical_reader_index].multislot_extension;
1789 } /* Multi_CreateNextSlot */