/[pcsclite]/trunk/Drivers/ccid/src/parse.c
ViewVC logotype

Contents of /trunk/Drivers/ccid/src/parse.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2429 - (hide annotations) (download)
Fri Feb 23 17:02:43 2007 UTC (6 years, 2 months ago) by rousseau
File MIME type: text/plain
File size: 11869 byte(s)
display the error message if usb_control_msg() fails
1 rousseau 269 /*
2     parse.c: parse CCID structure
3 rousseau 1160 Copyright (C) 2003-2004 Ludovic Rousseau
4 rousseau 269
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9    
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     GNU General Public License for more details.
14    
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18     */
19    
20     /*
21     * $Id$
22     */
23    
24     #include <stdio.h>
25 rousseau 2152 #include <string.h>
26 rousseau 1055 # ifdef S_SPLINT_S
27     # include <sys/types.h>
28     # endif
29 rousseau 269 #include <usb.h>
30 rousseau 1819 #include <errno.h>
31 rousseau 269
32 rousseau 877 #include "defs.h"
33 rousseau 405 #include "ccid.h"
34 rousseau 269
35     #ifndef TRUE
36     #define TRUE 1
37     #define FALSE 0
38     #endif
39    
40 rousseau 1057 static int ccid_parse_interface_descriptor(usb_dev_handle *handle,
41 rousseau 269 struct usb_device *dev);
42    
43 rousseau 405
44     /*****************************************************************************
45     *
46     * main
47     *
48     ****************************************************************************/
49 rousseau 2256 int main(void)
50 rousseau 269 {
51 rousseau 1819 static struct usb_bus *busses = NULL;
52     struct usb_bus *bus;
53     struct usb_dev_handle *dev_handle;
54 rousseau 269
55 rousseau 1819 usb_init();
56     usb_find_busses();
57     usb_find_devices();
58    
59     busses = usb_get_busses();
60     if (busses == NULL)
61 rousseau 269 {
62 rousseau 2328 printf("No USB buses found\n");
63 rousseau 1819 return -1;
64     }
65    
66     /* on any USB buses */
67     for (bus = busses; bus; bus = bus->next)
68     {
69     struct usb_device *dev;
70    
71     /* any device on this bus */
72     for (dev = bus->devices; dev; dev = dev->next)
73 rousseau 269 {
74 rousseau 1819 struct usb_interface *usb_interface = NULL;
75 rousseau 269
76 rousseau 1819 /* check if the device has bInterfaceClass == 11 */
77     usb_interface = get_ccid_usb_interface(dev);
78     if (NULL == usb_interface)
79     continue;
80    
81     fprintf(stderr, "Trying to open USB bus/device: %s/%s\n",
82     bus->dirname, dev->filename);
83    
84     dev_handle = usb_open(dev);
85     if (NULL == dev_handle)
86     {
87     fprintf(stderr, "Can't usb_open(%s/%s): %s\n",
88     bus->dirname, dev->filename, strerror(errno));
89     continue;
90     }
91    
92     /* now we found a free reader and we try to use it */
93     if (NULL == dev->config)
94     {
95     usb_close(dev_handle);
96     fprintf(stderr, "No dev->config found for %s/%s\n",
97     bus->dirname, dev->filename);
98     continue;
99     }
100    
101     usb_interface = get_ccid_usb_interface(dev);
102     if (NULL == usb_interface)
103     {
104     usb_close(dev_handle);
105     fprintf(stderr, "Can't find a CCID interface on %s/%s\n",
106     bus->dirname, dev->filename);
107     continue;
108 rousseau 2152 }
109 rousseau 1819
110     ccid_parse_interface_descriptor(dev_handle, dev);
111     usb_close(dev_handle);
112 rousseau 269 }
113     }
114    
115     return 0;
116     } /* main */
117    
118 rousseau 405
119 rousseau 269 /*****************************************************************************
120     *
121     * Parse a CCID USB Descriptor
122     *
123     ****************************************************************************/
124 rousseau 1057 static int ccid_parse_interface_descriptor(usb_dev_handle *handle,
125 rousseau 269 struct usb_device *dev)
126     {
127     struct usb_interface_descriptor *usb_interface;
128     unsigned char *extra;
129 rousseau 2428 char buffer[256*sizeof(int)]; /* maximum is 256 records */
130 rousseau 269
131     /*
132     * Vendor/model name
133     */
134 rousseau 1277 printf(" idVendor: 0x%04X\n", dev->descriptor.idVendor);
135 rousseau 314 if (usb_get_string_simple(handle, dev->descriptor.iManufacturer,
136     buffer, sizeof(buffer)) < 0)
137 rousseau 2234 {
138 rousseau 1277 printf(" Can't get iManufacturer string\n");
139 rousseau 2234 if (getuid())
140     {
141     printf("\33[01;31mPlease, restart the command as root\33[0m\n\n");
142     return TRUE;
143     }
144     }
145 rousseau 314 else
146 rousseau 1277 printf(" iManufacturer: %s\n", buffer);
147 rousseau 269
148 rousseau 1277 printf(" idProduct: 0x%04X\n", dev->descriptor.idProduct);
149 rousseau 314 if (usb_get_string_simple(handle, dev->descriptor.iProduct,
150     buffer, sizeof(buffer)) < 0)
151 rousseau 1277 printf(" Can't get iProduct string\n");
152 rousseau 314 else
153 rousseau 1277 printf(" iProduct: %s\n", buffer);
154 rousseau 269
155 rousseau 1276 printf(" bcdDevice: %X.%02X (firmware release?)\n",
156     dev->descriptor.bcdDevice >> 8, dev->descriptor.bcdDevice & 0xFF);
157    
158 rousseau 737 usb_interface = get_ccid_usb_interface(dev)->altsetting;
159 rousseau 2152
160 rousseau 269 printf(" bLength: %d\n", usb_interface->bLength);
161 rousseau 2152
162 rousseau 269 printf(" bDescriptorType: %d\n", usb_interface->bDescriptorType);
163 rousseau 2152
164 rousseau 269 printf(" bInterfaceNumber: %d\n", usb_interface->bInterfaceNumber);
165 rousseau 2152
166 rousseau 269 printf(" bAlternateSetting: %d\n", usb_interface->bAlternateSetting);
167 rousseau 2152
168 rousseau 269 printf(" bNumEndpoints: %d\n", usb_interface->bNumEndpoints);
169 rousseau 2389 switch (usb_interface->bNumEndpoints)
170     {
171     case 0:
172     printf(" Control only\n");
173     break;
174     case 1:
175     printf(" Interrupt-IN\n");
176     break;
177     case 2:
178     printf(" bulk-IN and bulk-OUT\n");
179     break;
180     case 3:
181     printf(" bulk-IN, bulk-OUT and Interrupt-IN\n");
182     break;
183     default:
184     printf(" UNKNOWN value\n");
185     }
186 rousseau 269
187     printf(" bInterfaceClass: 0x%02X", usb_interface->bInterfaceClass);
188     if (usb_interface->bInterfaceClass == 0x0b)
189     printf(" [Chip Card Interface Device Class (CCID)]\n");
190     else
191     {
192 rousseau 529 printf("\n NOT A CCID DEVICE\n");
193 rousseau 528 if (usb_interface->bInterfaceClass != 0xFF)
194     return TRUE;
195     else
196 rousseau 529 printf(" Class is 0xFF (proprietary)\n");
197 rousseau 269 }
198 rousseau 2152
199 rousseau 269 printf(" bInterfaceSubClass: %d\n", usb_interface->bInterfaceSubClass);
200     if (usb_interface->bInterfaceSubClass)
201     printf(" UNSUPPORTED SubClass\n");
202    
203     printf(" bInterfaceProtocol: %d\n", usb_interface->bInterfaceProtocol);
204 rousseau 2390 switch (usb_interface->bInterfaceProtocol)
205     {
206     case 0:
207     printf(" bulk transfer, optional interrupt-IN\n");
208     break;
209     case 1:
210     printf(" ICCD Version A, Control transfers, (no interrupt-IN)\n");
211     break;
212     case 2:
213     printf(" ICCD Version B, Control transfers, (optional interrupt-IN)\n");
214     break;
215     default:
216     printf(" UNSUPPORTED InterfaceProtocol\n");
217     }
218 rousseau 269
219     printf(" iInterface: %d\n", usb_interface->iInterface);
220    
221 rousseau 579 if (usb_interface->extralen < 54)
222     {
223     printf("USB extra length is too short: %d\n", usb_interface->extralen);
224     printf("\n NOT A CCID DEVICE\n");
225     return TRUE;
226     }
227    
228 rousseau 269 /*
229     * CCID Class Descriptor
230     */
231     printf(" CCID Class Descriptor\n");
232     extra = usb_interface->extra;
233    
234     printf(" bLength: 0x%02X\n", extra[0]);
235     if (extra[0] != 0x36)
236     {
237     printf(" UNSUPPORTED bLength\n");
238     return TRUE;
239     }
240    
241     printf(" bDescriptorType: 0x%02X\n", extra[1]);
242     if (extra[1] != 0x21)
243     {
244 rousseau 737 if (0xFF == extra[1])
245     printf(" PROPRIETARY bDescriptorType\n");
246     else
247     {
248     printf(" UNSUPPORTED bDescriptorType\n");
249     return TRUE;
250     }
251 rousseau 269 }
252    
253     printf(" bcdCCID: %X.%02X\n", extra[3], extra[2]);
254     printf(" bMaxSlotIndex: 0x%02X\n", extra[4]);
255 rousseau 405 printf(" bVoltageSupport: 0x%02X\n", extra[5]);
256 rousseau 269 if (extra[5] & 0x01)
257 rousseau 405 printf(" 5.0V\n");
258 rousseau 269 if (extra[5] & 0x02)
259 rousseau 405 printf(" 3.0V\n");
260 rousseau 269 if (extra[5] & 0x04)
261 rousseau 405 printf(" 1.8V\n");
262 rousseau 269
263 rousseau 405 printf(" dwProtocols: 0x%02X%02X 0x%02X%02X\n", extra[9], extra[8],
264     extra[7],extra[6]);
265 rousseau 269 if (extra[6] & 0x01)
266 rousseau 405 printf(" T=0\n");
267 rousseau 269 if (extra[6] & 0x02)
268 rousseau 405 printf(" T=1\n");
269 rousseau 269
270     printf(" dwDefaultClock: %.3f MHz\n", dw2i(extra, 10)/1000.0);
271     printf(" dwMaximumClock: %.3f MHz\n", dw2i(extra, 14)/1000.0);
272 rousseau 1640 printf(" bNumClockSupported: %d %s\n", extra[18],
273     extra[18] ? "" : "(will use whatever is returned)");
274 rousseau 1489 {
275     int n;
276    
277     /* See CCID 3.7.2 page 25 */
278     n = usb_control_msg(handle,
279     0xA1, /* request type */
280     0x02, /* GET CLOCK FREQUENCIES */
281     0x00, /* value */
282     usb_interface->bInterfaceNumber, /* interface */
283 rousseau 2428 buffer,
284 rousseau 1489 sizeof(buffer),
285     2 * 1000);
286    
287     /* we got an error? */
288     if (n <= 0)
289 rousseau 2429 printf(" IFD does not support GET CLOCK FREQUENCIES request: %s\n", strerror(errno));
290 rousseau 1489 else
291     if (n % 4) /* not a multiple of 4 */
292     printf(" wrong size for GET CLOCK FREQUENCIES: %d\n", n);
293     else
294     {
295     int i;
296    
297 rousseau 1609 /* we do not get the expected number of data rates */
298 rousseau 1640 if ((n != extra[18]*4) && extra[18])
299 rousseau 1609 {
300     printf(" Got %d clock frequencies but was expecting %d\n",
301     n/4, extra[18]);
302    
303     /* we got more data than expected */
304     if (n > extra[18]*4)
305     n = extra[18]*4;
306     }
307    
308 rousseau 1489 for (i=0; i<n; i+=4)
309     printf(" Support %d kHz\n", dw2i(buffer, i));
310     }
311     }
312 rousseau 1488 printf(" dwDataRate: %d bps\n", dw2i(extra, 19));
313     printf(" dwMaxDataRate: %d bps\n", dw2i(extra, 23));
314 rousseau 1640 printf(" bNumDataRatesSupported: %d %s\n", extra[27],
315     extra[27] ? "" : "(will use whatever is returned)");
316 rousseau 1468 {
317     int n;
318    
319     /* See CCID 3.7.3 page 25 */
320     n = usb_control_msg(handle,
321     0xA1, /* request type */
322 rousseau 1488 0x03, /* GET DATA RATES */
323 rousseau 1468 0x00, /* value */
324     usb_interface->bInterfaceNumber, /* interface */
325 rousseau 2428 buffer,
326 rousseau 1468 sizeof(buffer),
327     2 * 1000);
328    
329     /* we got an error? */
330     if (n <= 0)
331 rousseau 2429 printf(" IFD does not support GET_DATA_RATES request: %s\n",
332     strerror(errno));
333 rousseau 1468 else
334 rousseau 1480 if (n % 4) /* not a multiple of 4 */
335     printf(" wrong size for GET_DATA_RATES: %d\n", n);
336     else
337     {
338     int i;
339 rousseau 1468
340 rousseau 1609 /* we do not get the expected number of data rates */
341 rousseau 1640 if ((n != extra[27]*4) && extra[27])
342 rousseau 1609 {
343     printf(" Got %d data rates but was expecting %d\n", n/4,
344     extra[27]);
345    
346     /* we got more data than expected */
347     if (n > extra[27]*4)
348     n = extra[27]*4;
349     }
350    
351 rousseau 1480 for (i=0; i<n; i+=4)
352     printf(" Support %d bps\n", dw2i(buffer, i));
353     }
354 rousseau 1468 }
355 rousseau 269 printf(" dwMaxIFSD: %d\n", dw2i(extra, 28));
356     printf(" dwSynchProtocols: 0x%08X\n", dw2i(extra, 32));
357 rousseau 2032 if (extra[32] & 0x01)
358 rousseau 1560 printf(" 2-wire protocol\n");
359 rousseau 2032 if (extra[32] & 0x02)
360 rousseau 1560 printf(" 3-wire protocol\n");
361 rousseau 2032 if (extra[32] & 0x04)
362 rousseau 1560 printf(" I2C protocol\n");
363 rousseau 269
364 rousseau 405 printf(" dwMechanical: 0x%08X\n", dw2i(extra, 36));
365 rousseau 269 if (extra[36] == 0)
366 rousseau 405 printf(" No special characteristics\n");
367 rousseau 269 if (extra[36] & 0x01)
368 rousseau 405 printf(" Card accept mechanism\n");
369 rousseau 269 if (extra[36] & 0x02)
370 rousseau 405 printf(" Card ejection mechanism\n");
371 rousseau 269 if (extra[36] & 0x04)
372 rousseau 405 printf(" Card capture mechanism\n");
373 rousseau 269 if (extra[36] & 0x08)
374 rousseau 405 printf(" Card lock/unlock mechanism\n");
375 rousseau 269
376 rousseau 405 printf(" dwFeatures: 0x%08X\n", dw2i(extra, 40));
377 rousseau 1481 if (dw2i(extra, 40) == 0)
378 rousseau 405 printf(" No special characteristics\n");
379 rousseau 269 if (extra[40] & 0x02)
380 rousseau 1482 printf(" ....02 Automatic parameter configuration based on ATR data\n");
381 rousseau 269 if (extra[40] & 0x04)
382 rousseau 1482 printf(" ....04 Automatic activation of ICC on inserting\n");
383 rousseau 269 if (extra[40] & 0x08)
384 rousseau 1482 printf(" ....08 Automatic ICC voltage selection\n");
385 rousseau 269 if (extra[40] & 0x10)
386 rousseau 1482 printf(" ....10 Automatic ICC clock frequency change according to parameters\n");
387 rousseau 269 if (extra[40] & 0x20)
388 rousseau 1482 printf(" ....20 Automatic baud rate change according to frequency and Fi, Di params\n");
389 rousseau 269 if (extra[40] & 0x40)
390 rousseau 1482 printf(" ....40 Automatic parameters negotiation made by the CCID\n");
391 rousseau 269 if (extra[40] & 0x80)
392 rousseau 1482 printf(" ....80 Automatic PPS made by the CCID\n");
393 rousseau 269 if (extra[41] & 0x01)
394 rousseau 1482 printf(" ..01.. CCID can set ICC in clock stop mode\n");
395 rousseau 269 if (extra[41] & 0x02)
396 rousseau 1482 printf(" ..02.. NAD value other than 00 accepted (T=1)\n");
397 rousseau 269 if (extra[41] & 0x04)
398 rousseau 1482 printf(" ..04.. Automatic IFSD exchange as first exchange (T=1)\n");
399 rousseau 1275 switch (extra[42] & 0x07)
400     {
401     case 0x00:
402 rousseau 1482 printf(" 00.... Character level exchange\n");
403 rousseau 1275 break;
404 rousseau 269
405 rousseau 1275 case 0x01:
406 rousseau 1482 printf(" 01.... TPDU level exchange\n");
407 rousseau 1275 break;
408    
409     case 0x02:
410 rousseau 1482 printf(" 02.... Short APDU level exchange\n");
411 rousseau 1275 break;
412    
413     case 0x04:
414 rousseau 1482 printf(" 04.... Short and Extended APDU level exchange\n");
415 rousseau 1275 break;
416     }
417    
418 rousseau 269 printf(" dwMaxCCIDMessageLength: %d bytes\n", dw2i(extra, 44));
419 rousseau 1561 printf(" bClassGetResponse: 0x%02X\n", extra[48]);
420     if (0xFF == extra[48])
421     printf(" echoes the APDU class\n");
422 rousseau 1562 printf(" bClassEnveloppe: 0x%02X\n", extra[49]);
423     if (0xFF == extra[49])
424     printf(" echoes the APDU class\n");
425 rousseau 269 printf(" wLcdLayout: 0x%04X\n", (extra[51] << 8)+extra[50]);
426 rousseau 1563 if (extra[50])
427     printf(" %d lines\n", extra[50]);
428     if (extra[51])
429     printf(" %d characters per line\n", extra[51]);
430 rousseau 269 printf(" bPINSupport: 0x%02X\n", extra[52]);
431 rousseau 779 if (extra[52] & 0x01)
432     printf(" PIN Verification supported\n");
433     if (extra[52] & 0x02)
434     printf(" PIN Modification supported\n");
435 rousseau 269 printf(" bMaxCCIDBusySlots: %d\n", extra[53]);
436    
437     return FALSE;
438     } /* ccid_parse_interface_descriptor */
439    

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5