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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5