/[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 3356 - (hide annotations) (download)
Sat Mar 21 14:07:54 2009 UTC (4 years, 2 months ago) by rousseau
File MIME type: text/plain
File size: 27692 byte(s)
add support of PIN_PROPERTIES_STRUCTURE structure and
FEATURE_IFD_PIN_PROPERTIES

Thanks to Martin Paljak for the patch
1 rousseau 269 /*
2     ccid_usb.c: USB access routines using the libusb library
3 rousseau 3356 Copyright (C) 2003-2009 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 2974 You should have received a copy of the GNU Lesser General Public License
16     along with this library; if not, write to the Free Software Foundation,
17     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 rousseau 269 */
19    
20     /*
21     * $Id$
22     */
23    
24     #define __CCID_USB__
25    
26     #include <stdio.h>
27 rousseau 2152 #include <string.h>
28 rousseau 269 #include <errno.h>
29 rousseau 1052 # ifdef S_SPLINT_S
30     # include <sys/types.h>
31     # endif
32 rousseau 269 #include <usb.h>
33 rousseau 2871 #include <ifdhandler.h>
34 rousseau 269
35 rousseau 2014 #include "misc.h"
36 rousseau 878 #include "ccid.h"
37 rousseau 269 #include "config.h"
38     #include "debug.h"
39 rousseau 878 #include "defs.h"
40 rousseau 269 #include "utils.h"
41     #include "parser.h"
42 rousseau 878 #include "ccid_ifdhandler.h"
43 rousseau 269
44    
45 rousseau 570 /* write timeout
46     * we don't have to wait a long time since the card was doing nothing */
47     #define USB_WRITE_TIMEOUT (5 * 1000) /* 5 seconds timeout */
48    
49 rousseau 762 /*
50     * Proprietary USB Class (0xFF) are (or are not) accepted
51     * A proprietary class is used for devices released before the final CCID
52     * specifications were ready.
53     * We should not have problems with non CCID devices becasue the
54     * Manufacturer and Product ID are also used to identify the device */
55     #define ALLOW_PROPRIETARY_CLASS
56 rousseau 570
57 rousseau 269 #define BUS_DEVICE_STRSIZE 32
58    
59     typedef struct
60     {
61     usb_dev_handle *handle;
62 rousseau 2294 char *dirname;
63     char *filename;
64 rousseau 1327 int interface;
65 rousseau 269
66     /*
67     * Endpoints
68     */
69     int bulk_in;
70     int bulk_out;
71 rousseau 2772 int interrupt;
72 rousseau 406
73 rousseau 1791 /* Number of slots using the same device */
74     int real_nb_opened_slots;
75     int *nb_opened_slots;
76    
77 rousseau 406 /*
78     * CCID infos common to USB and serial
79     */
80     _ccid_descriptor ccid;
81    
82 rousseau 269 } _usbDevice;
83    
84 rousseau 406 /* The _usbDevice structure must be defined before including ccid_usb.h */
85 rousseau 269 #include "ccid_usb.h"
86    
87 rousseau 3348 static int get_end_points(struct usb_device *dev, _usbDevice *usbdevice, int num);
88 rousseau 1287 int ccid_check_firmware(struct usb_device *dev);
89 rousseau 2293 static unsigned int *get_data_rates(unsigned int reader_index,
90 rousseau 3348 struct usb_device *dev, int num);
91 rousseau 878
92 rousseau 892 /* ne need to initialize to 0 since it is static */
93 rousseau 1077 static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];
94 rousseau 269
95     #define PCSCLITE_MANUKEY_NAME "ifdVendorID"
96     #define PCSCLITE_PRODKEY_NAME "ifdProductID"
97     #define PCSCLITE_NAMEKEY_NAME "ifdFriendlyName"
98    
99 rousseau 1287 struct _bogus_firmware
100     {
101     int vendor; /* idVendor */
102     int product; /* idProduct */
103     int firmware; /* bcdDevice: previous firmwares have bugs */
104     };
105 rousseau 649
106 rousseau 1287 static struct _bogus_firmware Bogus_firmwares[] = {
107 rousseau 1312 { 0x04e6, 0xe001, 0x0516 }, /* SCR 331 */
108     { 0x04e6, 0x5111, 0x0620 }, /* SCR 331-DI */
109 rousseau 1287 { 0x04e6, 0x5115, 0x0514 }, /* SCR 335 */
110 rousseau 2048 { 0x04e6, 0xe003, 0x0510 }, /* SPR 532 */
111 rousseau 1325 { 0x0D46, 0x3001, 0x0037 }, /* KAAN Base */
112     { 0x0D46, 0x3002, 0x0037 }, /* KAAN Advanced */
113 rousseau 1875 { 0x09C3, 0x0008, 0x0203 }, /* ActivCard V2 */
114 rousseau 2002 { 0x0DC3, 0x1004, 0x0502 }, /* ASE IIIe USBv2 */
115     { 0x0DC3, 0x1102, 0x0607 }, /* ASE IIIe KB USB */
116 rousseau 2154 { 0x058F, 0x9520, 0x0102 }, /* Alcor AU9520-G */
117 rousseau 2691
118     /* the firmware version is not correct since I do not have received a
119     * working reader yet */
120     #ifndef O2MICRO_OZ776_PATCH
121     { 0x0b97, 0x7762, 0x0111 }, /* Oz776S */
122     #endif
123 rousseau 1287 };
124    
125 rousseau 1808 /* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
126     unsigned int SerialCustomDataRates[] = { GEMPLUS_CUSTOM_DATA_RATES, 0 };
127 rousseau 1287
128 rousseau 1808
129 rousseau 269 /*****************************************************************************
130     *
131     * OpenUSB
132     *
133     ****************************************************************************/
134 rousseau 1106 status_t OpenUSB(unsigned int reader_index, /*@unused@*/ int Channel)
135 rousseau 269 {
136 rousseau 1106 return OpenUSBByName(reader_index, NULL);
137 rousseau 649 } /* OpenUSB */
138    
139    
140     /*****************************************************************************
141     *
142     * OpenUSBByName
143     *
144     ****************************************************************************/
145 rousseau 1106 status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
146 rousseau 649 {
147 rousseau 269 static struct usb_bus *busses = NULL;
148     int alias = 0;
149     struct usb_bus *bus;
150     struct usb_dev_handle *dev_handle;
151     char keyValue[TOKEN_MAX_VALUE_SIZE];
152 rousseau 1569 unsigned int vendorID, productID;
153 rousseau 301 char infofile[FILENAME_MAX];
154 rousseau 3310 #ifndef __APPLE__
155 rousseau 892 unsigned int device_vendor, device_product;
156 rousseau 3310 #endif
157 rousseau 781 char *dirname = NULL, *filename = NULL;
158 rousseau 3350 char *serial = NULL;
159     int interface_number = -1;
160 rousseau 1151 static int previous_reader_index = -1;
161 rousseau 269
162 rousseau 1106 DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);
163 rousseau 269
164 rousseau 2754 #ifndef __APPLE__
165 rousseau 662 /* device name specified */
166     if (device)
167     {
168 rousseau 781 /* format: usb:%04x/%04x, vendor, product */
169 rousseau 662 if (strncmp("usb:", device, 4) != 0)
170     {
171     DEBUG_CRITICAL2("device name does not start with \"usb:\": %s",
172     device);
173     return STATUS_UNSUCCESSFUL;
174     }
175    
176     if (sscanf(device, "usb:%x/%x", &device_vendor, &device_product) != 2)
177     {
178     DEBUG_CRITICAL2("device name can't be parsed: %s", device);
179     return STATUS_UNSUCCESSFUL;
180     }
181 rousseau 781
182     /* format usb:%04x/%04x:libusb:%s
183     * with %s set to %s:%s, dirname, filename */
184     if ((dirname = strstr(device, "libusb:")) != NULL)
185     {
186     /* dirname points to the first char after libusb: */
187     dirname += strlen("libusb:");
188    
189     /* search the : (separation) char */
190     filename = strchr(dirname, ':');
191    
192     if (filename)
193     {
194     /* end the dirname string */
195     *filename = '\0';
196    
197     /* filename points to the first char after : */
198     filename++;
199     }
200     else
201     {
202     /* parse failed */
203     dirname = NULL;
204    
205     DEBUG_CRITICAL2("can't parse using libusb scheme: %s", device);
206     }
207     }
208 rousseau 3350
209     /* format usb:%04x/%04x:libhal:%s
210     * with %s set to
211     * /org/freedesktop/Hal/devices/usb_device_VID_PID_SERIAL_ifX
212     * VID is VendorID
213     * PID is ProductID
214     * SERIAL is device serial number
215     * X is the interface number
216     */
217     if ((dirname = strstr(device, "libhal:")) != NULL)
218     {
219     char *p;
220    
221     #define HAL_HEADER "usb_device_"
222    
223     /* parse the hal string */
224     if (
225     /* search the last '/' char */
226     (p = strrchr(dirname, '/'))
227    
228     /* if the string starts with "usb_device_" we continue */
229     && (0 == strncmp(++p, HAL_HEADER, sizeof(HAL_HEADER)-1))
230     /* skip the HAL header */
231     && (p += sizeof(HAL_HEADER)-1)
232    
233     /* search the '_' before PID */
234     && (p = strchr(++p, '_'))
235    
236     /* search the '_' before SERIAL */
237     && (p = strchr(++p, '_'))
238     && (serial = p+1)
239    
240     /* search the '_' before ifX */
241     && (p = strchr(++p, '_'))
242     && (0 == strncmp(++p, "if", 2))
243     )
244     {
245     /* terminate the serial number C-string */
246     *(p-1) = '\0';
247    
248     /* convert the interface number */
249     interface_number = atoi(p+2);
250     }
251     else
252     DEBUG_CRITICAL2("can't parse using libhal scheme: %s", device);
253    
254     /* dirname was just a temporary variable */
255     dirname = NULL;
256     }
257 rousseau 662 }
258 rousseau 2754 #endif
259 rousseau 662
260 rousseau 269 if (busses == NULL)
261     usb_init();
262    
263 rousseau 3268 (void)usb_find_busses();
264     (void)usb_find_devices();
265 rousseau 269
266     busses = usb_get_busses();
267    
268     if (busses == NULL)
269     {
270     DEBUG_CRITICAL("No USB busses found");
271     return STATUS_UNSUCCESSFUL;
272     }
273    
274 rousseau 1106 /* is the reader_index already used? */
275     if (usbDevice[reader_index].handle != NULL)
276 rousseau 269 {
277 rousseau 1106 DEBUG_CRITICAL2("USB driver with index %X already in use",
278     reader_index);
279 rousseau 269 return STATUS_UNSUCCESSFUL;
280     }
281    
282 rousseau 301 /* Info.plist full patch filename */
283 rousseau 3268 (void)snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
284 rousseau 406 PCSCLITE_HP_DROPDIR, BUNDLE);
285 rousseau 301
286 rousseau 269 /* general driver info */
287 rousseau 301 if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))
288 rousseau 774 {
289 rousseau 1792 DEBUG_INFO2("Manufacturer: %s", keyValue);
290 rousseau 774 }
291 rousseau 269 else
292     {
293 rousseau 1792 DEBUG_INFO2("LTPBundleFindValueWithKey error. Can't find %s?",
294 rousseau 301 infofile);
295 rousseau 269 return STATUS_UNSUCCESSFUL;
296     }
297 rousseau 301 if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))
298 rousseau 774 {
299 rousseau 1792 DEBUG_INFO2("ProductString: %s", keyValue);
300 rousseau 774 }
301 rousseau 269 else
302     return STATUS_UNSUCCESSFUL;
303 rousseau 301 if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))
304 rousseau 774 {
305 rousseau 1792 DEBUG_INFO2("Copyright: %s", keyValue);
306 rousseau 774 }
307 rousseau 269 else
308     return STATUS_UNSUCCESSFUL;
309     vendorID = strlen(keyValue);
310 rousseau 2083 alias = 0x1C;
311 rousseau 269 for (; vendorID--;)
312     alias ^= keyValue[vendorID];
313    
314     /* for any supported reader */
315 rousseau 301 while (LTPBundleFindValueWithKey(infofile, PCSCLITE_MANUKEY_NAME, keyValue, alias) == 0)
316 rousseau 269 {
317 rousseau 1079 vendorID = strtoul(keyValue, NULL, 0);
318 rousseau 269
319 rousseau 301 if (LTPBundleFindValueWithKey(infofile, PCSCLITE_PRODKEY_NAME, keyValue, alias))
320 rousseau 269 goto end;
321 rousseau 1079 productID = strtoul(keyValue, NULL, 0);
322 rousseau 269
323 rousseau 301 if (LTPBundleFindValueWithKey(infofile, PCSCLITE_NAMEKEY_NAME, keyValue, alias))
324 rousseau 269 goto end;
325    
326 rousseau 662 /* go to next supported reader for next round */
327     alias++;
328    
329 rousseau 2754 #ifndef __APPLE__
330 rousseau 662 /* the device was specified but is not the one we are trying to find */
331     if (device
332     && (vendorID != device_vendor || productID != device_product))
333     continue;
334 rousseau 2754 #else
335     /* Leopard puts the friendlyname in the device argument */
336     if (device && strcmp(device, keyValue))
337     continue;
338     #endif
339 rousseau 662
340 rousseau 269 /* on any USB buses */
341     for (bus = busses; bus; bus = bus->next)
342     {
343     struct usb_device *dev;
344    
345     /* any device on this bus */
346     for (dev = bus->devices; dev; dev = dev->next)
347     {
348 rousseau 781 /* device defined by name? */
349     if (dirname && (strcmp(dirname, bus->dirname)
350     || strcmp(filename, dev->filename)))
351     continue;
352    
353 rousseau 269 if (dev->descriptor.idVendor == vendorID
354     && dev->descriptor.idProduct == productID)
355     {
356     int r, already_used;
357 rousseau 662 struct usb_interface *usb_interface = NULL;
358     int interface;
359 rousseau 3348 int num = 0;
360 rousseau 269
361     /* is it already opened? */
362     already_used = FALSE;
363 rousseau 649
364 rousseau 2295 DEBUG_COMM3("Checking device: %s/%s",
365     bus->dirname, dev->filename);
366 rousseau 1077 for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
367 rousseau 269 {
368 rousseau 2294 if (usbDevice[r].handle)
369 rousseau 269 {
370 rousseau 662 /* same busname, same filename */
371 rousseau 2294 if (strcmp(usbDevice[r].dirname, bus->dirname) == 0 && strcmp(usbDevice[r].filename, dev->filename) == 0)
372 rousseau 662 already_used = TRUE;
373 rousseau 269 }
374     }
375    
376 rousseau 662 /* this reader is already managed by us */
377     if (already_used)
378 rousseau 269 {
379 rousseau 1151 if ((previous_reader_index != -1)
380 rousseau 2294 && usbDevice[previous_reader_index].handle
381     && (strcmp(usbDevice[previous_reader_index].dirname, bus->dirname) == 0)
382     && (strcmp(usbDevice[previous_reader_index].filename, dev->filename) == 0)
383 rousseau 1151 && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)
384     {
385     /* we reuse the same device
386     * and the reader is multi-slot */
387     usbDevice[reader_index] = usbDevice[previous_reader_index];
388 rousseau 1808 /* the other slots do not have the same data rates */
389     if ((GEMCOREPOSPRO == usbDevice[reader_index].ccid.readerID)
390     || (GEMCORESIMPRO == usbDevice[reader_index].ccid.readerID))
391     {
392     usbDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates;
393     usbDevice[reader_index].ccid.dwMaxDataRate = 125000;
394     }
395    
396 rousseau 1791 *usbDevice[reader_index].nb_opened_slots += 1;
397 rousseau 1151 usbDevice[reader_index].ccid.bCurrentSlotIndex++;
398 rousseau 2871 usbDevice[reader_index].ccid.dwSlotStatus =
399     IFD_ICC_PRESENT;
400 rousseau 1151 DEBUG_INFO2("Opening slot: %d",
401     usbDevice[reader_index].ccid.bCurrentSlotIndex);
402     goto end;
403     }
404     else
405     {
406 rousseau 3350 /* if an interface number is given by HAL we
407     * continue with this device. */
408     if (-1 == interface_number)
409     {
410     DEBUG_INFO3("USB device %s/%s already in use."
411     " Checking next one.",
412     bus->dirname, dev->filename);
413     continue;
414     }
415 rousseau 1151 }
416 rousseau 662 }
417 rousseau 269
418 rousseau 662 DEBUG_COMM3("Trying to open USB bus/device: %s/%s",
419     bus->dirname, dev->filename);
420 rousseau 269
421 rousseau 662 dev_handle = usb_open(dev);
422     if (dev_handle == NULL)
423     {
424     DEBUG_CRITICAL4("Can't usb_open(%s/%s): %s",
425     bus->dirname, dev->filename, strerror(errno));
426 rousseau 650
427 rousseau 662 continue;
428     }
429 rousseau 579
430 rousseau 662 /* now we found a free reader and we try to use it */
431     if (dev->config == NULL)
432     {
433 rousseau 3268 (void)usb_close(dev_handle);
434 rousseau 662 DEBUG_CRITICAL3("No dev->config found for %s/%s",
435     bus->dirname, dev->filename);
436     return STATUS_UNSUCCESSFUL;
437     }
438 rousseau 269
439 rousseau 3350 again:
440 rousseau 3348 usb_interface = get_ccid_usb_interface(dev, &num);
441 rousseau 662 if (usb_interface == NULL)
442     {
443 rousseau 3268 (void)usb_close(dev_handle);
444 rousseau 3350 if (0 == num)
445     DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",
446     bus->dirname, dev->filename);
447 rousseau 662 return STATUS_UNSUCCESSFUL;
448 rousseau 2152 }
449 rousseau 269
450 rousseau 662 if (usb_interface->altsetting->extralen != 54)
451     {
452 rousseau 3268 (void)usb_close(dev_handle);
453 rousseau 662 DEBUG_CRITICAL4("Extra field for %s/%s has a wrong length: %d", bus->dirname, dev->filename, usb_interface->altsetting->extralen);
454     return STATUS_UNSUCCESSFUL;
455 rousseau 269 }
456 rousseau 662
457     interface = usb_interface->altsetting->bInterfaceNumber;
458 rousseau 3350 if (interface_number >= 0 && interface != interface_number)
459     {
460     /* an interface was specified and it is not the
461     * current one */
462     DEBUG_INFO3("Wrong interface for USB device %s/%s."
463     " Checking next one.", bus->dirname, dev->filename);
464    
465     /* check for another CCID interface on the same device */
466     num++;
467    
468     goto again;
469     }
470    
471 rousseau 662 if (usb_claim_interface(dev_handle, interface) < 0)
472 rousseau 269 {
473 rousseau 3268 (void)usb_close(dev_handle);
474 rousseau 662 DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",
475     bus->dirname, dev->filename, strerror(errno));
476     return STATUS_UNSUCCESSFUL;
477 rousseau 269 }
478 rousseau 662
479     DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",
480     dev->descriptor.idVendor,
481     dev->descriptor.idProduct, keyValue);
482     DEBUG_INFO3("Using USB bus/device: %s/%s",
483     bus->dirname, dev->filename);
484    
485 rousseau 1287 /* check for firmware bugs */
486     if (ccid_check_firmware(dev))
487 rousseau 1585 {
488 rousseau 3268 (void)usb_close(dev_handle);
489 rousseau 1287 return STATUS_UNSUCCESSFUL;
490 rousseau 1585 }
491 rousseau 1287
492 rousseau 662 /* Get Endpoints values*/
493 rousseau 3348 (void)get_end_points(dev, &usbDevice[reader_index], num);
494 rousseau 662
495     /* store device information */
496 rousseau 1106 usbDevice[reader_index].handle = dev_handle;
497 rousseau 2294 usbDevice[reader_index].dirname = strdup(bus->dirname);
498     usbDevice[reader_index].filename = strdup(dev->filename);
499 rousseau 1327 usbDevice[reader_index].interface = interface;
500 rousseau 1791 usbDevice[reader_index].real_nb_opened_slots = 1;
501     usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
502 rousseau 662
503     /* CCID common informations */
504 rousseau 1149 usbDevice[reader_index].ccid.real_bSeq = 0;
505     usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq;
506 rousseau 1106 usbDevice[reader_index].ccid.readerID =
507 rousseau 662 (dev->descriptor.idVendor << 16) +
508     dev->descriptor.idProduct;
509 rousseau 1106 usbDevice[reader_index].ccid.dwFeatures = dw2i(usb_interface->altsetting->extra, 40);
510 rousseau 3356 usbDevice[reader_index].ccid.wLcdLayout =
511     (usb_interface->altsetting->extra[51] << 8) +
512     usb_interface->altsetting->extra[50];
513 rousseau 1106 usbDevice[reader_index].ccid.bPINSupport = usb_interface->altsetting->extra[52];
514     usbDevice[reader_index].ccid.dwMaxCCIDMessageLength = dw2i(usb_interface->altsetting->extra, 44);
515     usbDevice[reader_index].ccid.dwMaxIFSD = dw2i(usb_interface->altsetting->extra, 28);
516     usbDevice[reader_index].ccid.dwDefaultClock = dw2i(usb_interface->altsetting->extra, 10);
517 rousseau 1485 usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);
518 rousseau 1106 usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];
519     usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
520 rousseau 1453 usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
521 rousseau 3348 usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index, dev, num);
522 rousseau 2470 usbDevice[reader_index].ccid.bInterfaceProtocol = usb_interface->altsetting->bInterfaceProtocol;
523 rousseau 2771 usbDevice[reader_index].ccid.bNumEndpoints = usb_interface->altsetting->bNumEndpoints;
524 rousseau 2871 usbDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT;
525 rousseau 662 goto end;
526 rousseau 269 }
527     }
528     }
529     }
530     end:
531 rousseau 1106 if (usbDevice[reader_index].handle == NULL)
532 rousseau 269 return STATUS_UNSUCCESSFUL;
533    
534 rousseau 1151 /* memorise the current reader_index so we can detect
535     * a new OpenUSBByName on a multi slot reader */
536     previous_reader_index = reader_index;
537    
538 rousseau 269 return STATUS_SUCCESS;
539 rousseau 649 } /* OpenUSBByName */
540 rousseau 269
541    
542     /*****************************************************************************
543     *
544     * WriteUSB
545     *
546     ****************************************************************************/
547 rousseau 1106 status_t WriteUSB(unsigned int reader_index, unsigned int length,
548     unsigned char *buffer)
549 rousseau 269 {
550     int rv;
551     char debug_header[] = "-> 121234 ";
552    
553 rousseau 3269 (void)snprintf(debug_header, sizeof(debug_header), "-> %06X ",
554     (int)reader_index);
555 rousseau 269
556     DEBUG_XXD(debug_header, buffer, length);
557    
558 rousseau 1106 rv = usb_bulk_write(usbDevice[reader_index].handle,
559     usbDevice[reader_index].bulk_out, (char *)buffer, length,
560     USB_WRITE_TIMEOUT);
561 rousseau 269
562     if (rv < 0)
563     {
564 rousseau 2294 DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",
565     usbDevice[reader_index].dirname, usbDevice[reader_index].filename,
566     strerror(errno));
567 rousseau 1547
568 rousseau 2206 if (ENODEV == errno)
569     return STATUS_NO_SUCH_DEVICE;
570    
571 rousseau 269 return STATUS_UNSUCCESSFUL;
572     }
573    
574     return STATUS_SUCCESS;
575     } /* WriteUSB */
576    
577    
578     /*****************************************************************************
579     *
580     * ReadUSB
581     *
582     ****************************************************************************/
583 rousseau 1106 status_t ReadUSB(unsigned int reader_index, unsigned int * length,
584     unsigned char *buffer)
585 rousseau 269 {
586     int rv;
587     char debug_header[] = "<- 121234 ";
588 rousseau 2083 _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
589 rousseau 2763 int duplicate_frame = 0;
590 rousseau 269
591 rousseau 2083 read_again:
592 rousseau 3269 (void)snprintf(debug_header, sizeof(debug_header), "<- %06X ",
593     (int)reader_index);
594 rousseau 269
595 rousseau 1106 rv = usb_bulk_read(usbDevice[reader_index].handle,
596     usbDevice[reader_index].bulk_in, (char *)buffer, *length,
597 rousseau 1453 usbDevice[reader_index].ccid.readTimeout * 1000);
598 rousseau 269
599     if (rv < 0)
600     {
601 rousseau 895 *length = 0;
602 rousseau 2294 DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",
603     usbDevice[reader_index].dirname, usbDevice[reader_index].filename,
604     strerror(errno));
605 rousseau 2119
606 rousseau 2206 if (ENODEV == errno)
607     return STATUS_NO_SUCH_DEVICE;
608    
609 rousseau 269 return STATUS_UNSUCCESSFUL;
610     }
611    
612 rousseau 895 *length = rv;
613    
614 rousseau 269 DEBUG_XXD(debug_header, buffer, *length);
615    
616 rousseau 2083 #define BSEQ_OFFSET 6
617 rousseau 2097 if ((*length >= BSEQ_OFFSET)
618     && (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1))
619 rousseau 2083 {
620 rousseau 2763 duplicate_frame++;
621     if (duplicate_frame > 10)
622     {
623     DEBUG_CRITICAL("Too many duplicate frame detected");
624     return STATUS_UNSUCCESSFUL;
625     }
626 rousseau 2083 DEBUG_INFO("Duplicate frame detected");
627     goto read_again;
628     }
629    
630 rousseau 269 return STATUS_SUCCESS;
631     } /* ReadUSB */
632    
633    
634     /*****************************************************************************
635     *
636     * CloseUSB
637     *
638     ****************************************************************************/
639 rousseau 1106 status_t CloseUSB(unsigned int reader_index)
640 rousseau 269 {
641     /* device not opened */
642 rousseau 2294 if (usbDevice[reader_index].handle == NULL)
643 rousseau 269 return STATUS_UNSUCCESSFUL;
644    
645 rousseau 662 DEBUG_COMM3("Closing USB device: %s/%s",
646 rousseau 2294 usbDevice[reader_index].dirname,
647     usbDevice[reader_index].filename);
648 rousseau 269
649 rousseau 1807 if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates
650     && (usbDevice[reader_index].ccid.bCurrentSlotIndex == 0))
651     {
652     free(usbDevice[reader_index].ccid.arrayOfSupportedDataRates);
653     usbDevice[reader_index].ccid.arrayOfSupportedDataRates = NULL;
654     }
655    
656 rousseau 1791 /* one slot closed */
657     (*usbDevice[reader_index].nb_opened_slots)--;
658 rousseau 1446
659 rousseau 1791 /* release the allocated ressources for the last slot only */
660     if (0 == *usbDevice[reader_index].nb_opened_slots)
661     {
662     DEBUG_COMM("Last slot closed. Release resources");
663 rousseau 892
664 rousseau 1791 /* reset so that bSeq starts at 0 again */
665     if (DriverOptions & DRIVER_OPTION_RESET_ON_CLOSE)
666 rousseau 3268 (void)usb_reset(usbDevice[reader_index].handle);
667 rousseau 1791
668 rousseau 3268 (void)usb_release_interface(usbDevice[reader_index].handle,
669 rousseau 1791 usbDevice[reader_index].interface);
670 rousseau 3268 (void)usb_close(usbDevice[reader_index].handle);
671 rousseau 2296
672     free(usbDevice[reader_index].dirname);
673     free(usbDevice[reader_index].filename);
674 rousseau 1791 }
675    
676 rousseau 269 /* mark the resource unused */
677 rousseau 1106 usbDevice[reader_index].handle = NULL;
678 rousseau 2294 usbDevice[reader_index].dirname = NULL;
679     usbDevice[reader_index].filename = NULL;
680 rousseau 1327 usbDevice[reader_index].interface = 0;
681 rousseau 269
682     return STATUS_SUCCESS;
683     } /* CloseUSB */
684    
685    
686 rousseau 301 /*****************************************************************************
687     *
688 rousseau 406 * get_ccid_descriptor
689 rousseau 301 *
690     ****************************************************************************/
691 rousseau 1106 _ccid_descriptor *get_ccid_descriptor(unsigned int reader_index)
692 rousseau 269 {
693 rousseau 1106 return &usbDevice[reader_index].ccid;
694 rousseau 406 } /* get_ccid_descriptor */
695 rousseau 269
696    
697 rousseau 301 /*****************************************************************************
698     *
699     * get_end_points
700     *
701     ****************************************************************************/
702 rousseau 3348 static int get_end_points(struct usb_device *dev, _usbDevice *usbdevice,
703     int num)
704 rousseau 269 {
705     int i;
706     int bEndpointAddress;
707 rousseau 3348 struct usb_interface *usb_interface = get_ccid_usb_interface(dev, &num);
708 rousseau 2152
709 rousseau 269 /*
710     * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
711     */
712 rousseau 2393 for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
713 rousseau 269 {
714 rousseau 2772 /* interrupt end point (if available) */
715     if (usb_interface->altsetting->endpoint[i].bmAttributes == USB_ENDPOINT_TYPE_INTERRUPT)
716     {
717     usbdevice->interrupt = usb_interface->altsetting->endpoint[i].bEndpointAddress;
718     continue;
719     }
720    
721 rousseau 650 if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)
722 rousseau 269 continue;
723    
724 rousseau 650 bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;
725 rousseau 269
726     if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
727 rousseau 2426 usbdevice->bulk_in = bEndpointAddress;
728 rousseau 269
729     if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)
730 rousseau 2426 usbdevice->bulk_out = bEndpointAddress;
731 rousseau 269 }
732    
733     return 0;
734     } /* get_end_points */
735    
736 rousseau 650
737     /*****************************************************************************
738     *
739     * get_ccid_usb_interface
740     *
741     ****************************************************************************/
742 rousseau 3348 /*@null@*/ EXTERNAL struct usb_interface * get_ccid_usb_interface(
743     struct usb_device *dev, int *num)
744 rousseau 650 {
745 rousseau 2152 struct usb_interface *usb_interface = NULL;
746 rousseau 1818 int i;
747 rousseau 2602 #ifdef O2MICRO_OZ776_PATCH
748     int readerID;
749     #endif
750 rousseau 650
751     /* if multiple interfaces use the first one with CCID class type */
752 rousseau 3348 for (i = *num; dev->config && i<dev->config->bNumInterfaces; i++)
753 rousseau 650 {
754 rousseau 1818 /* CCID Class? */
755     if (dev->config->interface[i].altsetting->bInterfaceClass == 0xb
756 rousseau 738 #ifdef ALLOW_PROPRIETARY_CLASS
757 rousseau 1818 || dev->config->interface[i].altsetting->bInterfaceClass == 0xff
758 rousseau 738 #endif
759 rousseau 1818 )
760     {
761     usb_interface = &dev->config->interface[i];
762 rousseau 3348 /* store the interface number for further reference */
763     *num = i;
764 rousseau 1818 break;
765 rousseau 650 }
766     }
767    
768 rousseau 1256 #ifdef O2MICRO_OZ776_PATCH
769 rousseau 2602 readerID = (dev->descriptor.idVendor << 16) + dev->descriptor.idProduct;
770 rousseau 1256 if (usb_interface != NULL
771 rousseau 2685 && ((OZ776 == readerID) || (OZ776_7772 == readerID)
772 rousseau 2793 || (REINER_SCT == readerID) || (BLUDRIVEII_CCID == readerID))
773 rousseau 1256 && (0 == usb_interface->altsetting->extralen)) /* this is the bug */
774     {
775 rousseau 3348 int j;
776     for (j=0; j<usb_interface->altsetting->bNumEndpoints; j++)
777 rousseau 1256 {
778     /* find the extra[] array */
779 rousseau 3348 if (54 == usb_interface->altsetting->endpoint[j].extralen)
780 rousseau 1256 {
781     /* get the extra[] from the endpoint */
782     usb_interface->altsetting->extralen = 54;
783     usb_interface->altsetting->extra =
784 rousseau 3348 usb_interface->altsetting->endpoint[j].extra;
785 rousseau 2510 /* avoid double free on close */
786 rousseau 3348 usb_interface->altsetting->endpoint[j].extra = NULL;
787     usb_interface->altsetting->endpoint[j].extralen = 0;
788 rousseau 1256 break;
789     }
790     }
791     }
792     #endif
793    
794 rousseau 650 return usb_interface;
795     } /* get_ccid_usb_interface */
796    
797 rousseau 1287
798     /*****************************************************************************
799     *
800     * ccid_check_firmware
801     *
802     ****************************************************************************/
803     int ccid_check_firmware(struct usb_device *dev)
804     {
805 rousseau 2859 unsigned int i;
806 rousseau 1287
807     for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)
808     {
809     if (dev->descriptor.idVendor != Bogus_firmwares[i].vendor)
810     continue;
811    
812     if (dev->descriptor.idProduct != Bogus_firmwares[i].product)
813     continue;
814    
815     /* firmware too old and buggy */
816     if (dev->descriptor.bcdDevice < Bogus_firmwares[i].firmware)
817     {
818     if (DriverOptions & DRIVER_OPTION_USE_BOGUS_FIRMWARE)
819     {
820     DEBUG_INFO3("Firmware (%X.%02X) is bogus! but you choosed to use it",
821     dev->descriptor.bcdDevice >> 8,
822     dev->descriptor.bcdDevice & 0xFF);
823     return FALSE;
824     }
825     else
826     {
827     DEBUG_CRITICAL3("Firmware (%X.%02X) is bogus! Upgrade the reader firmware or get a new reader.",
828     dev->descriptor.bcdDevice >> 8,
829     dev->descriptor.bcdDevice & 0xFF);
830     return TRUE;
831     }
832     }
833     }
834    
835     /* by default the firmware is not bogus */
836     return FALSE;
837     } /* ccid_check_firmware */
838    
839 rousseau 2774
840 rousseau 1446 /*****************************************************************************
841     *
842     * get_data_rates
843     *
844     ****************************************************************************/
845 rousseau 2293 static unsigned int *get_data_rates(unsigned int reader_index,
846 rousseau 3348 struct usb_device *dev, int num)
847 rousseau 1446 {
848 rousseau 1608 int n, i, len;
849 rousseau 1446 unsigned char buffer[256*sizeof(int)]; /* maximum is 256 records */
850     unsigned int *int_array;
851    
852     /* See CCID 3.7.3 page 25 */
853 rousseau 2424 n = ControlUSB(reader_index,
854 rousseau 1446 0xA1, /* request type */
855     0x03, /* GET_DATA_RATES */
856     0x00, /* value */
857 rousseau 2424 buffer, sizeof(buffer));
858 rousseau 1446
859 rousseau 1486 /* we got an error? */
860     if (n <= 0)
861 rousseau 1446 {
862 rousseau 1486 DEBUG_INFO2("IFD does not support GET_DATA_RATES request: %s",
863     strerror(errno));
864     return NULL;
865     }
866 rousseau 1476
867 rousseau 1486 /* we got a strange value */
868     if (n % 4)
869     {
870     DEBUG_INFO2("Wrong GET DATA RATES size: %d", n);
871     return NULL;
872 rousseau 1446 }
873    
874     /* allocate the buffer (including the end marker) */
875     n /= sizeof(int);
876 rousseau 1608
877     /* we do not get the expected number of data rates */
878 rousseau 3348 len = get_ccid_usb_interface(dev, &num)->altsetting->extra[27]; /* bNumDataRatesSupported */
879 rousseau 1641 if ((n != len) && len)
880 rousseau 1608 {
881     DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);
882    
883     /* we got more data than expected */
884     if (n > len)
885     n = len;
886     }
887    
888 rousseau 1446 int_array = calloc(n+1, sizeof(int));
889 rousseau 1475 if (NULL == int_array)
890 rousseau 1446 {
891     DEBUG_CRITICAL("Memory allocation failed");
892     return NULL;
893     }
894    
895     /* convert in correct endianess */
896     for (i=0; i<n; i++)
897     {
898     int_array[i] = dw2i(buffer, i*4);
899     DEBUG_INFO2("declared: %d bps", int_array[i]);
900     }
901    
902     /* end of array marker */
903     int_array[i] = 0;
904    
905     return int_array;
906 rousseau 2774 } /* get_data_rates */
907 rousseau 1446
908 rousseau 2774
909     /*****************************************************************************
910     *
911     * ControlUSB
912     *
913     ****************************************************************************/
914 rousseau 2423 int ControlUSB(int reader_index, int requesttype, int request, int value,
915     unsigned char *bytes, unsigned int size)
916     {
917 rousseau 2469 int ret;
918    
919     DEBUG_COMM2("request: 0x%02X", request);
920    
921     if (0 == (requesttype & 0x80))
922     DEBUG_XXD("send: ", bytes, size);
923    
924     ret = usb_control_msg(usbDevice[reader_index].handle, requesttype,
925 rousseau 2425 request, value, usbDevice[reader_index].interface, (char *)bytes, size,
926 rousseau 2423 usbDevice[reader_index].ccid.readTimeout * 1000);
927 rousseau 2469
928     if (requesttype & 0x80)
929     DEBUG_XXD("receive: ", bytes, ret);
930    
931     return ret;
932 rousseau 2774 } /* ControlUSB */
933 rousseau 2423
934 rousseau 2776 /*****************************************************************************
935     *
936     * InterruptRead
937     *
938     *
939     ****************************************************************************/
940     int InterruptRead(int reader_index)
941     {
942     int ret;
943     char buffer[8];
944 rousseau 3026 int timeout = 2*1000; /* 2 seconds */
945 rousseau 2776
946     DEBUG_COMM("before");
947     ret = usb_interrupt_read(usbDevice[reader_index].handle,
948     usbDevice[reader_index].interrupt, buffer, sizeof(buffer), timeout);
949 rousseau 3027 DEBUG_COMM2("after %d", ret);
950 rousseau 2776
951     if (ret < 0)
952     {
953 rousseau 2802 /* if usb_interrupt_read() times out we get EILSEQ or EAGAIN */
954 rousseau 3106 if ((errno != EILSEQ) && (errno != EAGAIN) && (errno != ENODEV) && (errno != 0))
955 rousseau 3026 DEBUG_COMM4("usb_interrupt_read(%s/%s): %s",
956 rousseau 2776 usbDevice[reader_index].dirname,
957     usbDevice[reader_index].filename, strerror(errno));
958     }
959     else
960     DEBUG_XXD("NotifySlotChange: ", buffer, ret);
961    
962     return ret;
963     } /* InterruptRead */
964    

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5