/[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 - (hide 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 rousseau 269 /*
2     ccid_usb.c: USB access routines using the libusb library
3 rousseau 649 Copyright (C) 2003-2004 Ludovic Rousseau
4 rousseau 269
5 rousseau 1399 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 rousseau 269
10 rousseau 1399 This library is distributed in the hope that it will be useful,
11 rousseau 269 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 rousseau 1399 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13     Lesser General Public License for more details.
14 rousseau 269
15 rousseau 1399 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 rousseau 269 */
19    
20     /*
21     * $Id$
22     */
23    
24     #define __CCID_USB__
25    
26     #include <stdio.h>
27     #include <string.h>
28     #include <errno.h>
29 rousseau 1052 # ifdef S_SPLINT_S
30     # include <sys/types.h>
31     # endif
32 rousseau 269 #include <usb.h>
33    
34 rousseau 2014 #include "misc.h"
35 rousseau 878 #include "ccid.h"
36 rousseau 269 #include "config.h"
37     #include "debug.h"
38 rousseau 878 #include "defs.h"
39 rousseau 269 #include "utils.h"
40     #include "parser.h"
41 rousseau 878 #include "ccid_ifdhandler.h"
42 rousseau 269
43    
44 rousseau 570 /* 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 rousseau 762 /*
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 rousseau 570
56 rousseau 1256 /*
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 rousseau 269 #define BUS_DEVICE_STRSIZE 32
64    
65     typedef struct
66     {
67     usb_dev_handle *handle;
68     struct usb_device *dev;
69 rousseau 1327 int interface;
70 rousseau 269
71     /*
72     * Endpoints
73     */
74     int bulk_in;
75     int bulk_out;
76 rousseau 406
77 rousseau 1791 /* Number of slots using the same device */
78     int real_nb_opened_slots;
79     int *nb_opened_slots;
80    
81 rousseau 406 /*
82     * CCID infos common to USB and serial
83     */
84     _ccid_descriptor ccid;
85    
86 rousseau 269 } _usbDevice;
87    
88 rousseau 406 /* The _usbDevice structure must be defined before including ccid_usb.h */
89 rousseau 269 #include "ccid_usb.h"
90    
91 rousseau 878 static int get_end_points(struct usb_device *dev, _usbDevice *usb_device);
92 rousseau 1287 int ccid_check_firmware(struct usb_device *dev);
93 rousseau 1459 static unsigned int *get_data_rates(unsigned int reader_index);
94 rousseau 878
95 rousseau 892 /* ne need to initialize to 0 since it is static */
96 rousseau 1077 static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];
97 rousseau 269
98     #define PCSCLITE_MANUKEY_NAME "ifdVendorID"
99     #define PCSCLITE_PRODKEY_NAME "ifdProductID"
100     #define PCSCLITE_NAMEKEY_NAME "ifdFriendlyName"
101    
102 rousseau 1287 struct _bogus_firmware
103     {
104     int vendor; /* idVendor */
105     int product; /* idProduct */
106     int firmware; /* bcdDevice: previous firmwares have bugs */
107     };
108 rousseau 649
109 rousseau 1287 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 rousseau 1312 { 0x04e6, 0xe001, 0x0516 }, /* SCR 331 */
112     { 0x04e6, 0x5111, 0x0620 }, /* SCR 331-DI */
113 rousseau 1287 { 0x04e6, 0x5115, 0x0514 }, /* SCR 335 */
114 rousseau 2048 { 0x04e6, 0xe003, 0x0510 }, /* SPR 532 */
115 rousseau 1325 { 0x0D46, 0x3001, 0x0037 }, /* KAAN Base */
116     { 0x0D46, 0x3002, 0x0037 }, /* KAAN Advanced */
117 rousseau 1875 { 0x09C3, 0x0008, 0x0203 }, /* ActivCard V2 */
118 rousseau 2002 { 0x0DC3, 0x1004, 0x0502 }, /* ASE IIIe USBv2 */
119     { 0x0DC3, 0x1102, 0x0607 }, /* ASE IIIe KB USB */
120 rousseau 1287 };
121    
122 rousseau 1808 /* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
123     unsigned int SerialCustomDataRates[] = { GEMPLUS_CUSTOM_DATA_RATES, 0 };
124 rousseau 1287
125 rousseau 1808
126 rousseau 269 /*****************************************************************************
127     *
128     * OpenUSB
129     *
130     ****************************************************************************/
131 rousseau 1106 status_t OpenUSB(unsigned int reader_index, /*@unused@*/ int Channel)
132 rousseau 269 {
133 rousseau 1106 return OpenUSBByName(reader_index, NULL);
134 rousseau 649 } /* OpenUSB */
135    
136    
137     /*****************************************************************************
138     *
139     * OpenUSBByName
140     *
141     ****************************************************************************/
142 rousseau 1106 status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
143 rousseau 649 {
144 rousseau 269 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 rousseau 1569 unsigned int vendorID, productID;
150 rousseau 301 char infofile[FILENAME_MAX];
151 rousseau 892 unsigned int device_vendor, device_product;
152 rousseau 781 char *dirname = NULL, *filename = NULL;
153 rousseau 1151 static int previous_reader_index = -1;
154 rousseau 269
155 rousseau 1106 DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);
156 rousseau 269
157 rousseau 662 /* device name specified */
158     if (device)
159     {
160 rousseau 781 /* format: usb:%04x/%04x, vendor, product */
161 rousseau 662 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 rousseau 781
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 rousseau 662 }
201    
202 rousseau 269 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 rousseau 1106 /* is the reader_index already used? */
217     if (usbDevice[reader_index].handle != NULL)
218 rousseau 269 {
219 rousseau 1106 DEBUG_CRITICAL2("USB driver with index %X already in use",
220     reader_index);
221 rousseau 269 return STATUS_UNSUCCESSFUL;
222     }
223    
224 rousseau 301 /* Info.plist full patch filename */
225 rousseau 406 snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
226     PCSCLITE_HP_DROPDIR, BUNDLE);
227 rousseau 301
228 rousseau 269 /* general driver info */
229 rousseau 301 if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))
230 rousseau 774 {
231 rousseau 1792 DEBUG_INFO2("Manufacturer: %s", keyValue);
232 rousseau 774 }
233 rousseau 269 else
234     {
235 rousseau 1792 DEBUG_INFO2("LTPBundleFindValueWithKey error. Can't find %s?",
236 rousseau 301 infofile);
237 rousseau 269 return STATUS_UNSUCCESSFUL;
238     }
239 rousseau 301 if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))
240 rousseau 774 {
241 rousseau 1792 DEBUG_INFO2("ProductString: %s", keyValue);
242 rousseau 774 }
243 rousseau 269 else
244     return STATUS_UNSUCCESSFUL;
245 rousseau 301 if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))
246 rousseau 774 {
247 rousseau 1792 DEBUG_INFO2("Copyright: %s", keyValue);
248 rousseau 774 }
249 rousseau 269 else
250     return STATUS_UNSUCCESSFUL;
251     vendorID = strlen(keyValue);
252 rousseau 2083 alias = 0x1C;
253 rousseau 269 for (; vendorID--;)
254     alias ^= keyValue[vendorID];
255    
256     /* for any supported reader */
257 rousseau 301 while (LTPBundleFindValueWithKey(infofile, PCSCLITE_MANUKEY_NAME, keyValue, alias) == 0)
258 rousseau 269 {
259 rousseau 1079 vendorID = strtoul(keyValue, NULL, 0);
260 rousseau 269
261 rousseau 301 if (LTPBundleFindValueWithKey(infofile, PCSCLITE_PRODKEY_NAME, keyValue, alias))
262 rousseau 269 goto end;
263 rousseau 1079 productID = strtoul(keyValue, NULL, 0);
264 rousseau 269
265 rousseau 301 if (LTPBundleFindValueWithKey(infofile, PCSCLITE_NAMEKEY_NAME, keyValue, alias))
266 rousseau 269 goto end;
267    
268 rousseau 662 /* 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 rousseau 269 /* 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 rousseau 781 /* device defined by name? */
285     if (dirname && (strcmp(dirname, bus->dirname)
286     || strcmp(filename, dev->filename)))
287     continue;
288    
289 rousseau 269 if (dev->descriptor.idVendor == vendorID
290     && dev->descriptor.idProduct == productID)
291     {
292     int r, already_used;
293 rousseau 662 struct usb_interface *usb_interface = NULL;
294     int interface;
295 rousseau 269
296     /* is it already opened? */
297     already_used = FALSE;
298 rousseau 649
299 rousseau 1077 for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
300 rousseau 269 {
301 rousseau 662 if (usbDevice[r].dev)
302 rousseau 269 {
303 rousseau 662 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 rousseau 269 }
309     }
310    
311 rousseau 662 /* this reader is already managed by us */
312     if (already_used)
313 rousseau 269 {
314 rousseau 1151 if ((previous_reader_index != -1)
315 rousseau 1804 && usbDevice[previous_reader_index].dev
316 rousseau 1151 && (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 rousseau 1808 /* 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 rousseau 1791 *usbDevice[reader_index].nb_opened_slots += 1;
332 rousseau 1151 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 rousseau 301
344 rousseau 662 continue;
345     }
346 rousseau 269
347 rousseau 662 DEBUG_COMM3("Trying to open USB bus/device: %s/%s",
348     bus->dirname, dev->filename);
349 rousseau 269
350 rousseau 662 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 rousseau 650
356 rousseau 662 continue;
357     }
358 rousseau 579
359 rousseau 662 /* now we found a free reader and we try to use it */
360     if (dev->config == NULL)
361     {
362 rousseau 1585 usb_close(dev_handle);
363 rousseau 662 DEBUG_CRITICAL3("No dev->config found for %s/%s",
364     bus->dirname, dev->filename);
365     return STATUS_UNSUCCESSFUL;
366     }
367 rousseau 269
368 rousseau 662 usb_interface = get_ccid_usb_interface(dev);
369     if (usb_interface == NULL)
370     {
371 rousseau 1585 usb_close(dev_handle);
372 rousseau 662 DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",
373     bus->dirname, dev->filename);
374     return STATUS_UNSUCCESSFUL;
375     }
376 rousseau 269
377 rousseau 662 if (usb_interface->altsetting->extralen != 54)
378     {
379 rousseau 1585 usb_close(dev_handle);
380 rousseau 662 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 rousseau 269 }
383 rousseau 662
384     interface = usb_interface->altsetting->bInterfaceNumber;
385     if (usb_claim_interface(dev_handle, interface) < 0)
386 rousseau 269 {
387 rousseau 1585 usb_close(dev_handle);
388 rousseau 662 DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",
389     bus->dirname, dev->filename, strerror(errno));
390     return STATUS_UNSUCCESSFUL;
391 rousseau 269 }
392 rousseau 662
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 rousseau 1287 /* check for firmware bugs */
400     if (ccid_check_firmware(dev))
401 rousseau 1585 {
402     usb_close(dev_handle);
403 rousseau 1287 return STATUS_UNSUCCESSFUL;
404 rousseau 1585 }
405 rousseau 1287
406 rousseau 662 /* Get Endpoints values*/
407 rousseau 1106 get_end_points(dev, &usbDevice[reader_index]);
408 rousseau 662
409     /* store device information */
410 rousseau 1106 usbDevice[reader_index].handle = dev_handle;
411     usbDevice[reader_index].dev = dev;
412 rousseau 1327 usbDevice[reader_index].interface = interface;
413 rousseau 1791 usbDevice[reader_index].real_nb_opened_slots = 1;
414     usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
415 rousseau 662
416     /* CCID common informations */
417 rousseau 1149 usbDevice[reader_index].ccid.real_bSeq = 0;
418     usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq;
419 rousseau 1106 usbDevice[reader_index].ccid.readerID =
420 rousseau 662 (dev->descriptor.idVendor << 16) +
421     dev->descriptor.idProduct;
422 rousseau 1106 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 rousseau 1485 usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);
428 rousseau 1106 usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];
429     usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
430 rousseau 1453 usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
431 rousseau 1446 usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index);
432 rousseau 662 goto end;
433 rousseau 269 }
434     }
435     }
436     }
437     end:
438 rousseau 1106 if (usbDevice[reader_index].handle == NULL)
439 rousseau 269 return STATUS_UNSUCCESSFUL;
440    
441 rousseau 1151 /* 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 rousseau 269 return STATUS_SUCCESS;
446 rousseau 649 } /* OpenUSBByName */
447 rousseau 269
448    
449     /*****************************************************************************
450     *
451     * WriteUSB
452     *
453     ****************************************************************************/
454 rousseau 1106 status_t WriteUSB(unsigned int reader_index, unsigned int length,
455     unsigned char *buffer)
456 rousseau 269 {
457     int rv;
458     char debug_header[] = "-> 121234 ";
459    
460 rousseau 1106 sprintf(debug_header, "-> %06X ", (int)reader_index);
461 rousseau 269
462     DEBUG_XXD(debug_header, buffer, length);
463    
464 rousseau 1106 rv = usb_bulk_write(usbDevice[reader_index].handle,
465     usbDevice[reader_index].bulk_out, (char *)buffer, length,
466     USB_WRITE_TIMEOUT);
467 rousseau 269
468     if (rv < 0)
469     {
470 rousseau 1547 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 rousseau 269 return STATUS_UNSUCCESSFUL;
480     }
481    
482     return STATUS_SUCCESS;
483     } /* WriteUSB */
484    
485    
486     /*****************************************************************************
487     *
488     * ReadUSB
489     *
490     ****************************************************************************/
491 rousseau 1106 status_t ReadUSB(unsigned int reader_index, unsigned int * length,
492     unsigned char *buffer)
493 rousseau 269 {
494     int rv;
495     char debug_header[] = "<- 121234 ";
496 rousseau 2083 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
497 rousseau 269
498 rousseau 2083 read_again:
499 rousseau 1106 sprintf(debug_header, "<- %06X ", (int)reader_index);
500 rousseau 269
501 rousseau 1106 rv = usb_bulk_read(usbDevice[reader_index].handle,
502     usbDevice[reader_index].bulk_in, (char *)buffer, *length,
503 rousseau 1453 usbDevice[reader_index].ccid.readTimeout * 1000);
504 rousseau 269
505     if (rv < 0)
506     {
507 rousseau 895 *length = 0;
508 rousseau 662 DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",
509 rousseau 1106 usbDevice[reader_index].dev->bus->dirname,
510     usbDevice[reader_index].dev->filename, strerror(errno));
511 rousseau 269 return STATUS_UNSUCCESSFUL;
512     }
513    
514 rousseau 895 *length = rv;
515    
516 rousseau 269 DEBUG_XXD(debug_header, buffer, *length);
517    
518 rousseau 2083 #define BSEQ_OFFSET 6
519 rousseau 2097 if ((*length >= BSEQ_OFFSET)
520     && (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1))
521 rousseau 2083 {
522     DEBUG_INFO("Duplicate frame detected");
523     goto read_again;
524     }
525    
526 rousseau 269 return STATUS_SUCCESS;
527     } /* ReadUSB */
528    
529    
530     /*****************************************************************************
531     *
532     * CloseUSB
533     *
534     ****************************************************************************/
535 rousseau 1106 status_t CloseUSB(unsigned int reader_index)
536 rousseau 269 {
537     /* device not opened */
538 rousseau 1106 if (usbDevice[reader_index].dev == NULL)
539 rousseau 269 return STATUS_UNSUCCESSFUL;
540    
541 rousseau 662 DEBUG_COMM3("Closing USB device: %s/%s",
542 rousseau 1106 usbDevice[reader_index].dev->bus->dirname,
543     usbDevice[reader_index].dev->filename);
544 rousseau 269
545 rousseau 1807 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 rousseau 1791 /* one slot closed */
553     (*usbDevice[reader_index].nb_opened_slots)--;
554 rousseau 1446
555 rousseau 1791 /* 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 rousseau 892
560 rousseau 1791 /* 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 rousseau 269 /* mark the resource unused */
570 rousseau 1106 usbDevice[reader_index].handle = NULL;
571     usbDevice[reader_index].dev = NULL;
572 rousseau 1327 usbDevice[reader_index].interface = 0;
573 rousseau 269
574     return STATUS_SUCCESS;
575     } /* CloseUSB */
576    
577    
578 rousseau 301 /*****************************************************************************
579     *
580 rousseau 406 * get_ccid_descriptor
581 rousseau 301 *
582     ****************************************************************************/
583 rousseau 1106 _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
584 rousseau 269 {
585 rousseau 1106 return &usbDevice[reader_index].ccid;
586 rousseau 406 } /* get_ccid_descriptor */
587 rousseau 269
588    
589 rousseau 301 /*****************************************************************************
590     *
591     * get_desc
592     *
593     ****************************************************************************/
594 rousseau 1281 int get_desc(int lun, usb_dev_handle **handle, struct
595 rousseau 269 usb_device **dev)
596     {
597 rousseau 1281 int reader_index;
598 rousseau 269
599 rousseau 1281 if (-1 == (reader_index = LunToReaderIndex(lun)))
600     return FALSE;
601 rousseau 269
602 rousseau 1281 *handle = usbDevice[reader_index].handle;
603     *dev = usbDevice[reader_index].dev;
604    
605     return TRUE;
606 rousseau 269 } /* get_desc */
607    
608 rousseau 649
609 rousseau 301 /*****************************************************************************
610     *
611     * get_end_points
612     *
613     ****************************************************************************/
614 rousseau 878 static int get_end_points(struct usb_device *dev, _usbDevice *usb_device)
615 rousseau 269 {
616     int i;
617     int bEndpointAddress;
618 rousseau 650 struct usb_interface *usb_interface = get_ccid_usb_interface(dev);
619    
620 rousseau 269 /*
621     * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
622     */
623     for (i=0; i<3; i++)
624     {
625 rousseau 650 if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)
626 rousseau 269 continue;
627    
628 rousseau 650 bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;
629 rousseau 269
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 rousseau 650
641     /*****************************************************************************
642     *
643     * get_ccid_usb_interface
644     *
645     ****************************************************************************/
646 rousseau 2014 /*@null@*/ EXTERNAL struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)
647 rousseau 650 {
648     struct usb_interface *usb_interface = NULL;
649 rousseau 1818 int i;
650 rousseau 650
651     /* if multiple interfaces use the first one with CCID class type */
652 rousseau 1818 for (i=0; i<dev->config->bNumInterfaces; i++)
653 rousseau 650 {
654 rousseau 1818 /* CCID Class? */
655     if (dev->config->interface[i].altsetting->bInterfaceClass == 0xb
656 rousseau 738 #ifdef ALLOW_PROPRIETARY_CLASS
657 rousseau 1818 || dev->config->interface[i].altsetting->bInterfaceClass == 0xff
658 rousseau 738 #endif
659 rousseau 1818 )
660     {
661     usb_interface = &dev->config->interface[i];
662     break;
663 rousseau 650 }
664     }
665    
666 rousseau 1256 #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 rousseau 650 return usb_interface;
688     } /* get_ccid_usb_interface */
689    
690 rousseau 1287
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 rousseau 1446 /*****************************************************************************
733     *
734     * get_data_rates
735     *
736     ****************************************************************************/
737 rousseau 1459 static unsigned int *get_data_rates(unsigned int reader_index)
738 rousseau 1446 {
739 rousseau 1608 int n, i, len;
740 rousseau 1446 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 rousseau 1467 usbDevice[reader_index].interface, /* interface */
749 rousseau 1460 (char *)buffer,
750 rousseau 1446 sizeof(buffer),
751 rousseau 1453 usbDevice[reader_index].ccid.readTimeout * 1000);
752 rousseau 1446
753 rousseau 1486 /* we got an error? */
754     if (n <= 0)
755 rousseau 1446 {
756 rousseau 1486 DEBUG_INFO2("IFD does not support GET_DATA_RATES request: %s",
757     strerror(errno));
758     return NULL;
759     }
760 rousseau 1476
761 rousseau 1486 /* we got a strange value */
762     if (n % 4)
763     {
764     DEBUG_INFO2("Wrong GET DATA RATES size: %d", n);
765     return NULL;
766 rousseau 1446 }
767    
768     /* allocate the buffer (including the end marker) */
769     n /= sizeof(int);
770 rousseau 1608
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 rousseau 1641 if ((n != len) && len)
775 rousseau 1608 {
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 rousseau 1446 int_array = calloc(n+1, sizeof(int));
784 rousseau 1475 if (NULL == int_array)
785 rousseau 1446 {
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