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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2168 - (show annotations) (download)
Wed Sep 20 14:01:14 2006 UTC (6 years, 8 months ago) by rousseau
File MIME type: text/plain
File size: 39833 byte(s)
IFDHGetCapabilities(): add support of SCARD_ATTR_VENDOR_NAME
1 /*
2 ifdhandler.c: IFDH API
3 Copyright (C) 2003-2005 Ludovic Rousseau
4
5 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
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 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 */
19
20 /* $Id$ */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <arpa/inet.h>
26 #include "misc.h"
27 #include <pcsclite.h>
28 #include <ifdhandler.h>
29 #include <reader.h>
30
31 #include "ccid.h"
32 #include "defs.h"
33 #include "ccid_ifdhandler.h"
34 #include "config.h"
35 #include "debug.h"
36 #include "utils.h"
37 #include "commands.h"
38 #include "towitoko/atr.h"
39 #include "towitoko/pps.h"
40 #include "parser.h"
41
42 #ifdef HAVE_PTHREAD
43 #include <pthread.h>
44 #endif
45
46 /* Array of structures to hold the ATR and other state value of each slot */
47 static CcidDesc CcidSlots[CCID_DRIVER_MAX_READERS];
48
49 /* global mutex */
50 #ifdef HAVE_PTHREAD
51 static pthread_mutex_t ifdh_context_mutex = PTHREAD_MUTEX_INITIALIZER;
52 #endif
53
54 int LogLevel = DEBUG_LEVEL_CRITICAL | DEBUG_LEVEL_INFO;
55 int DriverOptions = 0;
56 int PowerOnVoltage = VOLTAGE_5V;
57 static int DebugInitialized = FALSE;
58
59 /* local functions */
60 static void init_driver(void);
61 static void extra_egt(ATR_t *atr, _ccid_descriptor *ccid_desc, DWORD Protocol);
62 static char find_baud_rate(unsigned int baudrate, unsigned int *list);
63 static unsigned int T0_card_timeout(double f, double d, int TC1, int TC2,
64 int clock_frequency);
65 static unsigned int T1_card_timeout(double f, double d, int TC1, int BWI,
66 int CWI, int clock_frequency);
67
68
69 EXTERNAL RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPSTR lpcDevice)
70 {
71 RESPONSECODE return_value = IFD_SUCCESS;
72 int reader_index;
73
74 if (! DebugInitialized)
75 init_driver();
76
77 DEBUG_INFO3("lun: %X, device: %s", Lun, lpcDevice);
78
79 if (-1 == (reader_index = GetNewReaderIndex(Lun)))
80 return IFD_COMMUNICATION_ERROR;
81
82 /* Reset ATR buffer */
83 CcidSlots[reader_index].nATRLength = 0;
84 *CcidSlots[reader_index].pcATRBuffer = '\0';
85
86 /* Reset PowerFlags */
87 CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
88
89 #ifdef HAVE_PTHREAD
90 pthread_mutex_lock(&ifdh_context_mutex);
91 #endif
92
93 if (OpenPortByName(reader_index, lpcDevice) != STATUS_SUCCESS)
94 {
95 DEBUG_CRITICAL("failed");
96 return_value = IFD_COMMUNICATION_ERROR;
97
98 /* release the allocated reader_index */
99 ReleaseReaderIndex(reader_index);
100 }
101 else
102 {
103 /* Maybe we have a special treatment for this reader */
104 ccid_open_hack(reader_index);
105
106 /* Try to access the reader */
107 /* This "warm up" sequence is sometimes needed when pcscd is
108 * restarted with the reader already connected. We get some
109 * "usb_bulk_read: Resource temporarily unavailable" on the first
110 * few tries. It is an empirical hack */
111 if ((IFD_COMMUNICATION_ERROR == IFDHICCPresence(Lun))
112 && (IFD_COMMUNICATION_ERROR == IFDHICCPresence(Lun))
113 && (IFD_COMMUNICATION_ERROR == IFDHICCPresence(Lun)))
114 {
115 DEBUG_CRITICAL("failed");
116 return_value = IFD_COMMUNICATION_ERROR;
117
118 /* release the allocated reader_index */
119 ReleaseReaderIndex(reader_index);
120 }
121 }
122
123 #ifdef HAVE_PTHREAD
124 pthread_mutex_unlock(&ifdh_context_mutex);
125 #endif
126
127 return return_value;
128 } /* IFDHCreateChannelByName */
129
130
131 EXTERNAL RESPONSECODE IFDHCreateChannel(DWORD Lun, DWORD Channel)
132 {
133 /*
134 * Lun - Logical Unit Number, use this for multiple card slots or
135 * multiple readers. 0xXXXXYYYY - XXXX multiple readers, YYYY multiple
136 * slots. The resource manager will set these automatically. By
137 * default the resource manager loads a new instance of the driver so
138 * if your reader does not have more than one smartcard slot then
139 * ignore the Lun in all the functions. Future versions of PC/SC might
140 * support loading multiple readers through one instance of the driver
141 * in which XXXX would be important to implement if you want this.
142 */
143
144 /*
145 * Channel - Channel ID. This is denoted by the following: 0x000001 -
146 * /dev/pcsc/1 0x000002 - /dev/pcsc/2 0x000003 - /dev/pcsc/3
147 *
148 * USB readers may choose to ignore this parameter and query the bus
149 * for the particular reader.
150 */
151
152 /*
153 * This function is required to open a communications channel to the
154 * port listed by Channel. For example, the first serial reader on
155 * COM1 would link to /dev/pcsc/1 which would be a sym link to
156 * /dev/ttyS0 on some machines This is used to help with intermachine
157 * independance.
158 *
159 * Once the channel is opened the reader must be in a state in which
160 * it is possible to query IFDHICCPresence() for card status.
161 *
162 * returns:
163 *
164 * IFD_SUCCESS IFD_COMMUNICATION_ERROR
165 */
166 RESPONSECODE return_value = IFD_SUCCESS;
167 int reader_index;
168
169 if (! DebugInitialized)
170 init_driver();
171
172 DEBUG_INFO2("lun: %X", Lun);
173
174 if (-1 == (reader_index = GetNewReaderIndex(Lun)))
175 return IFD_COMMUNICATION_ERROR;
176
177 /* Reset ATR buffer */
178 CcidSlots[reader_index].nATRLength = 0;
179 *CcidSlots[reader_index].pcATRBuffer = '\0';
180
181 /* Reset PowerFlags */
182 CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
183
184 #ifdef HAVE_PTHREAD
185 pthread_mutex_lock(&ifdh_context_mutex);
186 #endif
187
188 if (OpenPort(reader_index, Channel) != STATUS_SUCCESS)
189 {
190 DEBUG_CRITICAL("failed");
191 return_value = IFD_COMMUNICATION_ERROR;
192
193 /* release the allocated reader_index */
194 ReleaseReaderIndex(reader_index);
195 }
196 else
197 /* Maybe we have a special treatment for this reader */
198 ccid_open_hack(reader_index);
199
200 #ifdef HAVE_PTHREAD
201 pthread_mutex_unlock(&ifdh_context_mutex);
202 #endif
203
204 return return_value;
205 } /* IFDHCreateChannel */
206
207
208 EXTERNAL RESPONSECODE IFDHCloseChannel(DWORD Lun)
209 {
210 /*
211 * This function should close the reader communication channel for the
212 * particular reader. Prior to closing the communication channel the
213 * reader should make sure the card is powered down and the terminal
214 * is also powered down.
215 *
216 * returns:
217 *
218 * IFD_SUCCESS IFD_COMMUNICATION_ERROR
219 */
220 int reader_index;
221
222 DEBUG_INFO2("lun: %X", Lun);
223
224 if (-1 == (reader_index = LunToReaderIndex(Lun)))
225 return IFD_COMMUNICATION_ERROR;
226
227 /* Restore the default timeout
228 * No need to wait too long if the reader disapeared */
229 get_ccid_descriptor(reader_index)->readTimeout = DEFAULT_COM_READ_TIMEOUT;
230
231 (void)CmdPowerOff(reader_index);
232 /* No reader status check, if it failed, what can you do ? :) */
233
234 #ifdef HAVE_PTHREAD
235 pthread_mutex_lock(&ifdh_context_mutex);
236 #endif
237
238 (void)ClosePort(reader_index);
239 ReleaseReaderIndex(reader_index);
240
241 #ifdef HAVE_PTHREAD
242 pthread_mutex_unlock(&ifdh_context_mutex);
243 #endif
244
245 return IFD_SUCCESS;
246 } /* IFDHCloseChannel */
247
248
249 EXTERNAL RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag,
250 PDWORD Length, PUCHAR Value)
251 {
252 /*
253 * This function should get the slot/card capabilities for a
254 * particular slot/card specified by Lun. Again, if you have only 1
255 * card slot and don't mind loading a new driver for each reader then
256 * ignore Lun.
257 *
258 * Tag - the tag for the information requested example: TAG_IFD_ATR -
259 * return the Atr and it's size (required). these tags are defined in
260 * ifdhandler.h
261 *
262 * Length - the length of the returned data Value - the value of the
263 * data
264 *
265 * returns:
266 *
267 * IFD_SUCCESS IFD_ERROR_TAG
268 */
269 int reader_index;
270
271 DEBUG_INFO3("lun: %X, tag: 0x%X", Lun, Tag);
272
273 if (-1 == (reader_index = LunToReaderIndex(Lun)))
274 return IFD_COMMUNICATION_ERROR;
275
276 switch (Tag)
277 {
278 case TAG_IFD_ATR:
279 case SCARD_ATTR_ATR_STRING:
280 /* If Length is not zero, powerICC has been performed.
281 * Otherwise, return NULL pointer
282 * Buffer size is stored in *Length */
283 *Length = (*Length < CcidSlots[reader_index].nATRLength) ?
284 *Length : CcidSlots[reader_index].nATRLength;
285
286 if (*Length)
287 memcpy(Value, CcidSlots[reader_index].pcATRBuffer, *Length);
288 break;
289
290 #ifdef HAVE_PTHREAD
291 case TAG_IFD_SIMULTANEOUS_ACCESS:
292 if (*Length >= 1)
293 {
294 *Length = 1;
295 *Value = CCID_DRIVER_MAX_READERS;
296 }
297 break;
298
299 case TAG_IFD_THREAD_SAFE:
300 if (*Length >= 1)
301 {
302 *Length = 1;
303 *Value = 1; /* Can talk to multiple readers at the same time */
304 }
305 break;
306 #endif
307
308 case TAG_IFD_SLOTS_NUMBER:
309 if (*Length >= 1)
310 {
311 *Length = 1;
312 *Value = 1 + get_ccid_descriptor(reader_index) -> bMaxSlotIndex;
313 DEBUG_INFO2("Reader supports %d slots", *Value);
314 }
315 break;
316
317 case TAG_IFD_SLOT_THREAD_SAFE:
318 if (*Length >= 1)
319 {
320 *Length = 1;
321 *Value = 0; /* Can NOT talk to multiple slots at the same time */
322 }
323 break;
324
325 case SCARD_ATTR_VENDOR_IFD_VERSION:
326 /* Vendor-supplied interface device version (DWORD in the form
327 * 0xMMmmbbbb where MM = major version, mm = minor version, and
328 * bbbb = build number). */
329 *Length = sizeof(DWORD);
330 if (Value)
331 *(DWORD *)Value = CCID_VERSION;
332 break;
333
334 case SCARD_ATTR_VENDOR_NAME:
335 #define VENDOR_NAME "Ludovic Rousseau"
336 *Length = sizeof(VENDOR_NAME);
337 if (Value)
338 memcpy(Value, VENDOR_NAME, sizeof(VENDOR_NAME));
339 break;
340
341 default:
342 return IFD_ERROR_TAG;
343 }
344
345 return IFD_SUCCESS;
346 } /* IFDHGetCapabilities */
347
348
349 EXTERNAL RESPONSECODE IFDHSetCapabilities(DWORD Lun, DWORD Tag,
350 /*@unused@*/ DWORD Length, /*@unused@*/ PUCHAR Value)
351 {
352 /*
353 * This function should set the slot/card capabilities for a
354 * particular slot/card specified by Lun. Again, if you have only 1
355 * card slot and don't mind loading a new driver for each reader then
356 * ignore Lun.
357 *
358 * Tag - the tag for the information needing set
359 *
360 * Length - the length of the returned data Value - the value of the
361 * data
362 *
363 * returns:
364 *
365 * IFD_SUCCESS IFD_ERROR_TAG IFD_ERROR_SET_FAILURE
366 * IFD_ERROR_VALUE_READ_ONLY
367 */
368
369 /* By default, say it worked */
370
371 DEBUG_INFO3("lun: %X, tag: 0x%X", Lun, Tag);
372
373 /* if (CheckLun(Lun))
374 return IFD_COMMUNICATION_ERROR; */
375
376 return IFD_NOT_SUPPORTED;
377 } /* IFDHSetCapabilities */
378
379
380 EXTERNAL RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol,
381 UCHAR Flags, UCHAR PTS1, UCHAR PTS2, UCHAR PTS3)
382 {
383 /*
384 * This function should set the PTS of a particular card/slot using
385 * the three PTS parameters sent
386 *
387 * Protocol - 0 .... 14 T=0 .... T=14
388 * Flags - Logical OR of possible values:
389 * IFD_NEGOTIATE_PTS1
390 * IFD_NEGOTIATE_PTS2
391 * IFD_NEGOTIATE_PTS3
392 * to determine which PTS values to negotiate.
393 * PTS1,PTS2,PTS3 - PTS Values.
394 *
395 * returns:
396 * IFD_SUCCESS
397 * IFD_ERROR_PTS_FAILURE
398 * IFD_COMMUNICATION_ERROR
399 * IFD_PROTOCOL_NOT_SUPPORTED
400 */
401
402 BYTE pps[PPS_MAX_LENGTH];
403 ATR_t atr;
404 unsigned int len;
405 int convention;
406 int reader_index;
407
408 /* Set ccid desc params */
409 CcidDesc *ccid_slot;
410 _ccid_descriptor *ccid_desc;
411
412 DEBUG_INFO3("lun: %X, protocol T=%d", Lun, Protocol-1);
413
414 if (-1 == (reader_index = LunToReaderIndex(Lun)))
415 return IFD_COMMUNICATION_ERROR;
416
417 /* Set to zero buffer */
418 memset(pps, 0, sizeof(pps));
419 memset(&atr, 0, sizeof(atr));
420
421 /* Get ccid params */
422 ccid_slot = get_ccid_slot(reader_index);
423 ccid_desc = get_ccid_descriptor(reader_index);
424
425 /* Do not send CCID command SetParameters or PPS to the CCID
426 * The CCID will do this himself */
427 if (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_PROP)
428 return IFD_SUCCESS;
429
430 /* Get ATR of the card */
431 ATR_InitFromArray(&atr, ccid_slot->pcATRBuffer, ccid_slot->nATRLength);
432
433 /* Apply Extra EGT patch for bogus cards */
434 extra_egt(&atr, ccid_desc, Protocol);
435
436 if (SCARD_PROTOCOL_T0 == Protocol)
437 pps[1] |= ATR_PROTOCOL_TYPE_T0;
438 else
439 if (SCARD_PROTOCOL_T1 == Protocol)
440 pps[1] |= ATR_PROTOCOL_TYPE_T1;
441 else
442 return IFD_PROTOCOL_NOT_SUPPORTED;
443
444 /* TA2 present -> specific mode */
445 if (atr.ib[1][ATR_INTERFACE_BYTE_TA].present)
446 {
447 if (pps[1] != (atr.ib[1][ATR_INTERFACE_BYTE_TA].value & 0x0F))
448 {
449 /* wrong protocol */
450 DEBUG_COMM3("Specific mode in T=%d and T=%d requested",
451 atr.ib[1][ATR_INTERFACE_BYTE_TA].value & 0x0F, pps[1]);
452
453 return IFD_PROTOCOL_NOT_SUPPORTED;
454 }
455 }
456
457 /* TCi (i>2) indicates CRC instead of LRC */
458 if (SCARD_PROTOCOL_T1 == Protocol)
459 {
460 t1_state_t *t1 = &(ccid_slot -> t1);
461 int i;
462
463 /* TCi (i>2) present? */
464 for (i=2; i<ATR_MAX_PROTOCOLS; i++)
465 if (atr.ib[i][ATR_INTERFACE_BYTE_TC].present)
466 {
467 if (0 == atr.ib[i][ATR_INTERFACE_BYTE_TC].value)
468 {
469 DEBUG_COMM("Use LRC");
470 t1_set_param(t1, IFD_PROTOCOL_T1_CHECKSUM_LRC, 0);
471 }
472 else
473 if (1 == atr.ib[i][ATR_INTERFACE_BYTE_TC].value)
474 {
475 DEBUG_COMM("Use CRC");
476 t1_set_param(t1, IFD_PROTOCOL_T1_CHECKSUM_CRC, 0);
477 }
478 else
479 DEBUG_COMM2("Wrong value for TCi: %d",
480 atr.ib[i][ATR_INTERFACE_BYTE_TC].value);
481
482 /* only the first TCi (i>2) must be used */
483 break;
484 }
485 }
486
487 /* PTS1? */
488 if (Flags & IFD_NEGOTIATE_PTS1)
489 {
490 /* just use the value passed in argument */
491 pps[1] |= 0x10; /* PTS1 presence */
492 pps[2] = PTS1;
493 }
494 else
495 {
496 /* TA1 present */
497 if (atr.ib[0][ATR_INTERFACE_BYTE_TA].present)
498 {
499 unsigned int card_baudrate;
500 unsigned int default_baudrate;
501 double f, d;
502
503 ATR_GetParameter(&atr, ATR_PARAMETER_D, &d);
504 ATR_GetParameter(&atr, ATR_PARAMETER_F, &f);
505
506 /* may happen with non ISO cards */
507 if ((0 == f) || (0 == d))
508 {
509 /* values for TA1=11 */
510 f = 372;
511 d = 1;
512 }
513
514 /* Baudrate = f x D/F */
515 card_baudrate = (unsigned int) (1000 * ccid_desc->dwDefaultClock
516 * d / f);
517
518 default_baudrate = (unsigned int) (1000 * ccid_desc->dwDefaultClock
519 * ATR_DEFAULT_D / ATR_DEFAULT_F);
520
521 /* if the card does not try to lower the default speed */
522 if ((card_baudrate > default_baudrate)
523 /* and the reader is fast enough */
524 && (card_baudrate <= ccid_desc->dwMaxDataRate))
525 {
526 /* the reader has no baud rates table */
527 if ((NULL == ccid_desc->arrayOfSupportedDataRates)
528 /* or explicitely support it */
529 || find_baud_rate(card_baudrate,
530 ccid_desc->arrayOfSupportedDataRates))
531 {
532 pps[1] |= 0x10; /* PTS1 presence */
533 pps[2] = atr.ib[0][ATR_INTERFACE_BYTE_TA].value;
534
535 DEBUG_COMM2("Set speed to %d bauds", card_baudrate);
536 }
537 else
538 {
539 DEBUG_COMM2("Reader does not support %d bauds",
540 card_baudrate);
541
542 /* TA2 present -> specific mode: the card is supporting
543 * only the baud rate specified in TA1 but reader does not
544 * support this value. Reject the card. */
545 if (atr.ib[1][ATR_INTERFACE_BYTE_TA].present)
546 return IFD_COMMUNICATION_ERROR;
547 }
548 }
549 else
550 {
551 /* the card is too fast for the reader */
552 if ((card_baudrate > ccid_desc->dwMaxDataRate +2)
553 /* but TA1 <= 97 */
554 && (atr.ib[0][ATR_INTERFACE_BYTE_TA].value <= 0x97)
555 /* and the reader has a baud rate table */
556 && ccid_desc->arrayOfSupportedDataRates)
557 {
558 unsigned char old_TA1;
559
560 old_TA1 = atr.ib[0][ATR_INTERFACE_BYTE_TA].value;
561 while (atr.ib[0][ATR_INTERFACE_BYTE_TA].value > 0x94)
562 {
563 /* use a lower TA1 */
564 atr.ib[0][ATR_INTERFACE_BYTE_TA].value--;
565
566 ATR_GetParameter(&atr, ATR_PARAMETER_D, &d);
567 ATR_GetParameter(&atr, ATR_PARAMETER_F, &f);
568
569 /* Baudrate = f x D/F */
570 card_baudrate = (unsigned int) (1000 *
571 ccid_desc->dwDefaultClock * d / f);
572
573 if (find_baud_rate(card_baudrate,
574 ccid_desc->arrayOfSupportedDataRates))
575 {
576 pps[1] |= 0x10; /* PTS1 presence */
577 pps[2] = atr.ib[0][ATR_INTERFACE_BYTE_TA].value;
578
579 DEBUG_COMM2("Set adapted speed to %d bauds",
580 card_baudrate);
581
582 break;
583 }
584 }
585
586 /* restore original TA1 value */
587 atr.ib[0][ATR_INTERFACE_BYTE_TA].value = old_TA1;
588 }
589 }
590 }
591 }
592
593 /* PTS2? */
594 if (Flags & IFD_NEGOTIATE_PTS2)
595 {
596 pps[1] |= 0x20; /* PTS2 presence */
597 pps[3] = PTS2;
598 }
599
600 /* PTS3? */
601 if (Flags & IFD_NEGOTIATE_PTS3)
602 {
603 pps[1] |= 0x40; /* PTS3 presence */
604 pps[4] = PTS3;
605 }
606
607 /* Generate PPS */
608 pps[0] = 0xFF;
609
610 /* Automatic PPS made by the ICC? */
611 if ((! (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_CUR))
612 /* TA2 absent: negociable mode */
613 && (! atr.ib[1][ATR_INTERFACE_BYTE_TA].present))
614 {
615 int default_protocol;
616
617 if (ATR_MALFORMED == ATR_GetDefaultProtocol(&atr, &default_protocol))
618 return IFD_PROTOCOL_NOT_SUPPORTED;
619
620 /* if the requested protocol is not the default one
621 * or a TA1/PPS1 is present */
622 if (((pps[1] & 0x0F) != default_protocol) || (PPS_HAS_PPS1(pps)))
623 if (PPS_Exchange(reader_index, pps, &len, &pps[2]) != PPS_OK)
624 {
625 DEBUG_INFO("PPS_Exchange Failed");
626
627 return IFD_ERROR_PTS_FAILURE;
628 }
629 }
630
631 /* Now we must set the reader parameters */
632 ATR_GetConvention(&atr, &convention);
633
634 /* specific mode and implicit parameters? (b5 of TA2) */
635 if (atr.ib[1][ATR_INTERFACE_BYTE_TA].present
636 && (atr.ib[1][ATR_INTERFACE_BYTE_TA].value & 0x10))
637 return IFD_COMMUNICATION_ERROR;
638
639 /* T=1 */
640 if (SCARD_PROTOCOL_T1 == Protocol)
641 {
642 BYTE param[] = {
643 0x11, /* Fi/Di */
644 0x10, /* TCCKS */
645 0x00, /* GuardTime */
646 0x4D, /* BWI/CWI */
647 0x00, /* ClockStop */
648 0x20, /* IFSC */
649 0x00 /* NADValue */
650 };
651 int i;
652 t1_state_t *t1 = &(ccid_slot -> t1);
653 RESPONSECODE ret;
654 double f, d;
655
656 /* TA1 is not default */
657 if (PPS_HAS_PPS1(pps))
658 param[0] = pps[2];
659
660 /* CRC checksum? */
661 if (2 == t1->rc_bytes)
662 param[1] |= 0x01;
663
664 /* the CCID should ignore this bit */
665 if (ATR_CONVENTION_INVERSE == convention)
666 param[1] |= 0x02;
667
668 /* get TC1 Extra guard time */
669 if (atr.ib[0][ATR_INTERFACE_BYTE_TC].present)
670 param[2] = atr.ib[0][ATR_INTERFACE_BYTE_TC].value;
671
672 /* TBi (i>2) present? BWI/CWI */
673 for (i=2; i<ATR_MAX_PROTOCOLS; i++)
674 if (atr.ib[i][ATR_INTERFACE_BYTE_TB].present)
675 {
676 DEBUG_COMM3("BWI/CWI (TB%d) present: 0x%02X", i+1,
677 atr.ib[i][ATR_INTERFACE_BYTE_TB].value);
678 param[3] = atr.ib[i][ATR_INTERFACE_BYTE_TB].value;
679
680 /* only the first TBi (i>2) must be used */
681 break;
682 }
683
684 /* compute communication timeout */
685 ATR_GetParameter(&atr, ATR_PARAMETER_F, &f);
686 ATR_GetParameter(&atr, ATR_PARAMETER_D, &d);
687 ccid_desc->readTimeout = T1_card_timeout(f, d, param[2],
688 (param[3] & 0xF0) >> 4 /* BWI */, param[3] & 0x0F /* CWI */,
689 ccid_desc->dwDefaultClock);
690
691 DEBUG_COMM2("Timeout: %d seconds", ccid_desc->readTimeout);
692
693 ret = SetParameters(reader_index, 1, sizeof(param), param);
694 if (IFD_SUCCESS != ret)
695 return ret;
696 }
697 else
698 /* T=0 */
699 {
700 BYTE param[] = {
701 0x11, /* Fi/Di */
702 0x00, /* TCCKS */
703 0x00, /* GuardTime */
704 0x0A, /* WaitingInteger */
705 0x00 /* ClockStop */
706 };
707 RESPONSECODE ret;
708 double f, d;
709
710 /* TA1 is not default */
711 if (PPS_HAS_PPS1(pps))
712 param[0] = pps[2];
713
714 if (ATR_CONVENTION_INVERSE == convention)
715 param[1] |= 0x02;
716
717 /* get TC1 Extra guard time */
718 if (atr.ib[0][ATR_INTERFACE_BYTE_TC].present)
719 param[2] = atr.ib[0][ATR_INTERFACE_BYTE_TC].value;
720
721 /* TC2 WWT */
722 if (atr.ib[1][ATR_INTERFACE_BYTE_TC].present)
723 param[3] = atr.ib[1][ATR_INTERFACE_BYTE_TC].value;
724
725 /* compute communication timeout */
726 ATR_GetParameter(&atr, ATR_PARAMETER_F, &f);
727 ATR_GetParameter(&atr, ATR_PARAMETER_D, &d);
728
729 ccid_desc->readTimeout = T0_card_timeout(f, d, param[2] /* TC1 */,
730 param[3] /* TC2 */, ccid_desc->dwDefaultClock);
731
732 DEBUG_COMM2("Communication timeout: %d seconds",
733 ccid_desc->readTimeout);
734
735 ret = SetParameters(reader_index, 0, sizeof(param), param);
736 if (IFD_SUCCESS != ret)
737 return ret;
738 }
739
740 /* set IFSC & IFSD in T=1 */
741 if (SCARD_PROTOCOL_T1 == Protocol)
742 {
743 t1_state_t *t1 = &(ccid_slot -> t1);
744 int i;
745
746 /* TAi (i>2) present? */
747 for (i=2; i<ATR_MAX_PROTOCOLS; i++)
748 if (atr.ib[i][ATR_INTERFACE_BYTE_TA].present)
749 {
750 DEBUG_COMM3("IFSC (TA%d) present: %d", i+1,
751 atr.ib[i][ATR_INTERFACE_BYTE_TA].value);
752 t1_set_param(t1, IFD_PROTOCOL_T1_IFSC,
753 atr.ib[i][ATR_INTERFACE_BYTE_TA].value);
754
755 /* only the first TAi (i>2) must be used */
756 break;
757 }
758
759 /* IFSD not negociated by the reader? */
760 if (! (ccid_desc->dwFeatures & CCID_CLASS_AUTO_IFSD))
761 {
762 DEBUG_COMM2("Negociate IFSD at %d", ccid_desc -> dwMaxIFSD);
763 if (t1_negociate_ifsd(t1, 0, ccid_desc -> dwMaxIFSD) < 0)
764 return IFD_COMMUNICATION_ERROR;
765 }
766 t1_set_param(t1, IFD_PROTOCOL_T1_IFSD, ccid_desc -> dwMaxIFSD);
767
768 DEBUG_COMM3("T=1: IFSC=%d, IFSD=%d", t1->ifsc, t1->ifsd);
769 }
770
771 /* store used protocol for use by the secure commands (verify/change PIN) */
772 ccid_desc->cardProtocol = Protocol;
773
774 return IFD_SUCCESS;
775 } /* IFDHSetProtocolParameters */
776
777
778 EXTERNAL RESPONSECODE IFDHPowerICC(DWORD Lun, DWORD Action,
779 PUCHAR Atr, PDWORD AtrLength)
780 {
781 /*
782 * This function controls the power and reset signals of the smartcard
783 * reader at the particular reader/slot specified by Lun.
784 *
785 * Action - Action to be taken on the card.
786 *
787 * IFD_POWER_UP - Power and reset the card if not done so (store the
788 * ATR and return it and it's length).
789 *
790 * IFD_POWER_DOWN - Power down the card if not done already
791 * (Atr/AtrLength should be zero'd)
792 *
793 * IFD_RESET - Perform a quick reset on the card. If the card is not
794 * powered power up the card. (Store and return the Atr/Length)
795 *
796 * Atr - Answer to Reset of the card. The driver is responsible for
797 * caching this value in case IFDHGetCapabilities is called requesting
798 * the ATR and it's length. This should not exceed MAX_ATR_SIZE.
799 *
800 * AtrLength - Length of the Atr. This should not exceed
801 * MAX_ATR_SIZE.
802 *
803 * Notes:
804 *
805 * Memory cards without an ATR should return IFD_SUCCESS on reset but
806 * the Atr should be zero'd and the length should be zero
807 *
808 * Reset errors should return zero for the AtrLength and return
809 * IFD_ERROR_POWER_ACTION.
810 *
811 * returns:
812 *
813 * IFD_SUCCESS IFD_ERROR_POWER_ACTION IFD_COMMUNICATION_ERROR
814 * IFD_NOT_SUPPORTED
815 */
816
817 unsigned int nlength;
818 RESPONSECODE return_value = IFD_SUCCESS;
819 unsigned char pcbuffer[RESP_BUF_SIZE];
820 int reader_index;
821
822 DEBUG_INFO2("lun: %X", Lun);
823
824 /* By default, assume it won't work :) */
825 *AtrLength = 0;
826
827 if (-1 == (reader_index = LunToReaderIndex(Lun)))
828 return IFD_COMMUNICATION_ERROR;
829
830 switch (Action)
831 {
832 case IFD_POWER_DOWN:
833 /* Clear ATR buffer */
834 CcidSlots[reader_index].nATRLength = 0;
835 *CcidSlots[reader_index].pcATRBuffer = '\0';
836
837 /* Memorise the request */
838 CcidSlots[reader_index].bPowerFlags |= MASK_POWERFLAGS_PDWN;
839
840 /* send the command */
841 if (IFD_SUCCESS != CmdPowerOff(reader_index))
842 {
843 DEBUG_CRITICAL("PowerDown failed");
844 return_value = IFD_ERROR_POWER_ACTION;
845 goto end;
846 }
847
848 /* clear T=1 context */
849 t1_release(&(get_ccid_slot(reader_index) -> t1));
850 break;
851
852 case IFD_POWER_UP:
853 case IFD_RESET:
854 nlength = sizeof(pcbuffer);
855 if (CmdPowerOn(reader_index, &nlength, pcbuffer, PowerOnVoltage)
856 != IFD_SUCCESS)
857 {
858 DEBUG_CRITICAL("PowerUp failed");
859 return_value = IFD_ERROR_POWER_ACTION;
860 goto end;
861 }
862
863 /* Power up successful, set state variable to memorise it */
864 CcidSlots[reader_index].bPowerFlags |= MASK_POWERFLAGS_PUP;
865 CcidSlots[reader_index].bPowerFlags &= ~MASK_POWERFLAGS_PDWN;
866
867 /* Reset is returned, even if TCK is wrong */
868 CcidSlots[reader_index].nATRLength = *AtrLength =
869 (nlength < MAX_ATR_SIZE) ? nlength : MAX_ATR_SIZE;
870 memcpy(Atr, pcbuffer, *AtrLength);
871 memcpy(CcidSlots[reader_index].pcATRBuffer, pcbuffer, *AtrLength);
872
873 /* initialise T=1 context */
874 t1_init(&(get_ccid_slot(reader_index) -> t1), reader_index);
875 break;
876
877 default:
878 DEBUG_CRITICAL("Action not supported");
879 return_value = IFD_NOT_SUPPORTED;
880 }
881 end:
882
883 return return_value;
884 } /* IFDHPowerICC */
885
886
887 EXTERNAL RESPONSECODE IFDHTransmitToICC(DWORD Lun, SCARD_IO_HEADER SendPci,
888 PUCHAR TxBuffer, DWORD TxLength,
889 PUCHAR RxBuffer, PDWORD RxLength, /*@unused@*/ PSCARD_IO_HEADER RecvPci)
890 {
891 /*
892 * This function performs an APDU exchange with the card/slot
893 * specified by Lun. The driver is responsible for performing any
894 * protocol specific exchanges such as T=0/1 ... differences. Calling
895 * this function will abstract all protocol differences.
896 *
897 * SendPci Protocol - 0, 1, .... 14 Length - Not used.
898 *
899 * TxBuffer - Transmit APDU example (0x00 0xA4 0x00 0x00 0x02 0x3F
900 * 0x00) TxLength - Length of this buffer. RxBuffer - Receive APDU
901 * example (0x61 0x14) RxLength - Length of the received APDU. This
902 * function will be passed the size of the buffer of RxBuffer and this
903 * function is responsible for setting this to the length of the
904 * received APDU. This should be ZERO on all errors. The resource
905 * manager will take responsibility of zeroing out any temporary APDU
906 * buffers for security reasons.
907 *
908 * RecvPci Protocol - 0, 1, .... 14 Length - Not used.
909 *
910 * Notes: The driver is responsible for knowing what type of card it
911 * has. If the current slot/card contains a memory card then this
912 * command should ignore the Protocol and use the MCT style commands
913 * for support for these style cards and transmit them appropriately.
914 * If your reader does not support memory cards or you don't want to
915 * then ignore this.
916 *
917 * RxLength should be set to zero on error.
918 *
919 * returns:
920 *
921 * IFD_SUCCESS IFD_COMMUNICATION_ERROR IFD_RESPONSE_TIMEOUT
922 * IFD_ICC_NOT_PRESENT IFD_PROTOCOL_NOT_SUPPORTED
923 */
924
925 RESPONSECODE return_value;
926 unsigned int rx_length;
927 int reader_index;
928
929 DEBUG_INFO2("lun: %X", Lun);
930
931 if (-1 == (reader_index = LunToReaderIndex(Lun)))
932 return IFD_COMMUNICATION_ERROR;
933
934 rx_length = *RxLength;
935 return_value = CmdXfrBlock(reader_index, TxLength, TxBuffer, &rx_length,
936 RxBuffer, SendPci.Protocol);
937 *RxLength = rx_length;
938
939 return return_value;
940 } /* IFDHTransmitToICC */
941
942
943 EXTERNAL RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode,
944 PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength,
945 PDWORD pdwBytesReturned)
946 {
947 /*
948 * This function performs a data exchange with the reader (not the
949 * card) specified by Lun. Here XXXX will only be used. It is
950 * responsible for abstracting functionality such as PIN pads,
951 * biometrics, LCD panels, etc. You should follow the MCT, CTBCS
952 * specifications for a list of accepted commands to implement.
953 *
954 * TxBuffer - Transmit data TxLength - Length of this buffer. RxBuffer
955 * - Receive data RxLength - Length of the received data. This
956 * function will be passed the length of the buffer RxBuffer and it
957 * must set this to the length of the received data.
958 *
959 * Notes: RxLength should be zero on error.
960 */
961 RESPONSECODE return_value = IFD_COMMUNICATION_ERROR;
962 int reader_index;
963
964 DEBUG_INFO3("lun: %X, ControlCode: 0x%X", Lun, dwControlCode);
965
966 reader_index = LunToReaderIndex(Lun);
967 if ((-1 == reader_index) || (NULL == pdwBytesReturned))
968 return return_value;
969
970 /* Set the return length to 0 to avoid problems */
971 *pdwBytesReturned = 0;
972
973 if (IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE == dwControlCode)
974 {
975 if (FALSE == (DriverOptions & DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED))
976 {
977 DEBUG_INFO("ifd exchange (Escape command) not allowed");
978 return_value = IFD_COMMUNICATION_ERROR;
979 }
980 else
981 {
982 unsigned int iBytesReturned;
983
984 iBytesReturned = RxLength;
985 return_value = CmdEscape(reader_index, TxBuffer, TxLength, RxBuffer,
986 &iBytesReturned);
987 *pdwBytesReturned = iBytesReturned;
988 }
989 }
990
991 /* Implement the PC/SC v2.1.2 Part 10 IOCTL mechanism */
992
993 /* Query for features */
994 if (CM_IOCTL_GET_FEATURE_REQUEST == dwControlCode)
995 {
996 unsigned int iBytesReturned = 0;
997 PCSC_TLV_STRUCTURE *pcsc_tlv = (PCSC_TLV_STRUCTURE *)RxBuffer;
998
999 /* we need room for two records */
1000 if (RxLength < 2 * sizeof(PCSC_TLV_STRUCTURE))
1001 return IFD_COMMUNICATION_ERROR;
1002
1003 /* We can only support direct verify and/or modify currently */
1004 if (get_ccid_descriptor(reader_index) -> bPINSupport
1005 & CCID_CLASS_PIN_VERIFY)
1006 {
1007 pcsc_tlv -> tag = FEATURE_VERIFY_PIN_DIRECT;
1008 pcsc_tlv -> length = 0x04; /* always 0x04 */
1009 pcsc_tlv -> value = htonl(IOCTL_FEATURE_VERIFY_PIN_DIRECT);
1010
1011 pcsc_tlv++;
1012 iBytesReturned += sizeof(PCSC_TLV_STRUCTURE);
1013 }
1014
1015 if (get_ccid_descriptor(reader_index) -> bPINSupport
1016 & CCID_CLASS_PIN_MODIFY)
1017 {
1018 pcsc_tlv -> tag = FEATURE_MODIFY_PIN_DIRECT;
1019 pcsc_tlv -> length = 0x04; /* always 0x04 */
1020 pcsc_tlv -> value = htonl(IOCTL_FEATURE_MODIFY_PIN_DIRECT);
1021
1022 pcsc_tlv++;
1023 iBytesReturned += sizeof(PCSC_TLV_STRUCTURE);
1024 }
1025 *pdwBytesReturned = iBytesReturned;
1026 return_value = IFD_SUCCESS;
1027 }
1028
1029 /* Verify a PIN, plain CCID */
1030 if (IOCTL_FEATURE_VERIFY_PIN_DIRECT == dwControlCode)
1031 {
1032 unsigned int iBytesReturned;
1033
1034 iBytesReturned = RxLength;
1035 return_value = SecurePINVerify(reader_index, TxBuffer, TxLength,
1036 RxBuffer, &iBytesReturned);
1037 *pdwBytesReturned = iBytesReturned;
1038 }
1039
1040 /* Modify a PIN, plain CCID */
1041 if (IOCTL_FEATURE_MODIFY_PIN_DIRECT == dwControlCode)
1042 {
1043 unsigned int iBytesReturned;
1044
1045 iBytesReturned = RxLength;
1046 return_value = SecurePINModify(reader_index, TxBuffer, TxLength,
1047 RxBuffer, &iBytesReturned);
1048 *pdwBytesReturned = iBytesReturned;
1049 }
1050
1051 return return_value;
1052 } /* IFDHControl */
1053
1054
1055 EXTERNAL RESPONSECODE IFDHICCPresence(DWORD Lun)
1056 {
1057 /*
1058 * This function returns the status of the card inserted in the
1059 * reader/slot specified by Lun. It will return either:
1060 *
1061 * returns: IFD_ICC_PRESENT IFD_ICC_NOT_PRESENT
1062 * IFD_COMMUNICATION_ERROR
1063 */
1064
1065 unsigned char pcbuffer[SIZE_GET_SLOT_STATUS];
1066 RESPONSECODE return_value = IFD_COMMUNICATION_ERROR;
1067 int oldLogLevel;
1068 int reader_index;
1069 _ccid_descriptor *ccid_descriptor;
1070 unsigned int oldReadTimeout;
1071
1072 DEBUG_PERIODIC2("lun: %X", Lun);
1073
1074 if (-1 == (reader_index = LunToReaderIndex(Lun)))
1075 return IFD_COMMUNICATION_ERROR;
1076
1077 ccid_descriptor = get_ccid_descriptor(reader_index);
1078
1079 /* save the current read timeout computed from card capabilities */
1080 oldReadTimeout = ccid_descriptor->readTimeout;
1081
1082 /* use default timeout since the reader may not be present anymore */
1083 ccid_descriptor->readTimeout = DEFAULT_COM_READ_TIMEOUT;
1084
1085 /* if DEBUG_LEVEL_PERIODIC is not set we remove DEBUG_LEVEL_COMM */
1086 oldLogLevel = LogLevel;
1087 if (! (LogLevel & DEBUG_LEVEL_PERIODIC))
1088 LogLevel &= ~DEBUG_LEVEL_COMM;
1089
1090 return_value = CmdGetSlotStatus(reader_index, pcbuffer);
1091
1092 /* set back the old timeout */
1093 ccid_descriptor->readTimeout = oldReadTimeout;
1094
1095 /* set back the old LogLevel */
1096 LogLevel = oldLogLevel;
1097
1098 if (return_value != IFD_SUCCESS)
1099 return IFD_COMMUNICATION_ERROR;
1100
1101 return_value = IFD_COMMUNICATION_ERROR;
1102 switch (pcbuffer[7] & CCID_ICC_STATUS_MASK) /* bStatus */
1103 {
1104 case CCID_ICC_PRESENT_ACTIVE:
1105 return_value = IFD_ICC_PRESENT;
1106 /* use default slot */
1107 break;
1108
1109 case CCID_ICC_PRESENT_INACTIVE:
1110 if (CcidSlots[reader_index].bPowerFlags == POWERFLAGS_RAZ)
1111 /* the card was previously absent */
1112 return_value = IFD_ICC_PRESENT;
1113 else
1114 {
1115 /* the card was previously present but has been
1116 * removed and inserted between two consecutive
1117 * IFDHICCPresence() calls */
1118 CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
1119 return_value = IFD_ICC_NOT_PRESENT;
1120 }
1121 break;
1122
1123 case CCID_ICC_ABSENT:
1124 /* Reset ATR buffer */
1125 CcidSlots[reader_index].nATRLength = 0;
1126 *CcidSlots[reader_index].pcATRBuffer = '\0';
1127
1128 /* Reset PowerFlags */
1129 CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
1130
1131 return_value = IFD_ICC_NOT_PRESENT;
1132 break;
1133 }
1134
1135 /* SCR331-DI contactless reader */
1136 if (((SCR331DI == ccid_descriptor->readerID)
1137 || (SDI010 == ccid_descriptor->readerID)
1138 || (SCR331DINTTCOM == ccid_descriptor->readerID))
1139 && (ccid_descriptor->bCurrentSlotIndex > 0))
1140 {
1141 unsigned char cmd[] = { 0x11 };
1142 /* command: 11 ??
1143 * response: 00 11 01 ?? no card
1144 * 01 04 00 ?? card present */
1145
1146 unsigned char res[10];
1147 unsigned int length_res = sizeof(res);
1148 RESPONSECODE ret;
1149
1150 /* if DEBUG_LEVEL_PERIODIC is not set we remove DEBUG_LEVEL_COMM */
1151 oldLogLevel = LogLevel;
1152 if (! (LogLevel & DEBUG_LEVEL_PERIODIC))
1153 LogLevel &= ~DEBUG_LEVEL_COMM;
1154
1155 ret = CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res);
1156
1157 /* set back the old LogLevel */
1158 LogLevel = oldLogLevel;
1159
1160 if (ret != IFD_SUCCESS)
1161 {
1162 DEBUG_INFO("CmdEscape failed");
1163 /* simulate a card absent */
1164 res[0] = 0;
1165 }
1166
1167 if (0x01 == res[0])
1168 return_value = IFD_ICC_PRESENT;
1169 else
1170 {
1171 /* Reset ATR buffer */
1172 CcidSlots[reader_index].nATRLength = 0;
1173 *CcidSlots[reader_index].pcATRBuffer = '\0';
1174
1175 /* Reset PowerFlags */
1176 CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
1177
1178 return_value = IFD_ICC_NOT_PRESENT;
1179 }
1180 }
1181
1182 DEBUG_PERIODIC2("Card %s",
1183 IFD_ICC_PRESENT == return_value ? "present" : "absent");
1184
1185 return return_value;
1186 } /* IFDHICCPresence */
1187
1188
1189 CcidDesc *get_ccid_slot(unsigned int reader_index)
1190 {
1191 return &CcidSlots[reader_index];
1192 } /* get_ccid_slot */
1193
1194
1195 void init_driver(void)
1196 {
1197 char keyValue[TOKEN_MAX_VALUE_SIZE];
1198 char infofile[FILENAME_MAX];
1199
1200 /* Info.plist full patch filename */
1201 snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
1202 PCSCLITE_HP_DROPDIR, BUNDLE);
1203
1204 /* Log level */
1205 if (0 == LTPBundleFindValueWithKey(infofile, "ifdLogLevel", keyValue, 0))
1206 {
1207 /* convert from hex or dec or octal */
1208 LogLevel = strtoul(keyValue, NULL, 0);
1209
1210 /* print the log level used */
1211 DEBUG_INFO2("LogLevel: 0x%.4X", LogLevel);
1212 }
1213
1214 /* Driver options */
1215 if (0 == LTPBundleFindValueWithKey(infofile, "ifdDriverOptions", keyValue, 0))
1216 {
1217 /* convert from hex or dec or octal */
1218 DriverOptions = strtoul(keyValue, NULL, 0);
1219
1220 /* print the log level used */
1221 DEBUG_INFO2("DriverOptions: 0x%.4X", DriverOptions);
1222 }
1223
1224 /* get the voltage parameter */
1225 switch ((DriverOptions >> 4) & 0x03)
1226 {
1227 case 0:
1228 PowerOnVoltage = VOLTAGE_5V;
1229 break;
1230
1231 case 1:
1232 PowerOnVoltage = VOLTAGE_3V;
1233 break;
1234
1235 case 2:
1236 PowerOnVoltage = VOLTAGE_1_8V;
1237 break;
1238
1239 case 3:
1240 PowerOnVoltage = VOLTAGE_AUTO;
1241 break;
1242 }
1243
1244 /* initialise the Lun to reader_index mapping */
1245 InitReaderIndex();
1246
1247 DebugInitialized = TRUE;
1248 } /* init_driver */
1249
1250
1251 void extra_egt(ATR_t *atr, _ccid_descriptor *ccid_desc, DWORD Protocol)
1252 {
1253 /* This function use an EGT value for cards who comply with followings
1254 * criterias:
1255 * - TA1 > 11
1256 * - current EGT = 0x00 or 0xFF
1257 * - T=0 or (T=1 and CWI >= 2)
1258 *
1259 * Without this larger EGT some non ISO 7816-3 smart cards may not
1260 * communicate with the reader.
1261 *
1262 * This modification is harmless, the reader will just be less restrictive
1263 */
1264
1265 unsigned int card_baudrate;
1266 unsigned int default_baudrate;
1267 double f, d;
1268 int i;
1269
1270 /* if TA1 not present */
1271 if (! atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
1272 return;
1273
1274 ATR_GetParameter(atr, ATR_PARAMETER_D, &d);
1275 ATR_GetParameter(atr, ATR_PARAMETER_F, &f);
1276
1277 /* may happen with non ISO cards */
1278 if ((0 == f) || (0 == d))
1279 return;
1280
1281 /* Baudrate = f x D/F */
1282 card_baudrate = (unsigned int) (1000 * ccid_desc->dwDefaultClock * d / f);
1283
1284 default_baudrate = (unsigned int) (1000 * ccid_desc->dwDefaultClock
1285 * ATR_DEFAULT_D / ATR_DEFAULT_F);
1286
1287 /* TA1 > 11? */
1288 if (card_baudrate <= default_baudrate)
1289 return;
1290
1291 /* Current EGT = 0 or FF? */
1292 if (atr->ib[0][ATR_INTERFACE_BYTE_TC].present &&
1293 ((0x00 == atr->ib[0][ATR_INTERFACE_BYTE_TC].value) ||
1294 (0xFF == atr->ib[0][ATR_INTERFACE_BYTE_TC].value)))
1295 {
1296 if (SCARD_PROTOCOL_T0 == Protocol)
1297 {
1298 /* Init TC1 */
1299 atr->ib[0][ATR_INTERFACE_BYTE_TC].present = TRUE;
1300 atr->ib[0][ATR_INTERFACE_BYTE_TC].value = 2;
1301 DEBUG_INFO("Extra EGT patch applied");
1302 }
1303
1304 if (SCARD_PROTOCOL_T1 == Protocol)
1305 {
1306 /* TBi (i>2) present? BWI/CWI */
1307 for (i=2; i<ATR_MAX_PROTOCOLS; i++)
1308 {
1309 /* CWI >= 2 ? */
1310 if (atr->ib[i][ATR_INTERFACE_BYTE_TB].present &&
1311 ((atr->ib[i][ATR_INTERFACE_BYTE_TB].value & 0x0F) >= 2))
1312 {
1313 /* Init TC1 */
1314 atr->ib[0][ATR_INTERFACE_BYTE_TC].present = TRUE;
1315 atr->ib[0][ATR_INTERFACE_BYTE_TC].value = 2;
1316 DEBUG_INFO("Extra EGT patch applied");
1317
1318 /* only the first TBi (i>2) must be used */
1319 break;
1320 }
1321 }
1322 }
1323 }
1324 } /* extra_egt */
1325
1326
1327 static char find_baud_rate(unsigned int baudrate, unsigned int *list)
1328 {
1329 int i;
1330
1331 DEBUG_COMM2("Card baud rate: %d", baudrate);
1332
1333 /* Does the reader support the announced smart card data speed? */
1334 for (i=0;; i++)
1335 {
1336 /* end of array marker */
1337 if (0 == list[i])
1338 break;
1339
1340 DEBUG_COMM2("Reader can do: %d", list[i]);
1341
1342 /* We must take into account that the card_baudrate integral value
1343 * is an approximative result, computed from the d/f float result.
1344 */
1345 if ((baudrate < list[i] + 2) && (baudrate > list[i] - 2))
1346 return TRUE;
1347 }
1348
1349 return FALSE;
1350 } /* find_baud_rate */
1351
1352
1353 static unsigned int T0_card_timeout(double f, double d, int TC1, int TC2,
1354 int clock_frequency)
1355 {
1356 unsigned int timeout = DEFAULT_COM_READ_TIMEOUT;
1357 double EGT, WWT;
1358 unsigned int t;
1359
1360 /* Timeout applied on ISO_IN or ISO_OUT card exchange
1361 * we choose the maximum computed value.
1362 *
1363 * ISO_IN timeout is the sum of:
1364 * Terminal: Smart card:
1365 * 5 bytes header cmd ->
1366 * <- Procedure byte
1367 * 256 data bytes ->
1368 * <- SW1-SW2
1369 * = 261 EGT + 3 WWT + 3 WWT
1370 *
1371 * ISO_OUT Timeout is the sum of:
1372 * Terminal: Smart card:
1373 * 5 bytes header cmd ->
1374 * <- Procedure byte + 256 data bytes + SW1-SW2
1375 * = 5 EGT + 1 WWT + 259 WWT
1376 */
1377
1378 /* clock_frequency is in kHz so the times are in milliseconds and not
1379 * in seconds */
1380
1381 /* may happen with non ISO cards */
1382 if ((0 == f) || (0 == d) || (0 == clock_frequency))
1383 return 60; /* 60 seconds */
1384
1385 /* EGT */
1386 /* see ch. 6.5.3 Extra Guard Time, page 12 of ISO 7816-3 */
1387 EGT = 12 * f / d / clock_frequency + (f / d) * TC1 / clock_frequency;
1388
1389 /* card WWT */
1390 /* see ch. 8.2 Character level, page 15 of ISO 7816-3 */
1391 WWT = 960 * TC2 * f / clock_frequency;
1392
1393 /* ISO in */
1394 t = 261 * EGT + (3 + 3) * WWT;
1395 /* Convert from milliseonds to seconds rouned to the upper value
1396 * use +1 instead of ceil() to round up to the nearest interger
1397 * so we can avoid a dependency on the math library */
1398 t = t/1000 +1;
1399 if (timeout < t)
1400 timeout = t;
1401
1402 /* ISO out */
1403 t = 5 * EGT + (1 + 259) * WWT;
1404 t = t/1000 +1;
1405 if (timeout < t)
1406 timeout = t;
1407
1408 return timeout;
1409 } /* T0_card_timeout */
1410
1411
1412 static unsigned int T1_card_timeout(double f, double d, int TC1,
1413 int BWI, int CWI, int clock_frequency)
1414 {
1415 double EGT, BWT, CWT, etu;
1416 unsigned int timeout;
1417
1418 /* Timeout applied on ISO in + ISO out card exchange
1419 *
1420 * Timeout is the sum of:
1421 * - ISO in delay between leading edge of the first character sent by the
1422 * interface device and the last one (NAD PCB LN APDU CKS) = 260 EGT,
1423 * - delay between ISO in and ISO out = BWT,
1424 * - ISO out delay between leading edge of the first character sent by the
1425 * card and the last one (NAD PCB LN DATAS CKS) = 260 CWT.
1426 */
1427
1428 /* clock_frequency is in kHz so the times are in milliseconds and not
1429 * in seconds */
1430
1431 /* may happen with non ISO cards */
1432 if ((0 == f) || (0 == d) || (0 == clock_frequency))
1433 return 60; /* 60 seconds */
1434
1435 /* see ch. 6.5.2 Transmission factors F and D, page 12 of ISO 7816-3 */
1436 etu = f / d / clock_frequency;
1437
1438 /* EGT */
1439 /* see ch. 6.5.3 Extra Guard Time, page 12 of ISO 7816-3 */
1440 EGT = 12 * etu + (f / d) * TC1 / clock_frequency;
1441
1442 /* card BWT */
1443 /* see ch. 9.5.3.2 Block Waiting Time, page 20 of ISO 7816-3 */
1444 BWT = 11 * etu + (1<<BWI) * 960 * 372 / clock_frequency;
1445
1446 /* card CWT */
1447 /* see ch. 9.5.3.1 Caracter Waiting Time, page 20 of ISO 7816-3 */
1448 CWT = (11 + (1<<CWI)) * etu;
1449
1450 timeout = 260*EGT + BWT + 260*CWT;
1451
1452 /* Convert from milliseonds to seconds rounded to the upper value
1453 * we use +1 instead of ceil() to round up to the nearest greater interger
1454 * so we can avoid a dependency on the math library */
1455 timeout = timeout/1000 +1;
1456
1457 return timeout;
1458 } /* T1_card_timeout */
1459

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5