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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5