/[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 2390 - (show annotations) (download)
Thu Feb 8 14:18:56 2007 UTC (6 years, 3 months ago) by rousseau
File MIME type: text/plain
File size: 11939 byte(s)
parse bInterfaceProtocol field
1 /*
2 parse.c: parse CCID structure
3 Copyright (C) 2003-2004 Ludovic Rousseau
4
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 #include <string.h>
26 # ifdef S_SPLINT_S
27 # include <sys/types.h>
28 # endif
29 #include <usb.h>
30 #include <errno.h>
31
32 #include "defs.h"
33 #include "ccid.h"
34
35 #ifndef TRUE
36 #define TRUE 1
37 #define FALSE 0
38 #endif
39
40 static int ccid_parse_interface_descriptor(usb_dev_handle *handle,
41 struct usb_device *dev);
42
43
44 /*****************************************************************************
45 *
46 * main
47 *
48 ****************************************************************************/
49 int main(void)
50 {
51 static struct usb_bus *busses = NULL;
52 struct usb_bus *bus;
53 struct usb_dev_handle *dev_handle;
54
55 usb_init();
56 usb_find_busses();
57 usb_find_devices();
58
59 busses = usb_get_busses();
60 if (busses == NULL)
61 {
62 printf("No USB buses found\n");
63 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 {
74 struct usb_interface *usb_interface = NULL;
75
76 /* 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 }
109
110 ccid_parse_interface_descriptor(dev_handle, dev);
111 usb_close(dev_handle);
112 }
113 }
114
115 return 0;
116 } /* main */
117
118
119 /*****************************************************************************
120 *
121 * Parse a CCID USB Descriptor
122 *
123 ****************************************************************************/
124 static int ccid_parse_interface_descriptor(usb_dev_handle *handle,
125 struct usb_device *dev)
126 {
127 struct usb_interface_descriptor *usb_interface;
128 unsigned char *extra;
129 char buffer[255];
130
131 /*
132 * Vendor/model name
133 */
134 printf(" idVendor: 0x%04X\n", dev->descriptor.idVendor);
135 if (usb_get_string_simple(handle, dev->descriptor.iManufacturer,
136 buffer, sizeof(buffer)) < 0)
137 {
138 printf(" Can't get iManufacturer string\n");
139 if (getuid())
140 {
141 printf("\33[01;31mPlease, restart the command as root\33[0m\n\n");
142 return TRUE;
143 }
144 }
145 else
146 printf(" iManufacturer: %s\n", buffer);
147
148 printf(" idProduct: 0x%04X\n", dev->descriptor.idProduct);
149 if (usb_get_string_simple(handle, dev->descriptor.iProduct,
150 buffer, sizeof(buffer)) < 0)
151 printf(" Can't get iProduct string\n");
152 else
153 printf(" iProduct: %s\n", buffer);
154
155 printf(" bcdDevice: %X.%02X (firmware release?)\n",
156 dev->descriptor.bcdDevice >> 8, dev->descriptor.bcdDevice & 0xFF);
157
158 usb_interface = get_ccid_usb_interface(dev)->altsetting;
159
160 printf(" bLength: %d\n", usb_interface->bLength);
161
162 printf(" bDescriptorType: %d\n", usb_interface->bDescriptorType);
163
164 printf(" bInterfaceNumber: %d\n", usb_interface->bInterfaceNumber);
165
166 printf(" bAlternateSetting: %d\n", usb_interface->bAlternateSetting);
167
168 printf(" bNumEndpoints: %d\n", usb_interface->bNumEndpoints);
169 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
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 printf("\n NOT A CCID DEVICE\n");
193 if (usb_interface->bInterfaceClass != 0xFF)
194 return TRUE;
195 else
196 printf(" Class is 0xFF (proprietary)\n");
197 }
198
199 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 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
219 printf(" iInterface: %d\n", usb_interface->iInterface);
220
221 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 /*
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 if (0xFF == extra[1])
245 printf(" PROPRIETARY bDescriptorType\n");
246 else
247 {
248 printf(" UNSUPPORTED bDescriptorType\n");
249 return TRUE;
250 }
251 }
252
253 printf(" bcdCCID: %X.%02X\n", extra[3], extra[2]);
254 printf(" bMaxSlotIndex: 0x%02X\n", extra[4]);
255 printf(" bVoltageSupport: 0x%02X\n", extra[5]);
256 if (extra[5] & 0x01)
257 printf(" 5.0V\n");
258 if (extra[5] & 0x02)
259 printf(" 3.0V\n");
260 if (extra[5] & 0x04)
261 printf(" 1.8V\n");
262
263 printf(" dwProtocols: 0x%02X%02X 0x%02X%02X\n", extra[9], extra[8],
264 extra[7],extra[6]);
265 if (extra[6] & 0x01)
266 printf(" T=0\n");
267 if (extra[6] & 0x02)
268 printf(" T=1\n");
269
270 printf(" dwDefaultClock: %.3f MHz\n", dw2i(extra, 10)/1000.0);
271 printf(" dwMaximumClock: %.3f MHz\n", dw2i(extra, 14)/1000.0);
272 printf(" bNumClockSupported: %d %s\n", extra[18],
273 extra[18] ? "" : "(will use whatever is returned)");
274 {
275 unsigned char buffer[256*sizeof(int)]; /* maximum is 256 records */
276 int n;
277
278 /* See CCID 3.7.2 page 25 */
279 n = usb_control_msg(handle,
280 0xA1, /* request type */
281 0x02, /* GET CLOCK FREQUENCIES */
282 0x00, /* value */
283 usb_interface->bInterfaceNumber, /* interface */
284 (char *)buffer,
285 sizeof(buffer),
286 2 * 1000);
287
288 /* we got an error? */
289 if (n <= 0)
290 printf(" IFD does not support GET CLOCK FREQUENCIES request\n");
291 else
292 if (n % 4) /* not a multiple of 4 */
293 printf(" wrong size for GET CLOCK FREQUENCIES: %d\n", n);
294 else
295 {
296 int i;
297
298 /* we do not get the expected number of data rates */
299 if ((n != extra[18]*4) && extra[18])
300 {
301 printf(" Got %d clock frequencies but was expecting %d\n",
302 n/4, extra[18]);
303
304 /* we got more data than expected */
305 if (n > extra[18]*4)
306 n = extra[18]*4;
307 }
308
309 for (i=0; i<n; i+=4)
310 printf(" Support %d kHz\n", dw2i(buffer, i));
311 }
312 }
313 printf(" dwDataRate: %d bps\n", dw2i(extra, 19));
314 printf(" dwMaxDataRate: %d bps\n", dw2i(extra, 23));
315 printf(" bNumDataRatesSupported: %d %s\n", extra[27],
316 extra[27] ? "" : "(will use whatever is returned)");
317 {
318 unsigned char buffer[256*sizeof(int)]; /* maximum is 256 records */
319 int n;
320
321 /* See CCID 3.7.3 page 25 */
322 n = usb_control_msg(handle,
323 0xA1, /* request type */
324 0x03, /* GET DATA RATES */
325 0x00, /* value */
326 usb_interface->bInterfaceNumber, /* interface */
327 (char *)buffer,
328 sizeof(buffer),
329 2 * 1000);
330
331 /* we got an error? */
332 if (n <= 0)
333 printf(" IFD does not support GET_DATA_RATES request\n");
334 else
335 if (n % 4) /* not a multiple of 4 */
336 printf(" wrong size for GET_DATA_RATES: %d\n", n);
337 else
338 {
339 int i;
340
341 /* we do not get the expected number of data rates */
342 if ((n != extra[27]*4) && extra[27])
343 {
344 printf(" Got %d data rates but was expecting %d\n", n/4,
345 extra[27]);
346
347 /* we got more data than expected */
348 if (n > extra[27]*4)
349 n = extra[27]*4;
350 }
351
352 for (i=0; i<n; i+=4)
353 printf(" Support %d bps\n", dw2i(buffer, i));
354 }
355 }
356 printf(" dwMaxIFSD: %d\n", dw2i(extra, 28));
357 printf(" dwSynchProtocols: 0x%08X\n", dw2i(extra, 32));
358 if (extra[32] & 0x01)
359 printf(" 2-wire protocol\n");
360 if (extra[32] & 0x02)
361 printf(" 3-wire protocol\n");
362 if (extra[32] & 0x04)
363 printf(" I2C protocol\n");
364
365 printf(" dwMechanical: 0x%08X\n", dw2i(extra, 36));
366 if (extra[36] == 0)
367 printf(" No special characteristics\n");
368 if (extra[36] & 0x01)
369 printf(" Card accept mechanism\n");
370 if (extra[36] & 0x02)
371 printf(" Card ejection mechanism\n");
372 if (extra[36] & 0x04)
373 printf(" Card capture mechanism\n");
374 if (extra[36] & 0x08)
375 printf(" Card lock/unlock mechanism\n");
376
377 printf(" dwFeatures: 0x%08X\n", dw2i(extra, 40));
378 if (dw2i(extra, 40) == 0)
379 printf(" No special characteristics\n");
380 if (extra[40] & 0x02)
381 printf(" ....02 Automatic parameter configuration based on ATR data\n");
382 if (extra[40] & 0x04)
383 printf(" ....04 Automatic activation of ICC on inserting\n");
384 if (extra[40] & 0x08)
385 printf(" ....08 Automatic ICC voltage selection\n");
386 if (extra[40] & 0x10)
387 printf(" ....10 Automatic ICC clock frequency change according to parameters\n");
388 if (extra[40] & 0x20)
389 printf(" ....20 Automatic baud rate change according to frequency and Fi, Di params\n");
390 if (extra[40] & 0x40)
391 printf(" ....40 Automatic parameters negotiation made by the CCID\n");
392 if (extra[40] & 0x80)
393 printf(" ....80 Automatic PPS made by the CCID\n");
394 if (extra[41] & 0x01)
395 printf(" ..01.. CCID can set ICC in clock stop mode\n");
396 if (extra[41] & 0x02)
397 printf(" ..02.. NAD value other than 00 accepted (T=1)\n");
398 if (extra[41] & 0x04)
399 printf(" ..04.. Automatic IFSD exchange as first exchange (T=1)\n");
400 switch (extra[42] & 0x07)
401 {
402 case 0x00:
403 printf(" 00.... Character level exchange\n");
404 break;
405
406 case 0x01:
407 printf(" 01.... TPDU level exchange\n");
408 break;
409
410 case 0x02:
411 printf(" 02.... Short APDU level exchange\n");
412 break;
413
414 case 0x04:
415 printf(" 04.... Short and Extended APDU level exchange\n");
416 break;
417 }
418
419 printf(" dwMaxCCIDMessageLength: %d bytes\n", dw2i(extra, 44));
420 printf(" bClassGetResponse: 0x%02X\n", extra[48]);
421 if (0xFF == extra[48])
422 printf(" echoes the APDU class\n");
423 printf(" bClassEnveloppe: 0x%02X\n", extra[49]);
424 if (0xFF == extra[49])
425 printf(" echoes the APDU class\n");
426 printf(" wLcdLayout: 0x%04X\n", (extra[51] << 8)+extra[50]);
427 if (extra[50])
428 printf(" %d lines\n", extra[50]);
429 if (extra[51])
430 printf(" %d characters per line\n", extra[51]);
431 printf(" bPINSupport: 0x%02X\n", extra[52]);
432 if (extra[52] & 0x01)
433 printf(" PIN Verification supported\n");
434 if (extra[52] & 0x02)
435 printf(" PIN Modification supported\n");
436 printf(" bMaxCCIDBusySlots: %d\n", extra[53]);
437
438 return FALSE;
439 } /* ccid_parse_interface_descriptor */
440

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5