/[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 1775 - (hide annotations) (download)
Tue Nov 29 14:33:22 2005 UTC (7 years, 5 months ago) by rousseau
File MIME type: text/plain
File size: 21443 byte(s)
OpenUSBByName(): do not (re)set the usbDevice[].ccid.pbSeq field since
we just copied the complete structure just before
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.bCurrentSlotIndex++;
312     DEBUG_INFO2("Opening slot: %d",
313     usbDevice[reader_index].ccid.bCurrentSlotIndex);
314     goto end;
315     }
316     else
317     {
318     DEBUG_INFO3("USB device %s/%s already in use."
319     " Checking next one.",
320     bus->dirname, dev->filename);
321     }
322 rousseau 301
323 rousseau 662 continue;
324     }
325 rousseau 269
326 rousseau 662 DEBUG_COMM3("Trying to open USB bus/device: %s/%s",
327     bus->dirname, dev->filename);
328 rousseau 269
329 rousseau 662 dev_handle = usb_open(dev);
330     if (dev_handle == NULL)
331     {
332     DEBUG_CRITICAL4("Can't usb_open(%s/%s): %s",
333     bus->dirname, dev->filename, strerror(errno));
334 rousseau 650
335 rousseau 662 continue;
336     }
337 rousseau 579
338 rousseau 662 /* now we found a free reader and we try to use it */
339     if (dev->config == NULL)
340     {
341 rousseau 1585 usb_close(dev_handle);
342 rousseau 662 DEBUG_CRITICAL3("No dev->config found for %s/%s",
343     bus->dirname, dev->filename);
344     return STATUS_UNSUCCESSFUL;
345     }
346 rousseau 269
347 rousseau 662 usb_interface = get_ccid_usb_interface(dev);
348     if (usb_interface == NULL)
349     {
350 rousseau 1585 usb_close(dev_handle);
351 rousseau 662 DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",
352     bus->dirname, dev->filename);
353     return STATUS_UNSUCCESSFUL;
354     }
355 rousseau 269
356 rousseau 662 if (usb_interface->altsetting->extralen != 54)
357     {
358 rousseau 1585 usb_close(dev_handle);
359 rousseau 662 DEBUG_CRITICAL4("Extra field for %s/%s has a wrong length: %d", bus->dirname, dev->filename, usb_interface->altsetting->extralen);
360     return STATUS_UNSUCCESSFUL;
361 rousseau 269 }
362 rousseau 662
363     interface = usb_interface->altsetting->bInterfaceNumber;
364     if (usb_claim_interface(dev_handle, interface) < 0)
365 rousseau 269 {
366 rousseau 1585 usb_close(dev_handle);
367 rousseau 662 DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",
368     bus->dirname, dev->filename, strerror(errno));
369     return STATUS_UNSUCCESSFUL;
370 rousseau 269 }
371 rousseau 662
372     DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",
373     dev->descriptor.idVendor,
374     dev->descriptor.idProduct, keyValue);
375     DEBUG_INFO3("Using USB bus/device: %s/%s",
376     bus->dirname, dev->filename);
377    
378 rousseau 1287 /* check for firmware bugs */
379     if (ccid_check_firmware(dev))
380 rousseau 1585 {
381     usb_close(dev_handle);
382 rousseau 1287 return STATUS_UNSUCCESSFUL;
383 rousseau 1585 }
384 rousseau 1287
385 rousseau 662 /* Get Endpoints values*/
386 rousseau 1106 get_end_points(dev, &usbDevice[reader_index]);
387 rousseau 662
388     /* store device information */
389 rousseau 1106 usbDevice[reader_index].handle = dev_handle;
390     usbDevice[reader_index].dev = dev;
391 rousseau 1327 usbDevice[reader_index].interface = interface;
392 rousseau 662
393     /* CCID common informations */
394 rousseau 1149 usbDevice[reader_index].ccid.real_bSeq = 0;
395     usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq;
396 rousseau 1106 usbDevice[reader_index].ccid.readerID =
397 rousseau 662 (dev->descriptor.idVendor << 16) +
398     dev->descriptor.idProduct;
399 rousseau 1106 usbDevice[reader_index].ccid.dwFeatures = dw2i(usb_interface->altsetting->extra, 40);
400     usbDevice[reader_index].ccid.bPINSupport = usb_interface->altsetting->extra[52];
401     usbDevice[reader_index].ccid.dwMaxCCIDMessageLength = dw2i(usb_interface->altsetting->extra, 44);
402     usbDevice[reader_index].ccid.dwMaxIFSD = dw2i(usb_interface->altsetting->extra, 28);
403     usbDevice[reader_index].ccid.dwDefaultClock = dw2i(usb_interface->altsetting->extra, 10);
404 rousseau 1485 usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);
405 rousseau 1106 usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];
406     usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
407 rousseau 1453 usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
408 rousseau 1446 usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index);
409 rousseau 662 goto end;
410 rousseau 269 }
411     }
412     }
413     }
414     end:
415 rousseau 1106 if (usbDevice[reader_index].handle == NULL)
416 rousseau 269 return STATUS_UNSUCCESSFUL;
417    
418 rousseau 1151 /* memorise the current reader_index so we can detect
419     * a new OpenUSBByName on a multi slot reader */
420     previous_reader_index = reader_index;
421    
422 rousseau 269 return STATUS_SUCCESS;
423 rousseau 649 } /* OpenUSBByName */
424 rousseau 269
425    
426     /*****************************************************************************
427     *
428     * WriteUSB
429     *
430     ****************************************************************************/
431 rousseau 1106 status_t WriteUSB(unsigned int reader_index, unsigned int length,
432     unsigned char *buffer)
433 rousseau 269 {
434     int rv;
435     char debug_header[] = "-> 121234 ";
436    
437 rousseau 1106 sprintf(debug_header, "-> %06X ", (int)reader_index);
438 rousseau 269
439     DEBUG_XXD(debug_header, buffer, length);
440    
441 rousseau 1106 rv = usb_bulk_write(usbDevice[reader_index].handle,
442     usbDevice[reader_index].bulk_out, (char *)buffer, length,
443     USB_WRITE_TIMEOUT);
444 rousseau 269
445     if (rv < 0)
446     {
447 rousseau 1547 if (usbDevice[reader_index].dev->bus)
448     {
449     DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",
450     usbDevice[reader_index].dev->bus->dirname,
451     usbDevice[reader_index].dev->filename, strerror(errno));
452     }
453     else
454     DEBUG_CRITICAL2("usb_bulk_write(no device): %s", strerror(errno));
455    
456 rousseau 269 return STATUS_UNSUCCESSFUL;
457     }
458    
459     return STATUS_SUCCESS;
460     } /* WriteUSB */
461    
462    
463     /*****************************************************************************
464     *
465     * ReadUSB
466     *
467     ****************************************************************************/
468 rousseau 1106 status_t ReadUSB(unsigned int reader_index, unsigned int * length,
469     unsigned char *buffer)
470 rousseau 269 {
471     int rv;
472     char debug_header[] = "<- 121234 ";
473    
474 rousseau 1106 sprintf(debug_header, "<- %06X ", (int)reader_index);
475 rousseau 269
476 rousseau 1106 rv = usb_bulk_read(usbDevice[reader_index].handle,
477     usbDevice[reader_index].bulk_in, (char *)buffer, *length,
478 rousseau 1453 usbDevice[reader_index].ccid.readTimeout * 1000);
479 rousseau 269
480     if (rv < 0)
481     {
482 rousseau 895 *length = 0;
483 rousseau 662 DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",
484 rousseau 1106 usbDevice[reader_index].dev->bus->dirname,
485     usbDevice[reader_index].dev->filename, strerror(errno));
486 rousseau 269 return STATUS_UNSUCCESSFUL;
487     }
488    
489 rousseau 895 *length = rv;
490    
491 rousseau 269 DEBUG_XXD(debug_header, buffer, *length);
492    
493     return STATUS_SUCCESS;
494     } /* ReadUSB */
495    
496    
497     /*****************************************************************************
498     *
499     * CloseUSB
500     *
501     ****************************************************************************/
502 rousseau 1106 status_t CloseUSB(unsigned int reader_index)
503 rousseau 269 {
504     /* device not opened */
505 rousseau 1106 if (usbDevice[reader_index].dev == NULL)
506 rousseau 269 return STATUS_UNSUCCESSFUL;
507    
508 rousseau 662 DEBUG_COMM3("Closing USB device: %s/%s",
509 rousseau 1106 usbDevice[reader_index].dev->bus->dirname,
510     usbDevice[reader_index].dev->filename);
511 rousseau 269
512 rousseau 1446 if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates)
513     free(usbDevice[reader_index].ccid.arrayOfSupportedDataRates);
514    
515 rousseau 892 /* reset so that bSeq starts at 0 again */
516 rousseau 1613 if (DriverOptions & DRIVER_OPTION_RESET_ON_CLOSE)
517     usb_reset(usbDevice[reader_index].handle);
518 rousseau 892
519 rousseau 1327 usb_release_interface(usbDevice[reader_index].handle,
520     usbDevice[reader_index].interface);
521 rousseau 1106 usb_close(usbDevice[reader_index].handle);
522 rousseau 269
523     /* mark the resource unused */
524 rousseau 1106 usbDevice[reader_index].handle = NULL;
525     usbDevice[reader_index].dev = NULL;
526 rousseau 1327 usbDevice[reader_index].interface = 0;
527 rousseau 269
528     return STATUS_SUCCESS;
529     } /* CloseUSB */
530    
531    
532 rousseau 301 /*****************************************************************************
533     *
534 rousseau 406 * get_ccid_descriptor
535 rousseau 301 *
536     ****************************************************************************/
537 rousseau 1106 _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
538 rousseau 269 {
539 rousseau 1106 return &usbDevice[reader_index].ccid;
540 rousseau 406 } /* get_ccid_descriptor */
541 rousseau 269
542    
543 rousseau 301 /*****************************************************************************
544     *
545     * get_desc
546     *
547     ****************************************************************************/
548 rousseau 1281 int get_desc(int lun, usb_dev_handle **handle, struct
549 rousseau 269 usb_device **dev)
550     {
551 rousseau 1281 int reader_index;
552 rousseau 269
553 rousseau 1281 if (-1 == (reader_index = LunToReaderIndex(lun)))
554     return FALSE;
555 rousseau 269
556 rousseau 1281 *handle = usbDevice[reader_index].handle;
557     *dev = usbDevice[reader_index].dev;
558    
559     return TRUE;
560 rousseau 269 } /* get_desc */
561    
562 rousseau 649
563 rousseau 301 /*****************************************************************************
564     *
565     * get_end_points
566     *
567     ****************************************************************************/
568 rousseau 878 static int get_end_points(struct usb_device *dev, _usbDevice *usb_device)
569 rousseau 269 {
570     int i;
571     int bEndpointAddress;
572 rousseau 650 struct usb_interface *usb_interface = get_ccid_usb_interface(dev);
573    
574 rousseau 269 /*
575     * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
576     */
577     for (i=0; i<3; i++)
578     {
579 rousseau 650 if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)
580 rousseau 269 continue;
581    
582 rousseau 650 bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;
583 rousseau 269
584     if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
585     usb_device->bulk_in = bEndpointAddress;
586    
587     if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)
588     usb_device->bulk_out = bEndpointAddress;
589     }
590    
591     return 0;
592     } /* get_end_points */
593    
594 rousseau 650
595     /*****************************************************************************
596     *
597     * get_ccid_usb_interface
598     *
599     ****************************************************************************/
600 rousseau 1054 /*@null@*/ struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)
601 rousseau 650 {
602     struct usb_interface *usb_interface = NULL;
603    
604     /* if multiple interfaces use the first one with CCID class type */
605     if (dev->config->bNumInterfaces > 1)
606     {
607     int ii;
608     for (ii=0; ii<dev->config->bNumInterfaces; ii++)
609     {
610 rousseau 738 /* CCID Class? */
611     if (dev->config->interface[ii].altsetting->bInterfaceClass == 0xb
612     #ifdef ALLOW_PROPRIETARY_CLASS
613     || dev->config->interface[ii].altsetting->bInterfaceClass == 0xff
614     #endif
615     )
616 rousseau 650 {
617     usb_interface = &dev->config->interface[ii];
618     break;
619     }
620     }
621     }
622     else
623 rousseau 1256 /* only one interface found */
624 rousseau 650 usb_interface = dev->config->interface;
625    
626 rousseau 1256 #ifdef O2MICRO_OZ776_PATCH
627     if (usb_interface != NULL
628     && (OZ776 == (dev->descriptor.idVendor << 16)
629     + dev->descriptor.idProduct)
630     && (0 == usb_interface->altsetting->extralen)) /* this is the bug */
631     {
632     int i;
633    
634     for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
635     {
636     /* find the extra[] array */
637     if (54 == usb_interface->altsetting->endpoint[i].extralen)
638     {
639     /* get the extra[] from the endpoint */
640     usb_interface->altsetting->extralen = 54;
641     usb_interface->altsetting->extra =
642     usb_interface->altsetting->endpoint[i].extra;
643     break;
644     }
645     }
646     }
647     #endif
648    
649 rousseau 650 return usb_interface;
650     } /* get_ccid_usb_interface */
651    
652 rousseau 1287
653     /*****************************************************************************
654     *
655     * ccid_check_firmware
656     *
657     ****************************************************************************/
658     int ccid_check_firmware(struct usb_device *dev)
659     {
660     int i;
661    
662     for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)
663     {
664     if (dev->descriptor.idVendor != Bogus_firmwares[i].vendor)
665     continue;
666    
667     if (dev->descriptor.idProduct != Bogus_firmwares[i].product)
668     continue;
669    
670     /* firmware too old and buggy */
671     if (dev->descriptor.bcdDevice < Bogus_firmwares[i].firmware)
672     {
673     if (DriverOptions & DRIVER_OPTION_USE_BOGUS_FIRMWARE)
674     {
675     DEBUG_INFO3("Firmware (%X.%02X) is bogus! but you choosed to use it",
676     dev->descriptor.bcdDevice >> 8,
677     dev->descriptor.bcdDevice & 0xFF);
678     return FALSE;
679     }
680     else
681     {
682     DEBUG_CRITICAL3("Firmware (%X.%02X) is bogus! Upgrade the reader firmware or get a new reader.",
683     dev->descriptor.bcdDevice >> 8,
684     dev->descriptor.bcdDevice & 0xFF);
685     return TRUE;
686     }
687     }
688     }
689    
690     /* by default the firmware is not bogus */
691     return FALSE;
692     } /* ccid_check_firmware */
693    
694 rousseau 1446 /*****************************************************************************
695     *
696     * get_data_rates
697     *
698     ****************************************************************************/
699 rousseau 1459 static unsigned int *get_data_rates(unsigned int reader_index)
700 rousseau 1446 {
701 rousseau 1608 int n, i, len;
702 rousseau 1446 unsigned char buffer[256*sizeof(int)]; /* maximum is 256 records */
703     unsigned int *int_array;
704    
705     /* See CCID 3.7.3 page 25 */
706     n = usb_control_msg(usbDevice[reader_index].handle,
707     0xA1, /* request type */
708     0x03, /* GET_DATA_RATES */
709     0x00, /* value */
710 rousseau 1467 usbDevice[reader_index].interface, /* interface */
711 rousseau 1460 (char *)buffer,
712 rousseau 1446 sizeof(buffer),
713 rousseau 1453 usbDevice[reader_index].ccid.readTimeout * 1000);
714 rousseau 1446
715 rousseau 1486 /* we got an error? */
716     if (n <= 0)
717 rousseau 1446 {
718 rousseau 1486 DEBUG_INFO2("IFD does not support GET_DATA_RATES request: %s",
719     strerror(errno));
720     return NULL;
721     }
722 rousseau 1476
723 rousseau 1486 /* we got a strange value */
724     if (n % 4)
725     {
726     DEBUG_INFO2("Wrong GET DATA RATES size: %d", n);
727     return NULL;
728 rousseau 1446 }
729    
730     /* allocate the buffer (including the end marker) */
731     n /= sizeof(int);
732 rousseau 1608
733     /* we do not get the expected number of data rates */
734     len = get_ccid_usb_interface(usbDevice[reader_index].dev)
735     ->altsetting->extra[27]; /* bNumDataRatesSupported */
736 rousseau 1641 if ((n != len) && len)
737 rousseau 1608 {
738     DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);
739    
740     /* we got more data than expected */
741     if (n > len)
742     n = len;
743     }
744    
745 rousseau 1446 int_array = calloc(n+1, sizeof(int));
746 rousseau 1475 if (NULL == int_array)
747 rousseau 1446 {
748     DEBUG_CRITICAL("Memory allocation failed");
749     return NULL;
750     }
751    
752     /* convert in correct endianess */
753     for (i=0; i<n; i++)
754     {
755     int_array[i] = dw2i(buffer, i*4);
756     DEBUG_INFO2("declared: %d bps", int_array[i]);
757     }
758    
759     /* end of array marker */
760     int_array[i] = 0;
761    
762     return int_array;
763     }
764    

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5