/[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 2176 - (show annotations) (download)
Tue Sep 26 13:32:05 2006 UTC (6 years, 8 months ago) by rousseau
File MIME type: text/plain
File size: 40001 byte(s)
IFDHICCPresence(): the patch in revision 2150 was not correct.
SCardReconnect(..., SCARD_UNPOWER_CARD, ...) failed since the
card was reported as non present after the power off
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 char *actions[] = { "PowerUp", "PowerDown", "Reset" };
822
823 DEBUG_INFO3("lun: %X, action: %s", Lun, actions[Action-IFD_POWER_UP]);
824
825 /* By default, assume it won't work :) */
826 *AtrLength = 0;
827
828 if (-1 == (reader_index = LunToReaderIndex(Lun)))
829 return IFD_COMMUNICATION_ERROR;
830
831 switch (Action)
832 {
833 case IFD_POWER_DOWN:
834 /* Clear ATR buffer */
835 CcidSlots[reader_index].nATRLength = 0;
836 *CcidSlots[reader_index].pcATRBuffer = '\0';
837
838 /* Memorise the request */
839 CcidSlots[reader_index].bPowerFlags |= MASK_POWERFLAGS_PDWN;
840
841 /* send the command */
842 if (IFD_SUCCESS != CmdPowerOff(reader_index))
843 {
844 DEBUG_CRITICAL("PowerDown failed");
845 return_value = IFD_ERROR_POWER_ACTION;
846 goto end;
847 }
848
849 /* clear T=1 context */
850 t1_release(&(get_ccid_slot(reader_index) -> t1));
851 break;
852
853 case IFD_POWER_UP:
854 case IFD_RESET:
855 nlength = sizeof(pcbuffer);
856 if (CmdPowerOn(reader_index, &nlength, pcbuffer, PowerOnVoltage)
857 != IFD_SUCCESS)
858 {
859 DEBUG_CRITICAL("PowerUp failed");
860 return_value = IFD_ERROR_POWER_ACTION;
861 goto end;
862 }
863
864 /* Power up successful, set state variable to memorise it */
865 CcidSlots[reader_index].bPowerFlags |= MASK_POWERFLAGS_PUP;
866 CcidSlots[reader_index].bPowerFlags &= ~MASK_POWERFLAGS_PDWN;
867
868 /* Reset is returned, even if TCK is wrong */
869 CcidSlots[reader_index].nATRLength = *AtrLength =
870 (nlength < MAX_ATR_SIZE) ? nlength : MAX_ATR_SIZE;
871 memcpy(Atr, pcbuffer, *AtrLength);
872 memcpy(CcidSlots[reader_index].pcATRBuffer, pcbuffer, *AtrLength);
873
874 /* initialise T=1 context */
875 t1_init(&(get_ccid_slot(reader_index) -> t1), reader_index);
876 break;
877
878 default:
879 DEBUG_CRITICAL("Action not supported");
880 return_value = IFD_NOT_SUPPORTED;
881 }
882 end:
883
884 return return_value;
885 } /* IFDHPowerICC */
886
887
888 EXTERNAL RESPONSECODE IFDHTransmitToICC(DWORD Lun, SCARD_IO_HEADER SendPci,
889 PUCHAR TxBuffer, DWORD TxLength,
890 PUCHAR RxBuffer, PDWORD RxLength, /*@unused@*/ PSCARD_IO_HEADER RecvPci)
891 {
892 /*
893 * This function performs an APDU exchange with the card/slot
894 * specified by Lun. The driver is responsible for performing any
895 * protocol specific exchanges such as T=0/1 ... differences. Calling
896 * this function will abstract all protocol differences.
897 *
898 * SendPci Protocol - 0, 1, .... 14 Length - Not used.
899 *
900 * TxBuffer - Transmit APDU example (0x00 0xA4 0x00 0x00 0x02 0x3F
901 * 0x00) TxLength - Length of this buffer. RxBuffer - Receive APDU
902 * example (0x61 0x14) RxLength - Length of the received APDU. This
903 * function will be passed the size of the buffer of RxBuffer and this
904 * function is responsible for setting this to the length of the
905 * received APDU. This should be ZERO on all errors. The resource
906 * manager will take responsibility of zeroing out any temporary APDU
907 * buffers for security reasons.
908 *
909 * RecvPci Protocol - 0, 1, .... 14 Length - Not used.
910 *
911 * Notes: The driver is responsible for knowing what type of card it
912 * has. If the current slot/card contains a memory card then this
913 * command should ignore the Protocol and use the MCT style commands
914 * for support for these style cards and transmit them appropriately.
915 * If your reader does not support memory cards or you don't want to
916 * then ignore this.
917 *
918 * RxLength should be set to zero on error.
919 *
920 * returns:
921 *
922 * IFD_SUCCESS IFD_COMMUNICATION_ERROR IFD_RESPONSE_TIMEOUT
923 * IFD_ICC_NOT_PRESENT IFD_PROTOCOL_NOT_SUPPORTED
924 */
925
926 RESPONSECODE return_value;
927 unsigned int rx_length;
928 int reader_index;
929
930 DEBUG_INFO2("lun: %X", Lun);
931
932 if (-1 == (reader_index = LunToReaderIndex(Lun)))
933 return IFD_COMMUNICATION_ERROR;
934
935 rx_length = *RxLength;
936 return_value = CmdXfrBlock(reader_index, TxLength, TxBuffer, &rx_length,
937 RxBuffer, SendPci.Protocol);
938 *RxLength = rx_length;
939
940 return return_value;
941 } /* IFDHTransmitToICC */
942
943
944 EXTERNAL RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode,
945 PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength,
946 PDWORD pdwBytesReturned)
947 {
948 /*
949 * This function performs a data exchange with the reader (not the
950 * card) specified by Lun. Here XXXX will only be used. It is
951 * responsible for abstracting functionality such as PIN pads,
952 * biometrics, LCD panels, etc. You should follow the MCT, CTBCS
953 * specifications for a list of accepted commands to implement.
954 *
955 * TxBuffer - Transmit data TxLength - Length of this buffer. RxBuffer
956 * - Receive data RxLength - Length of the received data. This
957 * function will be passed the length of the buffer RxBuffer and it
958 * must set this to the length of the received data.
959 *
960 * Notes: RxLength should be zero on error.
961 */
962 RESPONSECODE return_value = IFD_COMMUNICATION_ERROR;
963 int reader_index;
964
965 DEBUG_INFO3("lun: %X, ControlCode: 0x%X", Lun, dwControlCode);
966
967 reader_index = LunToReaderIndex(Lun);
968 if ((-1 == reader_index) || (NULL == pdwBytesReturned))
969 return return_value;
970
971 /* Set the return length to 0 to avoid problems */
972 *pdwBytesReturned = 0;
973
974 if (IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE == dwControlCode)
975 {
976 if (FALSE == (DriverOptions & DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED))
977 {
978 DEBUG_INFO("ifd exchange (Escape command) not allowed");
979 return_value = IFD_COMMUNICATION_ERROR;
980 }
981 else
982 {
983 unsigned int iBytesReturned;
984
985 iBytesReturned = RxLength;
986 return_value = CmdEscape(reader_index, TxBuffer, TxLength, RxBuffer,
987 &iBytesReturned);
988 *pdwBytesReturned = iBytesReturned;
989 }
990 }
991
992 /* Implement the PC/SC v2.1.2 Part 10 IOCTL mechanism */
993
994 /* Query for features */
995 if (CM_IOCTL_GET_FEATURE_REQUEST == dwControlCode)
996 {
997 unsigned int iBytesReturned = 0;
998 PCSC_TLV_STRUCTURE *pcsc_tlv = (PCSC_TLV_STRUCTURE *)RxBuffer;
999
1000 /* we need room for two records */
1001 if (RxLength < 2 * sizeof(PCSC_TLV_STRUCTURE))
1002 return IFD_COMMUNICATION_ERROR;
1003
1004 /* We can only support direct verify and/or modify currently */
1005 if (get_ccid_descriptor(reader_index) -> bPINSupport
1006 & CCID_CLASS_PIN_VERIFY)
1007 {
1008 pcsc_tlv -> tag = FEATURE_VERIFY_PIN_DIRECT;
1009 pcsc_tlv -> length = 0x04; /* always 0x04 */
1010 pcsc_tlv -> value = htonl(IOCTL_FEATURE_VERIFY_PIN_DIRECT);
1011
1012 pcsc_tlv++;
1013 iBytesReturned += sizeof(PCSC_TLV_STRUCTURE);
1014 }
1015
1016 if (get_ccid_descriptor(reader_index) -> bPINSupport
1017 & CCID_CLASS_PIN_MODIFY)
1018 {
1019 pcsc_tlv -> tag = FEATURE_MODIFY_PIN_DIRECT;
1020 pcsc_tlv -> length = 0x04; /* always 0x04 */
1021 pcsc_tlv -> value = htonl(IOCTL_FEATURE_MODIFY_PIN_DIRECT);
1022
1023 pcsc_tlv++;
1024 iBytesReturned += sizeof(PCSC_TLV_STRUCTURE);
1025 }
1026 *pdwBytesReturned = iBytesReturned;
1027 return_value = IFD_SUCCESS;
1028 }
1029
1030 /* Verify a PIN, plain CCID */
1031 if (IOCTL_FEATURE_VERIFY_PIN_DIRECT == dwControlCode)
1032 {
1033 unsigned int iBytesReturned;
1034
1035 iBytesReturned = RxLength;
1036 return_value = SecurePINVerify(reader_index, TxBuffer, TxLength,
1037 RxBuffer, &iBytesReturned);
1038 *pdwBytesReturned = iBytesReturned;
1039 }
1040
1041 /* Modify a PIN, plain CCID */
1042 if (IOCTL_FEATURE_MODIFY_PIN_DIRECT == dwControlCode)
1043 {
1044 unsigned int iBytesReturned;
1045
1046 iBytesReturned = RxLength;
1047 return_value = SecurePINModify(reader_index, TxBuffer, TxLength,
1048 RxBuffer, &iBytesReturned);
1049 *pdwBytesReturned = iBytesReturned;
1050 }
1051
1052 return return_value;
1053 } /* IFDHControl */
1054
1055
1056 EXTERNAL RESPONSECODE IFDHICCPresence(DWORD Lun)
1057 {
1058 /*
1059 * This function returns the status of the card inserted in the
1060 * reader/slot specified by Lun. It will return either:
1061 *
1062 * returns: IFD_ICC_PRESENT IFD_ICC_NOT_PRESENT
1063 * IFD_COMMUNICATION_ERROR
1064 */
1065
1066 unsigned char pcbuffer[SIZE_GET_SLOT_STATUS];
1067 RESPONSECODE return_value = IFD_COMMUNICATION_ERROR;
1068 int oldLogLevel;
1069 int reader_index;
1070 _ccid_descriptor *ccid_descriptor;
1071 unsigned int oldReadTimeout;
1072
1073 DEBUG_PERIODIC2("lun: %X", Lun);
1074
1075 if (-1 == (reader_index = LunToReaderIndex(Lun)))
1076 return IFD_COMMUNICATION_ERROR;
1077
1078 ccid_descriptor = get_ccid_descriptor(reader_index);
1079
1080 /* save the current read timeout computed from card capabilities */
1081 oldReadTimeout = ccid_descriptor->readTimeout;
1082
1083 /* use default timeout since the reader may not be present anymore */
1084 ccid_descriptor->readTimeout = DEFAULT_COM_READ_TIMEOUT;
1085
1086 /* if DEBUG_LEVEL_PERIODIC is not set we remove DEBUG_LEVEL_COMM */
1087 oldLogLevel = LogLevel;
1088 if (! (LogLevel & DEBUG_LEVEL_PERIODIC))
1089 LogLevel &= ~DEBUG_LEVEL_COMM;
1090
1091 return_value = CmdGetSlotStatus(reader_index, pcbuffer);
1092
1093 /* set back the old timeout */
1094 ccid_descriptor->readTimeout = oldReadTimeout;
1095
1096 /* set back the old LogLevel */
1097 LogLevel = oldLogLevel;
1098
1099 if (return_value != IFD_SUCCESS)
1100 return IFD_COMMUNICATION_ERROR;
1101
1102 return_value = IFD_COMMUNICATION_ERROR;
1103 switch (pcbuffer[7] & CCID_ICC_STATUS_MASK) /* bStatus */
1104 {
1105 case CCID_ICC_PRESENT_ACTIVE:
1106 return_value = IFD_ICC_PRESENT;
1107 /* use default slot */
1108 break;
1109
1110 case CCID_ICC_PRESENT_INACTIVE:
1111 if ((CcidSlots[reader_index].bPowerFlags == POWERFLAGS_RAZ)
1112 || (CcidSlots[reader_index].bPowerFlags & MASK_POWERFLAGS_PDWN))
1113 /* the card was previously absent */
1114 return_value = IFD_ICC_PRESENT;
1115 else
1116 {
1117 /* the card was previously present but has been
1118 * removed and inserted between two consecutive
1119 * IFDHICCPresence() calls */
1120 CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
1121 return_value = IFD_ICC_NOT_PRESENT;
1122 }
1123 break;
1124
1125 case CCID_ICC_ABSENT:
1126 /* Reset ATR buffer */
1127 CcidSlots[reader_index].nATRLength = 0;
1128 *CcidSlots[reader_index].pcATRBuffer = '\0';
1129
1130 /* Reset PowerFlags */
1131 CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
1132
1133 return_value = IFD_ICC_NOT_PRESENT;
1134 break;
1135 }
1136
1137 /* SCR331-DI contactless reader */
1138 if (((SCR331DI == ccid_descriptor->readerID)
1139 || (SDI010 == ccid_descriptor->readerID)
1140 || (SCR331DINTTCOM == ccid_descriptor->readerID))
1141 && (ccid_descriptor->bCurrentSlotIndex > 0))
1142 {
1143 unsigned char cmd[] = { 0x11 };
1144 /* command: 11 ??
1145 * response: 00 11 01 ?? no card
1146 * 01 04 00 ?? card present */
1147
1148 unsigned char res[10];
1149 unsigned int length_res = sizeof(res);
1150 RESPONSECODE ret;
1151
1152 /* if DEBUG_LEVEL_PERIODIC is not set we remove DEBUG_LEVEL_COMM */
1153 oldLogLevel = LogLevel;
1154 if (! (LogLevel & DEBUG_LEVEL_PERIODIC))
1155 LogLevel &= ~DEBUG_LEVEL_COMM;
1156
1157 ret = CmdEscape(reader_index, cmd, sizeof(cmd), res, &length_res);
1158
1159 /* set back the old LogLevel */
1160 LogLevel = oldLogLevel;
1161
1162 if (ret != IFD_SUCCESS)
1163 {
1164 DEBUG_INFO("CmdEscape failed");
1165 /* simulate a card absent */
1166 res[0] = 0;
1167 }
1168
1169 if (0x01 == res[0])
1170 return_value = IFD_ICC_PRESENT;
1171 else
1172 {
1173 /* Reset ATR buffer */
1174 CcidSlots[reader_index].nATRLength = 0;
1175 *CcidSlots[reader_index].pcATRBuffer = '\0';
1176
1177 /* Reset PowerFlags */
1178 CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ;
1179
1180 return_value = IFD_ICC_NOT_PRESENT;
1181 }
1182 }
1183
1184 DEBUG_PERIODIC2("Card %s",
1185 IFD_ICC_PRESENT == return_value ? "present" : "absent");
1186
1187 return return_value;
1188 } /* IFDHICCPresence */
1189
1190
1191 CcidDesc *get_ccid_slot(unsigned int reader_index)
1192 {
1193 return &CcidSlots[reader_index];
1194 } /* get_ccid_slot */
1195
1196
1197 void init_driver(void)
1198 {
1199 char keyValue[TOKEN_MAX_VALUE_SIZE];
1200 char infofile[FILENAME_MAX];
1201
1202 /* Info.plist full patch filename */
1203 snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
1204 PCSCLITE_HP_DROPDIR, BUNDLE);
1205
1206 /* Log level */
1207 if (0 == LTPBundleFindValueWithKey(infofile, "ifdLogLevel", keyValue, 0))
1208 {
1209 /* convert from hex or dec or octal */
1210 LogLevel = strtoul(keyValue, NULL, 0);
1211
1212 /* print the log level used */
1213 DEBUG_INFO2("LogLevel: 0x%.4X", LogLevel);
1214 }
1215
1216 /* Driver options */
1217 if (0 == LTPBundleFindValueWithKey(infofile, "ifdDriverOptions", keyValue, 0))
1218 {
1219 /* convert from hex or dec or octal */
1220 DriverOptions = strtoul(keyValue, NULL, 0);
1221
1222 /* print the log level used */
1223 DEBUG_INFO2("DriverOptions: 0x%.4X", DriverOptions);
1224 }
1225
1226 /* get the voltage parameter */
1227 switch ((DriverOptions >> 4) & 0x03)
1228 {
1229 case 0:
1230 PowerOnVoltage = VOLTAGE_5V;
1231 break;
1232
1233 case 1:
1234 PowerOnVoltage = VOLTAGE_3V;
1235 break;
1236
1237 case 2:
1238 PowerOnVoltage = VOLTAGE_1_8V;
1239 break;
1240
1241 case 3:
1242 PowerOnVoltage = VOLTAGE_AUTO;
1243 break;
1244 }
1245
1246 /* initialise the Lun to reader_index mapping */
1247 InitReaderIndex();
1248
1249 DebugInitialized = TRUE;
1250 } /* init_driver */
1251
1252
1253 void extra_egt(ATR_t *atr, _ccid_descriptor *ccid_desc, DWORD Protocol)
1254 {
1255 /* This function use an EGT value for cards who comply with followings
1256 * criterias:
1257 * - TA1 > 11
1258 * - current EGT = 0x00 or 0xFF
1259 * - T=0 or (T=1 and CWI >= 2)
1260 *
1261 * Without this larger EGT some non ISO 7816-3 smart cards may not
1262 * communicate with the reader.
1263 *
1264 * This modification is harmless, the reader will just be less restrictive
1265 */
1266
1267 unsigned int card_baudrate;
1268 unsigned int default_baudrate;
1269 double f, d;
1270 int i;
1271
1272 /* if TA1 not present */
1273 if (! atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
1274 return;
1275
1276 ATR_GetParameter(atr, ATR_PARAMETER_D, &d);
1277 ATR_GetParameter(atr, ATR_PARAMETER_F, &f);
1278
1279 /* may happen with non ISO cards */
1280 if ((0 == f) || (0 == d))
1281 return;
1282
1283 /* Baudrate = f x D/F */
1284 card_baudrate = (unsigned int) (1000 * ccid_desc->dwDefaultClock * d / f);
1285
1286 default_baudrate = (unsigned int) (1000 * ccid_desc->dwDefaultClock
1287 * ATR_DEFAULT_D / ATR_DEFAULT_F);
1288
1289 /* TA1 > 11? */
1290 if (card_baudrate <= default_baudrate)
1291 return;
1292
1293 /* Current EGT = 0 or FF? */
1294 if (atr->ib[0][ATR_INTERFACE_BYTE_TC].present &&
1295 ((0x00 == atr->ib[0][ATR_INTERFACE_BYTE_TC].value) ||
1296 (0xFF == atr->ib[0][ATR_INTERFACE_BYTE_TC].value)))
1297 {
1298 if (SCARD_PROTOCOL_T0 == Protocol)
1299 {
1300 /* Init TC1 */
1301 atr->ib[0][ATR_INTERFACE_BYTE_TC].present = TRUE;
1302 atr->ib[0][ATR_INTERFACE_BYTE_TC].value = 2;
1303 DEBUG_INFO("Extra EGT patch applied");
1304 }
1305
1306 if (SCARD_PROTOCOL_T1 == Protocol)
1307 {
1308 /* TBi (i>2) present? BWI/CWI */
1309 for (i=2; i<ATR_MAX_PROTOCOLS; i++)
1310 {
1311 /* CWI >= 2 ? */
1312 if (atr->ib[i][ATR_INTERFACE_BYTE_TB].present &&
1313 ((atr->ib[i][ATR_INTERFACE_BYTE_TB].value & 0x0F) >= 2))
1314 {
1315 /* Init TC1 */
1316 atr->ib[0][ATR_INTERFACE_BYTE_TC].present = TRUE;
1317 atr->ib[0][ATR_INTERFACE_BYTE_TC].value = 2;
1318 DEBUG_INFO("Extra EGT patch applied");
1319
1320 /* only the first TBi (i>2) must be used */
1321 break;
1322 }
1323 }
1324 }
1325 }
1326 } /* extra_egt */
1327
1328
1329 static char find_baud_rate(unsigned int baudrate, unsigned int *list)
1330 {
1331 int i;
1332
1333 DEBUG_COMM2("Card baud rate: %d", baudrate);
1334
1335 /* Does the reader support the announced smart card data speed? */
1336 for (i=0;; i++)
1337 {
1338 /* end of array marker */
1339 if (0 == list[i])
1340 break;
1341
1342 DEBUG_COMM2("Reader can do: %d", list[i]);
1343
1344 /* We must take into account that the card_baudrate integral value
1345 * is an approximative result, computed from the d/f float result.
1346 */
1347 if ((baudrate < list[i] + 2) && (baudrate > list[i] - 2))
1348 return TRUE;
1349 }
1350
1351 return FALSE;
1352 } /* find_baud_rate */
1353
1354
1355 static unsigned int T0_card_timeout(double f, double d, int TC1, int TC2,
1356 int clock_frequency)
1357 {
1358 unsigned int timeout = DEFAULT_COM_READ_TIMEOUT;
1359 double EGT, WWT;
1360 unsigned int t;
1361
1362 /* Timeout applied on ISO_IN or ISO_OUT card exchange
1363 * we choose the maximum computed value.
1364 *
1365 * ISO_IN timeout is the sum of:
1366 * Terminal: Smart card:
1367 * 5 bytes header cmd ->
1368 * <- Procedure byte
1369 * 256 data bytes ->
1370 * <- SW1-SW2
1371 * = 261 EGT + 3 WWT + 3 WWT
1372 *
1373 * ISO_OUT Timeout is the sum of:
1374 * Terminal: Smart card:
1375 * 5 bytes header cmd ->
1376 * <- Procedure byte + 256 data bytes + SW1-SW2
1377 * = 5 EGT + 1 WWT + 259 WWT
1378 */
1379
1380 /* clock_frequency is in kHz so the times are in milliseconds and not
1381 * in seconds */
1382
1383 /* may happen with non ISO cards */
1384 if ((0 == f) || (0 == d) || (0 == clock_frequency))
1385 return 60; /* 60 seconds */
1386
1387 /* EGT */
1388 /* see ch. 6.5.3 Extra Guard Time, page 12 of ISO 7816-3 */
1389 EGT = 12 * f / d / clock_frequency + (f / d) * TC1 / clock_frequency;
1390
1391 /* card WWT */
1392 /* see ch. 8.2 Character level, page 15 of ISO 7816-3 */
1393 WWT = 960 * TC2 * f / clock_frequency;
1394
1395 /* ISO in */
1396 t = 261 * EGT + (3 + 3) * WWT;
1397 /* Convert from milliseonds to seconds rouned to the upper value
1398 * use +1 instead of ceil() to round up to the nearest interger
1399 * so we can avoid a dependency on the math library */
1400 t = t/1000 +1;
1401 if (timeout < t)
1402 timeout = t;
1403
1404 /* ISO out */
1405 t = 5 * EGT + (1 + 259) * WWT;
1406 t = t/1000 +1;
1407 if (timeout < t)
1408 timeout = t;
1409
1410 return timeout;
1411 } /* T0_card_timeout */
1412
1413
1414 static unsigned int T1_card_timeout(double f, double d, int TC1,
1415 int BWI, int CWI, int clock_frequency)
1416 {
1417 double EGT, BWT, CWT, etu;
1418 unsigned int timeout;
1419
1420 /* Timeout applied on ISO in + ISO out card exchange
1421 *
1422 * Timeout is the sum of:
1423 * - ISO in delay between leading edge of the first character sent by the
1424 * interface device and the last one (NAD PCB LN APDU CKS) = 260 EGT,
1425 * - delay between ISO in and ISO out = BWT,
1426 * - ISO out delay between leading edge of the first character sent by the
1427 * card and the last one (NAD PCB LN DATAS CKS) = 260 CWT.
1428 */
1429
1430 /* clock_frequency is in kHz so the times are in milliseconds and not
1431 * in seconds */
1432
1433 /* may happen with non ISO cards */
1434 if ((0 == f) || (0 == d) || (0 == clock_frequency))
1435 return 60; /* 60 seconds */
1436
1437 /* see ch. 6.5.2 Transmission factors F and D, page 12 of ISO 7816-3 */
1438 etu = f / d / clock_frequency;
1439
1440 /* EGT */
1441 /* see ch. 6.5.3 Extra Guard Time, page 12 of ISO 7816-3 */
1442 EGT = 12 * etu + (f / d) * TC1 / clock_frequency;
1443
1444 /* card BWT */
1445 /* see ch. 9.5.3.2 Block Waiting Time, page 20 of ISO 7816-3 */
1446 BWT = 11 * etu + (1<<BWI) * 960 * 372 / clock_frequency;
1447
1448 /* card CWT */
1449 /* see ch. 9.5.3.1 Caracter Waiting Time, page 20 of ISO 7816-3 */
1450 CWT = (11 + (1<<CWI)) * etu;
1451
1452 timeout = 260*EGT + BWT + 260*CWT;
1453
1454 /* Convert from milliseonds to seconds rounded to the upper value
1455 * we use +1 instead of ceil() to round up to the nearest greater interger
1456 * so we can avoid a dependency on the math library */
1457 timeout = timeout/1000 +1;
1458
1459 return timeout;
1460 } /* T1_card_timeout */
1461

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5