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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5