/[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 804 - (hide annotations) (download)
Mon Apr 19 16:09:24 2004 UTC (9 years, 1 month ago) by rousseau
File MIME type: text/plain
File size: 19444 byte(s)
add SCARD_ATTR_ATR_STRING in addition to TAG_IFD_ATR in IFDHGetCapabilities()
1 rousseau 269 /*
2     ifdhandler.c: IFDH API
3     Copyright (C) 2003 Ludovic Rousseau
4    
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9    
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     GNU General Public License for more details.
14    
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18     */
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 269
26     #include "pcscdefines.h"
27 rousseau 611 #include "defs.h"
28 rousseau 269 #include "ifdhandler.h"
29     #include "config.h"
30     #include "debug.h"
31     #include "utils.h"
32     #include "commands.h"
33 rousseau 616 #include "ccid.h"
34 rousseau 673 #include "protocol_t1/atr.h"
35     #include "protocol_t1/pps.h"
36 rousseau 687 #include "protocol_t1/protocol_t1.h"
37 rousseau 773 #include "parser.h"
38 rousseau 804 #include "winsmcrd.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     static CcidDesc CcidSlots[PCSCLITE_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 773 static int DebugInitialized = FALSE;
53     int LogLevel = DEBUG_LEVEL_CRITICAL | DEBUG_LEVEL_INFO;
54 rousseau 463
55 rousseau 773 static void init_debug(void);
56    
57    
58 rousseau 649 RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPSTR lpcDevice)
59     {
60 rousseau 770 RESPONSECODE return_value = IFD_SUCCESS;
61    
62 rousseau 773 if (! DebugInitialized)
63     init_debug();
64    
65 rousseau 649 DEBUG_INFO3("lun: %X, device: %s", Lun, lpcDevice);
66    
67     if (CheckLun(Lun))
68     return IFD_COMMUNICATION_ERROR;
69    
70     // Reset ATR buffer
71     CcidSlots[LunToReaderIndex(Lun)].nATRLength = 0;
72     *CcidSlots[LunToReaderIndex(Lun)].pcATRBuffer = '\0';
73    
74     // Reset PowerFlags
75     CcidSlots[LunToReaderIndex(Lun)].bPowerFlags = POWERFLAGS_RAZ;
76    
77     #ifdef HAVE_PTHREAD
78     pthread_mutex_lock(&ifdh_context_mutex);
79     #endif
80    
81     if (OpenPortByName(Lun, lpcDevice) != STATUS_SUCCESS)
82     {
83 rousseau 663 DEBUG_CRITICAL("failed");
84 rousseau 770 return_value = IFD_COMMUNICATION_ERROR;
85 rousseau 649 }
86    
87 rousseau 769 /* Maybe we have a special treatment for this reader */
88     ccid_open_hack(Lun);
89    
90 rousseau 649 #ifdef HAVE_PTHREAD
91     pthread_mutex_unlock(&ifdh_context_mutex);
92     #endif
93    
94 rousseau 770 return return_value;
95 rousseau 649 } /* IFDHCreateChannelByName */
96    
97    
98 rousseau 269 RESPONSECODE IFDHCreateChannel(DWORD Lun, DWORD Channel)
99     {
100     /*
101     * Lun - Logical Unit Number, use this for multiple card slots or
102     * multiple readers. 0xXXXXYYYY - XXXX multiple readers, YYYY multiple
103     * slots. The resource manager will set these automatically. By
104     * default the resource manager loads a new instance of the driver so
105     * if your reader does not have more than one smartcard slot then
106     * ignore the Lun in all the functions. Future versions of PC/SC might
107     * support loading multiple readers through one instance of the driver
108     * in which XXXX would be important to implement if you want this.
109     */
110    
111     /*
112     * Channel - Channel ID. This is denoted by the following: 0x000001 -
113     * /dev/pcsc/1 0x000002 - /dev/pcsc/2 0x000003 - /dev/pcsc/3
114     *
115     * USB readers may choose to ignore this parameter and query the bus
116     * for the particular reader.
117     */
118    
119     /*
120     * This function is required to open a communications channel to the
121     * port listed by Channel. For example, the first serial reader on
122     * COM1 would link to /dev/pcsc/1 which would be a sym link to
123     * /dev/ttyS0 on some machines This is used to help with intermachine
124     * independance.
125     *
126     * Once the channel is opened the reader must be in a state in which
127     * it is possible to query IFDHICCPresence() for card status.
128     *
129     * returns:
130     *
131     * IFD_SUCCESS IFD_COMMUNICATION_ERROR
132     */
133     RESPONSECODE return_value = IFD_SUCCESS;
134    
135 rousseau 773 if (! DebugInitialized)
136     init_debug();
137    
138 rousseau 608 DEBUG_INFO2("lun: %X", Lun);
139 rousseau 269
140     if (CheckLun(Lun))
141     return IFD_COMMUNICATION_ERROR;
142    
143 rousseau 410 /* Reset ATR buffer */
144 rousseau 269 CcidSlots[LunToReaderIndex(Lun)].nATRLength = 0;
145     *CcidSlots[LunToReaderIndex(Lun)].pcATRBuffer = '\0';
146    
147 rousseau 410 /* Reset PowerFlags */
148 rousseau 269 CcidSlots[LunToReaderIndex(Lun)].bPowerFlags = POWERFLAGS_RAZ;
149    
150 rousseau 563 #ifdef HAVE_PTHREAD
151 rousseau 463 pthread_mutex_lock(&ifdh_context_mutex);
152     #endif
153    
154 rousseau 410 if (OpenPort(Lun, Channel) != STATUS_SUCCESS)
155 rousseau 269 {
156 rousseau 663 DEBUG_CRITICAL("failed");
157 rousseau 269 return_value = IFD_COMMUNICATION_ERROR;
158     }
159    
160 rousseau 612 /* Maybe we have a special treatment for this reader */
161     ccid_open_hack(Lun);
162    
163 rousseau 563 #ifdef HAVE_PTHREAD
164 rousseau 463 pthread_mutex_unlock(&ifdh_context_mutex);
165     #endif
166    
167 rousseau 269 return return_value;
168     } /* IFDHCreateChannel */
169    
170    
171     RESPONSECODE IFDHCloseChannel(DWORD Lun)
172     {
173     /*
174     * This function should close the reader communication channel for the
175     * particular reader. Prior to closing the communication channel the
176     * reader should make sure the card is powered down and the terminal
177     * is also powered down.
178     *
179     * returns:
180     *
181     * IFD_SUCCESS IFD_COMMUNICATION_ERROR
182     */
183    
184 rousseau 608 DEBUG_INFO2("lun: %X", Lun);
185 rousseau 269
186     if (CheckLun(Lun))
187     return IFD_COMMUNICATION_ERROR;
188    
189     CmdPowerOff(Lun);
190 rousseau 410 /* No reader status check, if it failed, what can you do ? :) */
191 rousseau 269
192 rousseau 563 #ifdef HAVE_PTHREAD
193 rousseau 463 pthread_mutex_lock(&ifdh_context_mutex);
194     #endif
195    
196 rousseau 410 ClosePort(Lun);
197 rousseau 269
198 rousseau 563 #ifdef HAVE_PTHREAD
199 rousseau 463 pthread_mutex_unlock(&ifdh_context_mutex);
200     #endif
201    
202 rousseau 269 return IFD_SUCCESS;
203     } /* IFDHCloseChannel */
204    
205    
206     RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag,
207     PDWORD Length, PUCHAR Value)
208     {
209     /*
210     * This function should get the slot/card capabilities for a
211     * particular slot/card specified by Lun. Again, if you have only 1
212     * card slot and don't mind loading a new driver for each reader then
213     * ignore Lun.
214     *
215     * Tag - the tag for the information requested example: TAG_IFD_ATR -
216     * return the Atr and it's size (required). these tags are defined in
217     * ifdhandler.h
218     *
219     * Length - the length of the returned data Value - the value of the
220     * data
221     *
222     * returns:
223     *
224     * IFD_SUCCESS IFD_ERROR_TAG
225     */
226    
227 rousseau 804 DEBUG_INFO3("lun: %X, tag: 0x%X", Lun, Tag);
228 rousseau 269
229     if (CheckLun(Lun))
230     return IFD_COMMUNICATION_ERROR;
231    
232     switch (Tag)
233     {
234     case TAG_IFD_ATR:
235 rousseau 804 case SCARD_ATTR_ATR_STRING:
236 rousseau 410 /* If Length is not zero, powerICC has been performed.
237     * Otherwise, return NULL pointer
238     * Buffer size is stored in *Length */
239 rousseau 804 *Length = (*Length < CcidSlots[LunToReaderIndex(Lun)].nATRLength) ?
240     *Length : CcidSlots[LunToReaderIndex(Lun)].nATRLength;
241 rousseau 269
242     if (*Length)
243     memcpy(Value, CcidSlots[LunToReaderIndex(Lun)]
244     .pcATRBuffer, *Length);
245     break;
246    
247 rousseau 563 #ifdef HAVE_PTHREAD
248 rousseau 269 case TAG_IFD_SIMULTANEOUS_ACCESS:
249     if (*Length >= 1)
250     {
251     *Length = 1;
252 rousseau 410 *Value = PCSCLITE_MAX_READERS;
253 rousseau 269 }
254     break;
255    
256 rousseau 463 case TAG_IFD_THREAD_SAFE:
257     if (*Length >= 1)
258     {
259     *Length = 1;
260     *Value = 1; /* Can talk to multiple readers at the same time */
261     }
262     break;
263 rousseau 563 #endif
264 rousseau 463
265 rousseau 269 case TAG_IFD_SLOTS_NUMBER:
266     if (*Length >= 1)
267     {
268     *Length = 1;
269     *Value = 1; /* One slot only */
270     }
271     break;
272    
273     default:
274     return IFD_ERROR_TAG;
275     }
276 rousseau 569
277 rousseau 269 return IFD_SUCCESS;
278     } /* IFDHGetCapabilities */
279    
280    
281     RESPONSECODE IFDHSetCapabilities(DWORD Lun, DWORD Tag,
282     DWORD Length, PUCHAR Value)
283     {
284     /*
285     * This function should set the slot/card capabilities for a
286     * particular slot/card specified by Lun. Again, if you have only 1
287     * card slot and don't mind loading a new driver for each reader then
288     * ignore Lun.
289     *
290     * Tag - the tag for the information needing set
291     *
292     * Length - the length of the returned data Value - the value of the
293     * data
294     *
295     * returns:
296     *
297     * IFD_SUCCESS IFD_ERROR_TAG IFD_ERROR_SET_FAILURE
298     * IFD_ERROR_VALUE_READ_ONLY
299     */
300    
301 rousseau 410 /* By default, say it worked */
302 rousseau 269
303 rousseau 804 DEBUG_INFO3("lun: %X, tag: 0x%X", Lun, Tag);
304 rousseau 269
305     /* if (CheckLun(Lun))
306     return IFD_COMMUNICATION_ERROR; */
307    
308 rousseau 569 return IFD_NOT_SUPPORTED;
309 rousseau 269 } /* IFDHSetCapabilities */
310    
311    
312     RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol,
313     UCHAR Flags, UCHAR PTS1, UCHAR PTS2, UCHAR PTS3)
314     {
315     /*
316     * This function should set the PTS of a particular card/slot using
317     * the three PTS parameters sent
318     *
319     * Protocol - 0 .... 14 T=0 .... T=14 Flags - Logical OR of possible
320     * values: IFD_NEGOTIATE_PTS1 IFD_NEGOTIATE_PTS2 IFD_NEGOTIATE_PTS3 to
321     * determine which PTS values to negotiate. PTS1,PTS2,PTS3 - PTS
322     * Values.
323     *
324     * returns:
325     *
326     * IFD_SUCCESS IFD_ERROR_PTS_FAILURE IFD_COMMUNICATION_ERROR
327     * IFD_PROTOCOL_NOT_SUPPORTED
328     */
329    
330 rousseau 608 DEBUG_INFO2("lun: %X", Lun);
331 rousseau 269
332     /* if (CheckLun(Lun))
333     return IFD_COMMUNICATION_ERROR; */
334    
335 rousseau 569 return IFD_NOT_SUPPORTED;
336 rousseau 269 } /* IFDHSetProtocolParameters */
337    
338    
339     RESPONSECODE IFDHPowerICC(DWORD Lun, DWORD Action,
340     PUCHAR Atr, PDWORD AtrLength)
341     {
342     /*
343     * This function controls the power and reset signals of the smartcard
344     * reader at the particular reader/slot specified by Lun.
345     *
346     * Action - Action to be taken on the card.
347     *
348     * IFD_POWER_UP - Power and reset the card if not done so (store the
349     * ATR and return it and it's length).
350     *
351     * IFD_POWER_DOWN - Power down the card if not done already
352     * (Atr/AtrLength should be zero'd)
353     *
354     * IFD_RESET - Perform a quick reset on the card. If the card is not
355     * powered power up the card. (Store and return the Atr/Length)
356     *
357     * Atr - Answer to Reset of the card. The driver is responsible for
358     * caching this value in case IFDHGetCapabilities is called requesting
359     * the ATR and it's length. This should not exceed MAX_ATR_SIZE.
360     *
361     * AtrLength - Length of the Atr. This should not exceed
362     * MAX_ATR_SIZE.
363     *
364     * Notes:
365     *
366     * Memory cards without an ATR should return IFD_SUCCESS on reset but
367     * the Atr should be zero'd and the length should be zero
368     *
369     * Reset errors should return zero for the AtrLength and return
370     * IFD_ERROR_POWER_ACTION.
371     *
372     * returns:
373     *
374     * IFD_SUCCESS IFD_ERROR_POWER_ACTION IFD_COMMUNICATION_ERROR
375     * IFD_NOT_SUPPORTED
376     */
377    
378     int nlength;
379     RESPONSECODE return_value = IFD_SUCCESS;
380     unsigned char pcbuffer[RESP_BUF_SIZE];
381    
382 rousseau 608 DEBUG_INFO2("lun: %X", Lun);
383 rousseau 269
384 rousseau 410 /* By default, assume it won't work :) */
385 rousseau 269 *AtrLength = 0;
386    
387     if (CheckLun(Lun))
388     return IFD_COMMUNICATION_ERROR;
389    
390 rousseau 766 switch (Action)
391 rousseau 269 {
392 rousseau 766 case IFD_POWER_DOWN:
393     /* Clear ATR buffer */
394     CcidSlots[LunToReaderIndex(Lun)].nATRLength = 0;
395     *CcidSlots[LunToReaderIndex(Lun)].pcATRBuffer = '\0';
396 rousseau 269
397 rousseau 766 /* Memorise the request */
398     CcidSlots[LunToReaderIndex(Lun)].bPowerFlags |=
399     MASK_POWERFLAGS_PDWN;
400     /* send the command */
401     if (IFD_SUCCESS != CmdPowerOff(Lun))
402     {
403     DEBUG_CRITICAL("PowerDown failed");
404     return_value = IFD_ERROR_POWER_ACTION;
405     goto end;
406     }
407 rousseau 269
408 rousseau 766 return_value = CardDown(Lun);
409 rousseau 616
410 rousseau 766 case IFD_POWER_UP:
411     case IFD_RESET:
412     nlength = sizeof(pcbuffer);
413     if (CmdPowerOn(Lun, &nlength, pcbuffer) != IFD_SUCCESS)
414     {
415     DEBUG_CRITICAL("PowerUp failed");
416     return_value = IFD_ERROR_POWER_ACTION;
417     goto end;
418     }
419 rousseau 269
420 rousseau 766 /* Power up successful, set state variable to memorise it */
421     CcidSlots[LunToReaderIndex(Lun)].bPowerFlags |=
422     MASK_POWERFLAGS_PUP;
423     CcidSlots[LunToReaderIndex(Lun)].bPowerFlags &=
424     ~MASK_POWERFLAGS_PDWN;
425 rousseau 269
426 rousseau 766 /* Reset is returned, even if TCK is wrong */
427     CcidSlots[LunToReaderIndex(Lun)].nATRLength = *AtrLength =
428     (nlength < MAX_ATR_SIZE) ? nlength : MAX_ATR_SIZE;
429     memcpy(Atr, pcbuffer, *AtrLength);
430     memcpy(CcidSlots[LunToReaderIndex(Lun)].pcATRBuffer,
431     pcbuffer, *AtrLength);
432 rousseau 616
433 rousseau 766 return_value = CardUp(Lun);
434     break;
435    
436     default:
437     DEBUG_CRITICAL("Action not supported");
438     return_value = IFD_NOT_SUPPORTED;
439 rousseau 269 }
440     end:
441    
442     return return_value;
443     } /* IFDHPowerICC */
444    
445    
446     RESPONSECODE IFDHTransmitToICC(DWORD Lun, SCARD_IO_HEADER SendPci,
447     PUCHAR TxBuffer, DWORD TxLength,
448     PUCHAR RxBuffer, PDWORD RxLength, PSCARD_IO_HEADER RecvPci)
449     {
450     /*
451     * This function performs an APDU exchange with the card/slot
452     * specified by Lun. The driver is responsible for performing any
453     * protocol specific exchanges such as T=0/1 ... differences. Calling
454     * this function will abstract all protocol differences.
455     *
456     * SendPci Protocol - 0, 1, .... 14 Length - Not used.
457     *
458     * TxBuffer - Transmit APDU example (0x00 0xA4 0x00 0x00 0x02 0x3F
459     * 0x00) TxLength - Length of this buffer. RxBuffer - Receive APDU
460     * example (0x61 0x14) RxLength - Length of the received APDU. This
461     * function will be passed the size of the buffer of RxBuffer and this
462     * function is responsible for setting this to the length of the
463     * received APDU. This should be ZERO on all errors. The resource
464     * manager will take responsibility of zeroing out any temporary APDU
465     * buffers for security reasons.
466     *
467     * RecvPci Protocol - 0, 1, .... 14 Length - Not used.
468     *
469     * Notes: The driver is responsible for knowing what type of card it
470     * has. If the current slot/card contains a memory card then this
471     * command should ignore the Protocol and use the MCT style commands
472     * for support for these style cards and transmit them appropriately.
473     * If your reader does not support memory cards or you don't want to
474     * then ignore this.
475     *
476     * RxLength should be set to zero on error.
477     *
478     * returns:
479     *
480     * IFD_SUCCESS IFD_COMMUNICATION_ERROR IFD_RESPONSE_TIMEOUT
481     * IFD_ICC_NOT_PRESENT IFD_PROTOCOL_NOT_SUPPORTED
482     */
483    
484 rousseau 611 RESPONSECODE return_value;
485     int rx_length;
486 rousseau 269
487 rousseau 608 DEBUG_INFO2("lun: %X", Lun);
488 rousseau 269
489     if (CheckLun(Lun))
490     return IFD_COMMUNICATION_ERROR;
491    
492 rousseau 611 rx_length = *RxLength;
493 rousseau 616 return_value = CmdXfrBlock(Lun, TxLength, TxBuffer, &rx_length, RxBuffer,
494     SendPci.Protocol);
495 rousseau 611 *RxLength = rx_length;
496 rousseau 269
497     return return_value;
498     } /* IFDHTransmitToICC */
499    
500    
501 rousseau 795 RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode, PUCHAR TxBuffer,
502     DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, PDWORD pdwBytesReturned)
503 rousseau 269 {
504     /*
505     * This function performs a data exchange with the reader (not the
506     * card) specified by Lun. Here XXXX will only be used. It is
507     * responsible for abstracting functionality such as PIN pads,
508     * biometrics, LCD panels, etc. You should follow the MCT, CTBCS
509     * specifications for a list of accepted commands to implement.
510     *
511     * TxBuffer - Transmit data TxLength - Length of this buffer. RxBuffer
512     * - Receive data RxLength - Length of the received data. This
513     * function will be passed the length of the buffer RxBuffer and it
514     * must set this to the length of the received data.
515     *
516     * Notes: RxLength should be zero on error.
517     */
518    
519 rousseau 795 DEBUG_INFO3("lun: %X, ControlCode: 0x%X", Lun, dwControlCode);
520 rousseau 269
521 rousseau 795 if (CheckLun(Lun))
522     return IFD_COMMUNICATION_ERROR;
523 rousseau 269
524 rousseau 568 /* Set the return length to 0 to avoid problems */
525 rousseau 795 if (pdwBytesReturned)
526     *pdwBytesReturned = 0;
527 rousseau 568
528 rousseau 795 return IFD_SUCCESS;
529 rousseau 269 } /* IFDHControl */
530    
531    
532     RESPONSECODE IFDHICCPresence(DWORD Lun)
533     {
534     /*
535     * This function returns the status of the card inserted in the
536     * reader/slot specified by Lun. It will return either:
537     *
538     * returns: IFD_ICC_PRESENT IFD_ICC_NOT_PRESENT
539     * IFD_COMMUNICATION_ERROR
540     */
541    
542     unsigned char pcbuffer[SIZE_GET_SLOT_STATUS];
543     RESPONSECODE return_value = IFD_COMMUNICATION_ERROR;
544    
545 rousseau 608 DEBUG_PERIODIC2("lun: %X", Lun);
546 rousseau 269
547     if (CheckLun(Lun))
548     return IFD_COMMUNICATION_ERROR;
549    
550     if (CmdGetSlotStatus(Lun, pcbuffer) != IFD_SUCCESS)
551     return IFD_COMMUNICATION_ERROR;
552    
553     switch (pcbuffer[7]) /* bStatus */
554     {
555     case 0x00:
556     return_value = IFD_ICC_PRESENT;
557     break;
558    
559     case 0x01:
560     return_value = IFD_ICC_PRESENT;
561     break;
562    
563     case 0x02:
564     return_value = IFD_ICC_NOT_PRESENT;
565     break;
566     }
567    
568     return return_value;
569     } /* IFDHICCPresence */
570    
571 rousseau 609
572     CcidDesc *get_ccid_slot(int lun)
573     {
574     return &CcidSlots[LunToReaderIndex(lun)];
575     } /* get_ccid_slot */
576    
577 rousseau 673
578     RESPONSECODE CardUp(int lun)
579     {
580     ATR atr;
581     BYTE protocol = ATR_PROTOCOL_TYPE_T0;
582     unsigned int np;
583     CcidDesc *ccid_slot = get_ccid_slot(lun);
584     _ccid_descriptor *ccid_desc = get_ccid_descriptor(lun);
585    
586     /* Get ATR of the card */
587     ATR_InitFromArray(&atr, ccid_slot -> pcATRBuffer, ccid_slot -> nATRLength);
588    
589     ATR_GetNumberOfProtocols(&atr, &np);
590    
591 rousseau 692 /* PPS not negociated by reader, and TA1 present */
592     if (atr.ib[0][ATR_INTERFACE_BYTE_TA].present &&
593 rousseau 696 ! (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_CUR))
594 rousseau 692 {
595 rousseau 696 unsigned int baudrate;
596     double f, d;
597 rousseau 692
598 rousseau 696 ATR_GetParameter(&atr, ATR_PARAMETER_D, &d);
599     ATR_GetParameter(&atr, ATR_PARAMETER_F, &f);
600 rousseau 692
601 rousseau 696 /* Baudrate = f x D/F */
602     baudrate = (unsigned int) (1000 * ccid_desc->dwDefaultClock * d / f);
603 rousseau 692
604 rousseau 696 /* if the reader is fast enough */
605     if (baudrate < ccid_desc->dwMaxDataRate)
606     {
607     int len = 3;
608     BYTE pps[] = {
609     0xFF, /* PTSS */
610     0x10, /* PTS0: PTS1 present */
611     0, /* PTS1 */
612     0}; /* PCK: will be calculated */
613    
614     /* TD1: protocol */
615     if (atr.ib[0][ATR_INTERFACE_BYTE_TD].present)
616     pps[1] |= (atr.ib[0][ATR_INTERFACE_BYTE_TD].value & 0x0F);
617    
618     /* PTS1 = TA1 */
619     pps[2] = atr.ib[0][ATR_INTERFACE_BYTE_TA].value;
620    
621     PPS_Exchange(lun, pps, &len);
622     }
623     else
624     {
625     DEBUG_INFO3("The reader is too slow (%d bauds) for the card (%d bauds)", ccid_desc->dwMaxDataRate, baudrate);
626     }
627 rousseau 692 }
628    
629 rousseau 673 /*
630     * Get protocol offered by interface bytes T*2 if available,
631 rousseau 692 * (that is, if TD1 is available), otherwise use default T=0
632 rousseau 673 */
633     if (np>1)
634     ATR_GetProtocolType(&atr, 2, &protocol);
635    
636 rousseau 696 /* SetParameters */
637     //if (! (ccid_desc->dwFeatures & CCID_CLASS_AUTO_BAUD))
638 rousseau 673 {
639 rousseau 696 int convention;
640 rousseau 673
641 rousseau 696 ATR_GetConvention(&atr, &convention);
642 rousseau 673
643 rousseau 696 /* T=1 */
644     if (protocol == ATR_PROTOCOL_TYPE_T1)
645     {
646     BYTE param[] = {0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00};
647     Protocol_T1 *t1 = &(ccid_slot -> t1);
648 rousseau 673
649 rousseau 696 /* get TA1 Fi/Di */
650     if (atr.ib[0][ATR_INTERFACE_BYTE_TA].present)
651     param[0] = atr.ib[0][ATR_INTERFACE_BYTE_TA].value;
652    
653     if (convention == ATR_CONVENTION_INVERSE)
654     param[1] &= 0x02;
655    
656     /* get TC1 Extra guard time */
657     if (atr.ib[0][ATR_INTERFACE_BYTE_TC].present)
658     param[2] = atr.ib[0][ATR_INTERFACE_BYTE_TC].value;
659    
660     /* get TB3 BWI/BCI */
661     if (atr.ib[2][ATR_INTERFACE_BYTE_TB].present)
662     param[3] = atr.ib[2][ATR_INTERFACE_BYTE_TB].value;
663    
664     /* set T=1 context */
665     Protocol_T1_Init(t1, lun);
666    
667     SetParameters(lun, 1, sizeof(param), param);
668     }
669     else
670     /* T=0 */
671     {
672     BYTE param[] = {0x00, 0x00, 0x00, 0x0a, 0x00};
673    
674     /* get TA1 Fi/Di */
675     if (atr.ib[0][ATR_INTERFACE_BYTE_TA].present)
676     param[0] = atr.ib[0][ATR_INTERFACE_BYTE_TA].value;
677    
678     if (convention == ATR_CONVENTION_INVERSE)
679     param[1] &= 0x02;
680    
681     /* get TC1 Extra guard time */
682     if (atr.ib[0][ATR_INTERFACE_BYTE_TC].present)
683     param[2] = atr.ib[0][ATR_INTERFACE_BYTE_TC].value;
684    
685     /* TC2 WWT */
686     if (atr.ib[1][ATR_INTERFACE_BYTE_TC].present)
687     param[3] = atr.ib[1][ATR_INTERFACE_BYTE_TC].value;
688    
689     SetParameters(lun, 0, sizeof(param), param);
690     }
691 rousseau 673 }
692    
693 rousseau 696
694 rousseau 692 /* negotiate IFSD in T=1 */
695     if ((protocol == ATR_PROTOCOL_TYPE_T1) &&
696     ! (ccid_desc->dwFeatures & CCID_CLASS_AUTO_IFSD))
697 rousseau 673 {
698     Protocol_T1 *t1 = &(ccid_slot -> t1);
699    
700 rousseau 692 Protocol_T1_Negociate_IFSD(t1, ccid_desc -> dwMaxIFSD);
701 rousseau 673
702 rousseau 692 DEBUG_COMM3("T=1: IFSC=%d, IFSD=%d", t1->ifsc, t1->ifsd);
703 rousseau 673 }
704    
705     return IFD_SUCCESS;
706     } /* CardUp */
707    
708    
709     RESPONSECODE CardDown(int lun)
710     {
711     /* clear T=1 context */
712     Protocol_T1_Close(&((get_ccid_slot(lun)) -> t1));
713    
714     return IFD_SUCCESS;
715 rousseau 768 } /* CardDown */
716 rousseau 673
717 rousseau 773
718     void init_debug(void)
719     {
720     char keyValue[TOKEN_MAX_VALUE_SIZE];
721     char infofile[FILENAME_MAX];
722    
723     /* Info.plist full patch filename */
724     snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
725     PCSCLITE_HP_DROPDIR, BUNDLE);
726    
727     if (LTPBundleFindValueWithKey(infofile, "ifdLogLevel", keyValue, 0))
728     return;
729    
730     /* convert from hex or dec or octal */
731     LogLevel = strtoul(keyValue, 0, 16);
732    
733     /* print the log level used */
734     debug_msg("%s:%d:%s LogLevel: 0x%.4X", __FILE__, __LINE__, __FUNCTION__,
735     LogLevel);
736    
737     DebugInitialized = TRUE;
738     } /* init_debug */
739    

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.5