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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5