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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5