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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5