/[pcsclite]/trunk/Drivers/ccid/src/ccid_usb.c
ViewVC logotype

Contents of /trunk/Drivers/ccid/src/ccid_usb.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2097 - (show annotations) (download)
Tue Jul 4 07:06:10 2006 UTC (6 years, 10 months ago) by rousseau
File MIME type: text/plain
File size: 22961 byte(s)
ReadUSB(): be sure we have read enough bytes before checking for frame
detectation
1 /*
2 ccid_usb.c: USB access routines using the libusb library
3 Copyright (C) 2003-2004 Ludovic Rousseau
4
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.
9
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.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 /*
21 * $Id$
22 */
23
24 #define __CCID_USB__
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <errno.h>
29 # ifdef S_SPLINT_S
30 # include <sys/types.h>
31 # endif
32 #include <usb.h>
33
34 #include "misc.h"
35 #include "ccid.h"
36 #include "config.h"
37 #include "debug.h"
38 #include "defs.h"
39 #include "utils.h"
40 #include "parser.h"
41 #include "ccid_ifdhandler.h"
42
43
44 /* write timeout
45 * we don't have to wait a long time since the card was doing nothing */
46 #define USB_WRITE_TIMEOUT (5 * 1000) /* 5 seconds timeout */
47
48 /*
49 * Proprietary USB Class (0xFF) are (or are not) accepted
50 * A proprietary class is used for devices released before the final CCID
51 * specifications were ready.
52 * We should not have problems with non CCID devices becasue the
53 * Manufacturer and Product ID are also used to identify the device */
54 #define ALLOW_PROPRIETARY_CLASS
55
56 /*
57 * The O2Micro OZ776S reader has a wrong USB descriptor
58 * The extra[] field is associated with the last endpoint instead of the
59 * main USB descriptor
60 */
61 #define O2MICRO_OZ776_PATCH
62
63 #define BUS_DEVICE_STRSIZE 32
64
65 typedef struct
66 {
67 usb_dev_handle *handle;
68 struct usb_device *dev;
69 int interface;
70
71 /*
72 * Endpoints
73 */
74 int bulk_in;
75 int bulk_out;
76
77 /* Number of slots using the same device */
78 int real_nb_opened_slots;
79 int *nb_opened_slots;
80
81 /*
82 * CCID infos common to USB and serial
83 */
84 _ccid_descriptor ccid;
85
86 } _usbDevice;
87
88 /* The _usbDevice structure must be defined before including ccid_usb.h */
89 #include "ccid_usb.h"
90
91 static int get_end_points(struct usb_device *dev, _usbDevice *usb_device);
92 int ccid_check_firmware(struct usb_device *dev);
93 static unsigned int *get_data_rates(unsigned int reader_index);
94
95 /* ne need to initialize to 0 since it is static */
96 static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];
97
98 #define PCSCLITE_MANUKEY_NAME "ifdVendorID"
99 #define PCSCLITE_PRODKEY_NAME "ifdProductID"
100 #define PCSCLITE_NAMEKEY_NAME "ifdFriendlyName"
101
102 struct _bogus_firmware
103 {
104 int vendor; /* idVendor */
105 int product; /* idProduct */
106 int firmware; /* bcdDevice: previous firmwares have bugs */
107 };
108
109 static struct _bogus_firmware Bogus_firmwares[] = {
110 { 0x0b97, 0x7762, 0x0111 }, /* Oz776S */ /* the firmware version if not correct since I don't have received a working reader yet */
111 { 0x04e6, 0xe001, 0x0516 }, /* SCR 331 */
112 { 0x04e6, 0x5111, 0x0620 }, /* SCR 331-DI */
113 { 0x04e6, 0x5115, 0x0514 }, /* SCR 335 */
114 { 0x04e6, 0xe003, 0x0510 }, /* SPR 532 */
115 { 0x0D46, 0x3001, 0x0037 }, /* KAAN Base */
116 { 0x0D46, 0x3002, 0x0037 }, /* KAAN Advanced */
117 { 0x09C3, 0x0008, 0x0203 }, /* ActivCard V2 */
118 { 0x0DC3, 0x1004, 0x0502 }, /* ASE IIIe USBv2 */
119 { 0x0DC3, 0x1102, 0x0607 }, /* ASE IIIe KB USB */
120 };
121
122 /* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
123 unsigned int SerialCustomDataRates[] = { GEMPLUS_CUSTOM_DATA_RATES, 0 };
124
125
126 /*****************************************************************************
127 *
128 * OpenUSB
129 *
130 ****************************************************************************/
131 status_t OpenUSB(unsigned int reader_index, /*@unused@*/ int Channel)
132 {
133 return OpenUSBByName(reader_index, NULL);
134 } /* OpenUSB */
135
136
137 /*****************************************************************************
138 *
139 * OpenUSBByName
140 *
141 ****************************************************************************/
142 status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
143 {
144 static struct usb_bus *busses = NULL;
145 int alias = 0;
146 struct usb_bus *bus;
147 struct usb_dev_handle *dev_handle;
148 char keyValue[TOKEN_MAX_VALUE_SIZE];
149 unsigned int vendorID, productID;
150 char infofile[FILENAME_MAX];
151 unsigned int device_vendor, device_product;
152 char *dirname = NULL, *filename = NULL;
153 static int previous_reader_index = -1;
154
155 DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);
156
157 /* device name specified */
158 if (device)
159 {
160 /* format: usb:%04x/%04x, vendor, product */
161 if (strncmp("usb:", device, 4) != 0)
162 {
163 DEBUG_CRITICAL2("device name does not start with \"usb:\": %s",
164 device);
165 return STATUS_UNSUCCESSFUL;
166 }
167
168 if (sscanf(device, "usb:%x/%x", &device_vendor, &device_product) != 2)
169 {
170 DEBUG_CRITICAL2("device name can't be parsed: %s", device);
171 return STATUS_UNSUCCESSFUL;
172 }
173
174 /* format usb:%04x/%04x:libusb:%s
175 * with %s set to %s:%s, dirname, filename */
176 if ((dirname = strstr(device, "libusb:")) != NULL)
177 {
178 /* dirname points to the first char after libusb: */
179 dirname += strlen("libusb:");
180
181 /* search the : (separation) char */
182 filename = strchr(dirname, ':');
183
184 if (filename)
185 {
186 /* end the dirname string */
187 *filename = '\0';
188
189 /* filename points to the first char after : */
190 filename++;
191 }
192 else
193 {
194 /* parse failed */
195 dirname = NULL;
196
197 DEBUG_CRITICAL2("can't parse using libusb scheme: %s", device);
198 }
199 }
200 }
201
202 if (busses == NULL)
203 usb_init();
204
205 usb_find_busses();
206 usb_find_devices();
207
208 busses = usb_get_busses();
209
210 if (busses == NULL)
211 {
212 DEBUG_CRITICAL("No USB busses found");
213 return STATUS_UNSUCCESSFUL;
214 }
215
216 /* is the reader_index already used? */
217 if (usbDevice[reader_index].handle != NULL)
218 {
219 DEBUG_CRITICAL2("USB driver with index %X already in use",
220 reader_index);
221 return STATUS_UNSUCCESSFUL;
222 }
223
224 /* Info.plist full patch filename */
225 snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
226 PCSCLITE_HP_DROPDIR, BUNDLE);
227
228 /* general driver info */
229 if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))
230 {
231 DEBUG_INFO2("Manufacturer: %s", keyValue);
232 }
233 else
234 {
235 DEBUG_INFO2("LTPBundleFindValueWithKey error. Can't find %s?",
236 infofile);
237 return STATUS_UNSUCCESSFUL;
238 }
239 if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))
240 {
241 DEBUG_INFO2("ProductString: %s", keyValue);
242 }
243 else
244 return STATUS_UNSUCCESSFUL;
245 if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))
246 {
247 DEBUG_INFO2("Copyright: %s", keyValue);
248 }
249 else
250 return STATUS_UNSUCCESSFUL;
251 vendorID = strlen(keyValue);
252 alias = 0x1C;
253 for (; vendorID--;)
254 alias ^= keyValue[vendorID];
255
256 /* for any supported reader */
257 while (LTPBundleFindValueWithKey(infofile, PCSCLITE_MANUKEY_NAME, keyValue, alias) == 0)
258 {
259 vendorID = strtoul(keyValue, NULL, 0);
260
261 if (LTPBundleFindValueWithKey(infofile, PCSCLITE_PRODKEY_NAME, keyValue, alias))
262 goto end;
263 productID = strtoul(keyValue, NULL, 0);
264
265 if (LTPBundleFindValueWithKey(infofile, PCSCLITE_NAMEKEY_NAME, keyValue, alias))
266 goto end;
267
268 /* go to next supported reader for next round */
269 alias++;
270
271 /* the device was specified but is not the one we are trying to find */
272 if (device
273 && (vendorID != device_vendor || productID != device_product))
274 continue;
275
276 /* on any USB buses */
277 for (bus = busses; bus; bus = bus->next)
278 {
279 struct usb_device *dev;
280
281 /* any device on this bus */
282 for (dev = bus->devices; dev; dev = dev->next)
283 {
284 /* device defined by name? */
285 if (dirname && (strcmp(dirname, bus->dirname)
286 || strcmp(filename, dev->filename)))
287 continue;
288
289 if (dev->descriptor.idVendor == vendorID
290 && dev->descriptor.idProduct == productID)
291 {
292 int r, already_used;
293 struct usb_interface *usb_interface = NULL;
294 int interface;
295
296 /* is it already opened? */
297 already_used = FALSE;
298
299 for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
300 {
301 if (usbDevice[r].dev)
302 {
303 DEBUG_COMM3("Checking device: %s/%s",
304 bus->dirname, dev->filename);
305 /* same busname, same filename */
306 if (strcmp(usbDevice[r].dev->bus->dirname, bus->dirname) == 0 && strcmp(usbDevice[r].dev->filename, dev->filename) == 0)
307 already_used = TRUE;
308 }
309 }
310
311 /* this reader is already managed by us */
312 if (already_used)
313 {
314 if ((previous_reader_index != -1)
315 && usbDevice[previous_reader_index].dev
316 && (strcmp(usbDevice[previous_reader_index].dev->bus->dirname, bus->dirname) == 0)
317 && (strcmp(usbDevice[previous_reader_index].dev->filename, dev->filename) == 0)
318 && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)
319 {
320 /* we reuse the same device
321 * and the reader is multi-slot */
322 usbDevice[reader_index] = usbDevice[previous_reader_index];
323 /* the other slots do not have the same data rates */
324 if ((GEMCOREPOSPRO == usbDevice[reader_index].ccid.readerID)
325 || (GEMCORESIMPRO == usbDevice[reader_index].ccid.readerID))
326 {
327 usbDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates;
328 usbDevice[reader_index].ccid.dwMaxDataRate = 125000;
329 }
330
331 *usbDevice[reader_index].nb_opened_slots += 1;
332 usbDevice[reader_index].ccid.bCurrentSlotIndex++;
333 DEBUG_INFO2("Opening slot: %d",
334 usbDevice[reader_index].ccid.bCurrentSlotIndex);
335 goto end;
336 }
337 else
338 {
339 DEBUG_INFO3("USB device %s/%s already in use."
340 " Checking next one.",
341 bus->dirname, dev->filename);
342 }
343
344 continue;
345 }
346
347 DEBUG_COMM3("Trying to open USB bus/device: %s/%s",
348 bus->dirname, dev->filename);
349
350 dev_handle = usb_open(dev);
351 if (dev_handle == NULL)
352 {
353 DEBUG_CRITICAL4("Can't usb_open(%s/%s): %s",
354 bus->dirname, dev->filename, strerror(errno));
355
356 continue;
357 }
358
359 /* now we found a free reader and we try to use it */
360 if (dev->config == NULL)
361 {
362 usb_close(dev_handle);
363 DEBUG_CRITICAL3("No dev->config found for %s/%s",
364 bus->dirname, dev->filename);
365 return STATUS_UNSUCCESSFUL;
366 }
367
368 usb_interface = get_ccid_usb_interface(dev);
369 if (usb_interface == NULL)
370 {
371 usb_close(dev_handle);
372 DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",
373 bus->dirname, dev->filename);
374 return STATUS_UNSUCCESSFUL;
375 }
376
377 if (usb_interface->altsetting->extralen != 54)
378 {
379 usb_close(dev_handle);
380 DEBUG_CRITICAL4("Extra field for %s/%s has a wrong length: %d", bus->dirname, dev->filename, usb_interface->altsetting->extralen);
381 return STATUS_UNSUCCESSFUL;
382 }
383
384 interface = usb_interface->altsetting->bInterfaceNumber;
385 if (usb_claim_interface(dev_handle, interface) < 0)
386 {
387 usb_close(dev_handle);
388 DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",
389 bus->dirname, dev->filename, strerror(errno));
390 return STATUS_UNSUCCESSFUL;
391 }
392
393 DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",
394 dev->descriptor.idVendor,
395 dev->descriptor.idProduct, keyValue);
396 DEBUG_INFO3("Using USB bus/device: %s/%s",
397 bus->dirname, dev->filename);
398
399 /* check for firmware bugs */
400 if (ccid_check_firmware(dev))
401 {
402 usb_close(dev_handle);
403 return STATUS_UNSUCCESSFUL;
404 }
405
406 /* Get Endpoints values*/
407 get_end_points(dev, &usbDevice[reader_index]);
408
409 /* store device information */
410 usbDevice[reader_index].handle = dev_handle;
411 usbDevice[reader_index].dev = dev;
412 usbDevice[reader_index].interface = interface;
413 usbDevice[reader_index].real_nb_opened_slots = 1;
414 usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
415
416 /* CCID common informations */
417 usbDevice[reader_index].ccid.real_bSeq = 0;
418 usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq;
419 usbDevice[reader_index].ccid.readerID =
420 (dev->descriptor.idVendor << 16) +
421 dev->descriptor.idProduct;
422 usbDevice[reader_index].ccid.dwFeatures = dw2i(usb_interface->altsetting->extra, 40);
423 usbDevice[reader_index].ccid.bPINSupport = usb_interface->altsetting->extra[52];
424 usbDevice[reader_index].ccid.dwMaxCCIDMessageLength = dw2i(usb_interface->altsetting->extra, 44);
425 usbDevice[reader_index].ccid.dwMaxIFSD = dw2i(usb_interface->altsetting->extra, 28);
426 usbDevice[reader_index].ccid.dwDefaultClock = dw2i(usb_interface->altsetting->extra, 10);
427 usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);
428 usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];
429 usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
430 usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
431 usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index);
432 goto end;
433 }
434 }
435 }
436 }
437 end:
438 if (usbDevice[reader_index].handle == NULL)
439 return STATUS_UNSUCCESSFUL;
440
441 /* memorise the current reader_index so we can detect
442 * a new OpenUSBByName on a multi slot reader */
443 previous_reader_index = reader_index;
444
445 return STATUS_SUCCESS;
446 } /* OpenUSBByName */
447
448
449 /*****************************************************************************
450 *
451 * WriteUSB
452 *
453 ****************************************************************************/
454 status_t WriteUSB(unsigned int reader_index, unsigned int length,
455 unsigned char *buffer)
456 {
457 int rv;
458 char debug_header[] = "-> 121234 ";
459
460 sprintf(debug_header, "-> %06X ", (int)reader_index);
461
462 DEBUG_XXD(debug_header, buffer, length);
463
464 rv = usb_bulk_write(usbDevice[reader_index].handle,
465 usbDevice[reader_index].bulk_out, (char *)buffer, length,
466 USB_WRITE_TIMEOUT);
467
468 if (rv < 0)
469 {
470 if (usbDevice[reader_index].dev->bus)
471 {
472 DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",
473 usbDevice[reader_index].dev->bus->dirname,
474 usbDevice[reader_index].dev->filename, strerror(errno));
475 }
476 else
477 DEBUG_CRITICAL2("usb_bulk_write(no device): %s", strerror(errno));
478
479 return STATUS_UNSUCCESSFUL;
480 }
481
482 return STATUS_SUCCESS;
483 } /* WriteUSB */
484
485
486 /*****************************************************************************
487 *
488 * ReadUSB
489 *
490 ****************************************************************************/
491 status_t ReadUSB(unsigned int reader_index, unsigned int * length,
492 unsigned char *buffer)
493 {
494 int rv;
495 char debug_header[] = "<- 121234 ";
496 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
497
498 read_again:
499 sprintf(debug_header, "<- %06X ", (int)reader_index);
500
501 rv = usb_bulk_read(usbDevice[reader_index].handle,
502 usbDevice[reader_index].bulk_in, (char *)buffer, *length,
503 usbDevice[reader_index].ccid.readTimeout * 1000);
504
505 if (rv < 0)
506 {
507 *length = 0;
508 DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",
509 usbDevice[reader_index].dev->bus->dirname,
510 usbDevice[reader_index].dev->filename, strerror(errno));
511 return STATUS_UNSUCCESSFUL;
512 }
513
514 *length = rv;
515
516 DEBUG_XXD(debug_header, buffer, *length);
517
518 #define BSEQ_OFFSET 6
519 if ((*length >= BSEQ_OFFSET)
520 && (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1))
521 {
522 DEBUG_INFO("Duplicate frame detected");
523 goto read_again;
524 }
525
526 return STATUS_SUCCESS;
527 } /* ReadUSB */
528
529
530 /*****************************************************************************
531 *
532 * CloseUSB
533 *
534 ****************************************************************************/
535 status_t CloseUSB(unsigned int reader_index)
536 {
537 /* device not opened */
538 if (usbDevice[reader_index].dev == NULL)
539 return STATUS_UNSUCCESSFUL;
540
541 DEBUG_COMM3("Closing USB device: %s/%s",
542 usbDevice[reader_index].dev->bus->dirname,
543 usbDevice[reader_index].dev->filename);
544
545 if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates
546 && (usbDevice[reader_index].ccid.bCurrentSlotIndex == 0))
547 {
548 free(usbDevice[reader_index].ccid.arrayOfSupportedDataRates);
549 usbDevice[reader_index].ccid.arrayOfSupportedDataRates = NULL;
550 }
551
552 /* one slot closed */
553 (*usbDevice[reader_index].nb_opened_slots)--;
554
555 /* release the allocated ressources for the last slot only */
556 if (0 == *usbDevice[reader_index].nb_opened_slots)
557 {
558 DEBUG_COMM("Last slot closed. Release resources");
559
560 /* reset so that bSeq starts at 0 again */
561 if (DriverOptions & DRIVER_OPTION_RESET_ON_CLOSE)
562 usb_reset(usbDevice[reader_index].handle);
563
564 usb_release_interface(usbDevice[reader_index].handle,
565 usbDevice[reader_index].interface);
566 usb_close(usbDevice[reader_index].handle);
567 }
568
569 /* mark the resource unused */
570 usbDevice[reader_index].handle = NULL;
571 usbDevice[reader_index].dev = NULL;
572 usbDevice[reader_index].interface = 0;
573
574 return STATUS_SUCCESS;
575 } /* CloseUSB */
576
577
578 /*****************************************************************************
579 *
580 * get_ccid_descriptor
581 *
582 ****************************************************************************/
583 _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
584 {
585 return &usbDevice[reader_index].ccid;
586 } /* get_ccid_descriptor */
587
588
589 /*****************************************************************************
590 *
591 * get_desc
592 *
593 ****************************************************************************/
594 int get_desc(int lun, usb_dev_handle **handle, struct
595 usb_device **dev)
596 {
597 int reader_index;
598
599 if (-1 == (reader_index = LunToReaderIndex(lun)))
600 return FALSE;
601
602 *handle = usbDevice[reader_index].handle;
603 *dev = usbDevice[reader_index].dev;
604
605 return TRUE;
606 } /* get_desc */
607
608
609 /*****************************************************************************
610 *
611 * get_end_points
612 *
613 ****************************************************************************/
614 static int get_end_points(struct usb_device *dev, _usbDevice *usb_device)
615 {
616 int i;
617 int bEndpointAddress;
618 struct usb_interface *usb_interface = get_ccid_usb_interface(dev);
619
620 /*
621 * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
622 */
623 for (i=0; i<3; i++)
624 {
625 if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)
626 continue;
627
628 bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;
629
630 if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
631 usb_device->bulk_in = bEndpointAddress;
632
633 if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)
634 usb_device->bulk_out = bEndpointAddress;
635 }
636
637 return 0;
638 } /* get_end_points */
639
640
641 /*****************************************************************************
642 *
643 * get_ccid_usb_interface
644 *
645 ****************************************************************************/
646 /*@null@*/ EXTERNAL struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)
647 {
648 struct usb_interface *usb_interface = NULL;
649 int i;
650
651 /* if multiple interfaces use the first one with CCID class type */
652 for (i=0; i<dev->config->bNumInterfaces; i++)
653 {
654 /* CCID Class? */
655 if (dev->config->interface[i].altsetting->bInterfaceClass == 0xb
656 #ifdef ALLOW_PROPRIETARY_CLASS
657 || dev->config->interface[i].altsetting->bInterfaceClass == 0xff
658 #endif
659 )
660 {
661 usb_interface = &dev->config->interface[i];
662 break;
663 }
664 }
665
666 #ifdef O2MICRO_OZ776_PATCH
667 if (usb_interface != NULL
668 && (OZ776 == (dev->descriptor.idVendor << 16)
669 + dev->descriptor.idProduct)
670 && (0 == usb_interface->altsetting->extralen)) /* this is the bug */
671 {
672 for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
673 {
674 /* find the extra[] array */
675 if (54 == usb_interface->altsetting->endpoint[i].extralen)
676 {
677 /* get the extra[] from the endpoint */
678 usb_interface->altsetting->extralen = 54;
679 usb_interface->altsetting->extra =
680 usb_interface->altsetting->endpoint[i].extra;
681 break;
682 }
683 }
684 }
685 #endif
686
687 return usb_interface;
688 } /* get_ccid_usb_interface */
689
690
691 /*****************************************************************************
692 *
693 * ccid_check_firmware
694 *
695 ****************************************************************************/
696 int ccid_check_firmware(struct usb_device *dev)
697 {
698 int i;
699
700 for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)
701 {
702 if (dev->descriptor.idVendor != Bogus_firmwares[i].vendor)
703 continue;
704
705 if (dev->descriptor.idProduct != Bogus_firmwares[i].product)
706 continue;
707
708 /* firmware too old and buggy */
709 if (dev->descriptor.bcdDevice < Bogus_firmwares[i].firmware)
710 {
711 if (DriverOptions & DRIVER_OPTION_USE_BOGUS_FIRMWARE)
712 {
713 DEBUG_INFO3("Firmware (%X.%02X) is bogus! but you choosed to use it",
714 dev->descriptor.bcdDevice >> 8,
715 dev->descriptor.bcdDevice & 0xFF);
716 return FALSE;
717 }
718 else
719 {
720 DEBUG_CRITICAL3("Firmware (%X.%02X) is bogus! Upgrade the reader firmware or get a new reader.",
721 dev->descriptor.bcdDevice >> 8,
722 dev->descriptor.bcdDevice & 0xFF);
723 return TRUE;
724 }
725 }
726 }
727
728 /* by default the firmware is not bogus */
729 return FALSE;
730 } /* ccid_check_firmware */
731
732 /*****************************************************************************
733 *
734 * get_data_rates
735 *
736 ****************************************************************************/
737 static unsigned int *get_data_rates(unsigned int reader_index)
738 {
739 int n, i, len;
740 unsigned char buffer[256*sizeof(int)]; /* maximum is 256 records */
741 unsigned int *int_array;
742
743 /* See CCID 3.7.3 page 25 */
744 n = usb_control_msg(usbDevice[reader_index].handle,
745 0xA1, /* request type */
746 0x03, /* GET_DATA_RATES */
747 0x00, /* value */
748 usbDevice[reader_index].interface, /* interface */
749 (char *)buffer,
750 sizeof(buffer),
751 usbDevice[reader_index].ccid.readTimeout * 1000);
752
753 /* we got an error? */
754 if (n <= 0)
755 {
756 DEBUG_INFO2("IFD does not support GET_DATA_RATES request: %s",
757 strerror(errno));
758 return NULL;
759 }
760
761 /* we got a strange value */
762 if (n % 4)
763 {
764 DEBUG_INFO2("Wrong GET DATA RATES size: %d", n);
765 return NULL;
766 }
767
768 /* allocate the buffer (including the end marker) */
769 n /= sizeof(int);
770
771 /* we do not get the expected number of data rates */
772 len = get_ccid_usb_interface(usbDevice[reader_index].dev)
773 ->altsetting->extra[27]; /* bNumDataRatesSupported */
774 if ((n != len) && len)
775 {
776 DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);
777
778 /* we got more data than expected */
779 if (n > len)
780 n = len;
781 }
782
783 int_array = calloc(n+1, sizeof(int));
784 if (NULL == int_array)
785 {
786 DEBUG_CRITICAL("Memory allocation failed");
787 return NULL;
788 }
789
790 /* convert in correct endianess */
791 for (i=0; i<n; i++)
792 {
793 int_array[i] = dw2i(buffer, i*4);
794 DEBUG_INFO2("declared: %d bps", int_array[i]);
795 }
796
797 /* end of array marker */
798 int_array[i] = 0;
799
800 return int_array;
801 }
802

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.5