pcsc-lite 2.3.0
ifdwrapper.c
Go to the documentation of this file.
1/*
2 * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ )
3 *
4 * Copyright (C) 1999-2004
5 * David Corcoran <corcoran@musclecard.com>
6 * Copyright (C) 2003-2004
7 * Damien Sauveron <damien.sauveron@labri.fr>
8 * Copyright (C) 2002-2023
9 * Ludovic Rousseau <ludovic.rousseau@free.fr>
10 *
11Redistribution and use in source and binary forms, with or without
12modification, are permitted provided that the following conditions
13are met:
14
151. Redistributions of source code must retain the above copyright
16 notice, this list of conditions and the following disclaimer.
172. Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in the
19 documentation and/or other materials provided with the distribution.
203. The name of the author may not be used to endorse or promote products
21 derived from this software without specific prior written permission.
22
23THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
40#include <errno.h>
41#include <unistd.h>
42#include <pthread.h>
43
44#include "config.h"
45#include "misc.h"
46#include "pcscd.h"
47#include "debuglog.h"
48#include "readerfactory.h"
49#include "ifdwrapper.h"
50#include "atrhandler.h"
51#include "dyn_generic.h"
52#include "sys_generic.h"
53#include "utils.h"
54
55#ifdef PCSCLITE_STATIC_DRIVER
56/* check that either IFDHANDLERv2 or IFDHANDLERv3 is
57 * defined */
58 #if ! (defined(IFDHANDLERv2) || defined(IFDHANDLERv3))
59 #error IFDHANDLER version not defined
60 #endif
61#endif
62
67RESPONSECODE IFDSetPTS(READER_CONTEXT * rContext, DWORD dwProtocol,
68 UCHAR ucFlags, UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
69{
70 RESPONSECODE rv;
71
72#ifndef PCSCLITE_STATIC_DRIVER
73 RESPONSECODE(*IFDH_set_protocol_parameters) (DWORD, DWORD, UCHAR,
74 UCHAR, UCHAR, UCHAR) = NULL;
75
76 IFDH_set_protocol_parameters = (RESPONSECODE(*)(DWORD, DWORD, UCHAR,
77 UCHAR, UCHAR, UCHAR))
78 rContext->psFunctions.psFunctions_v2.pvfSetProtocolParameters;
79
80 if (NULL == IFDH_set_protocol_parameters)
82#endif
83
84 /*
85 * Locking is done in winscard.c SCardConnect() and SCardReconnect()
86 *
87 * This avoids to renegotiate the protocol and confuse the card
88 * Error returned by CCID driver is: CCID_Receive Procedure byte conflict
89 */
90
91#ifndef PCSCLITE_STATIC_DRIVER
92 rv = (*IFDH_set_protocol_parameters) (rContext->slot,
93 dwProtocol, ucFlags, ucPTS1, ucPTS2, ucPTS3);
94#else
95 rv = IFDHSetProtocolParameters(rContext->slot, dwProtocol, ucFlags,
96 ucPTS1, ucPTS2, ucPTS3);
97#endif
98
99 return rv;
100}
101
105RESPONSECODE IFDOpenIFD(READER_CONTEXT * rContext)
106{
107 RESPONSECODE rv = IFD_SUCCESS;
108
109#ifndef PCSCLITE_STATIC_DRIVER
110 RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
111 RESPONSECODE(*IFDH_create_channel_by_name) (DWORD, LPSTR) = NULL;
112
113 if (rContext->version == IFD_HVERSION_2_0)
114 IFDH_create_channel =
115 rContext->psFunctions.psFunctions_v2.pvfCreateChannel;
116 else
117 {
118 IFDH_create_channel =
119 rContext->psFunctions.psFunctions_v3.pvfCreateChannel;
120 IFDH_create_channel_by_name =
121 rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName;
122 }
123#endif
124
125 /* LOCK THIS CODE REGION */
126 (void)pthread_mutex_lock(rContext->mMutex);
127
128#ifndef PCSCLITE_STATIC_DRIVER
129 if (rContext->version == IFD_HVERSION_2_0)
130 {
131 rv = (*IFDH_create_channel) (rContext->slot, rContext->port);
132 } else
133 {
134 /* use device name only if defined */
135 if (rContext->device[0] != '\0')
136 rv = (*IFDH_create_channel_by_name) (rContext->slot, rContext->device);
137 else
138 rv = (*IFDH_create_channel) (rContext->slot, rContext->port);
139 }
140#else
141#if defined(IFDHANDLERv2)
142 rv = IFDHCreateChannel(rContext->slot, rContext->port);
143#else
144 {
145 /* Use device name only if defined */
146 if (rContext->device[0] != '\0')
147 rv = IFDHCreateChannelByName(rContext->slot, rContext->device);
148 else
149 rv = IFDHCreateChannel(rContext->slot, rContext->port);
150 }
151#endif
152#endif
153
154 /* END OF LOCKED REGION */
155 (void)pthread_mutex_unlock(rContext->mMutex);
156
157 return rv;
158}
159
163RESPONSECODE IFDCloseIFD(READER_CONTEXT * rContext)
164{
165 RESPONSECODE rv;
166 int repeat;
167 bool do_unlock = true;
168
169#ifndef PCSCLITE_STATIC_DRIVER
170 RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;
171
172 IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
173#endif
174
175 /* TRY TO LOCK THIS CODE REGION */
176 repeat = 5;
177again:
178 rv = pthread_mutex_trylock(rContext->mMutex);
179 if (EBUSY == rv)
180 {
181 Log1(PCSC_LOG_ERROR, "Locking failed");
182 repeat--;
183 if (repeat)
184 {
185 (void)SYS_USleep(100*1000); /* 100 ms */
186 goto again;
187 }
188 else
189 /* locking failed but we need to close the IFD */
190 do_unlock = false;
191 }
192
193#ifndef PCSCLITE_STATIC_DRIVER
194 rv = (*IFDH_close_channel) (rContext->slot);
195#else
196 rv = IFDHCloseChannel(rContext->slot);
197#endif
198
199 /* END OF LOCKED REGION */
200 if (do_unlock)
201 (void)pthread_mutex_unlock(rContext->mMutex);
202
203 return rv;
204}
205
209RESPONSECODE IFDSetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
210 DWORD dwLength, PUCHAR pucValue)
211{
212 RESPONSECODE rv;
213
214#ifndef PCSCLITE_STATIC_DRIVER
215 RESPONSECODE(*IFDH_set_capabilities) (DWORD, DWORD, DWORD, PUCHAR) = NULL;
216
217 IFDH_set_capabilities = rContext->psFunctions.psFunctions_v2.pvfSetCapabilities;
218#endif
219
220 /*
221 * Let the calling function lock this otherwise a deadlock will
222 * result
223 */
224
225#ifndef PCSCLITE_STATIC_DRIVER
226 rv = (*IFDH_set_capabilities) (rContext->slot, dwTag,
227 dwLength, pucValue);
228#else
229 rv = IFDHSetCapabilities(rContext->slot, dwTag, dwLength, pucValue);
230#endif
231
232 return rv;
233}
234
240RESPONSECODE IFDGetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
241 PDWORD pdwLength, PUCHAR pucValue)
242{
243 RESPONSECODE rv;
244
245#ifndef PCSCLITE_STATIC_DRIVER
246 RESPONSECODE(*IFDH_get_capabilities) (DWORD, DWORD, PDWORD, /*@out@*/ PUCHAR) = NULL;
247
248 IFDH_get_capabilities =
249 rContext->psFunctions.psFunctions_v2.pvfGetCapabilities;
250#endif
251
252 /* LOCK THIS CODE REGION */
253 (void)pthread_mutex_lock(rContext->mMutex);
254
255#ifndef PCSCLITE_STATIC_DRIVER
256 rv = (*IFDH_get_capabilities) (rContext->slot, dwTag, pdwLength, pucValue);
257#else
258 rv = IFDHGetCapabilities(rContext->slot, dwTag, pdwLength, pucValue);
259#endif
260
261 /* END OF LOCKED REGION */
262 (void)pthread_mutex_unlock(rContext->mMutex);
263
264 return rv;
265}
266
270RESPONSECODE IFDPowerICC(READER_CONTEXT * rContext, DWORD dwAction,
271 PUCHAR pucAtr, PDWORD pdwAtrLen)
272{
273 RESPONSECODE rv;
274 DWORD dwStatus;
275 UCHAR dummyAtr[MAX_ATR_SIZE];
276 DWORD dummyAtrLen = sizeof(dummyAtr);
277
278#ifndef PCSCLITE_STATIC_DRIVER
279 RESPONSECODE(*IFDH_power_icc) (DWORD, DWORD, PUCHAR, PDWORD) = NULL;
280#endif
281
282 /*
283 * Zero out everything
284 */
285 dwStatus = 0;
286
287 if (NULL == pucAtr)
288 pucAtr = dummyAtr;
289 if (NULL == pdwAtrLen)
290 pdwAtrLen = &dummyAtrLen;
291
292 /*
293 * Check that the card is inserted first
294 */
295 rv = IFDStatusICC(rContext, &dwStatus);
296 if (rv != SCARD_S_SUCCESS)
297 return rv;
298
299 if (dwStatus & SCARD_ABSENT)
301#ifndef PCSCLITE_STATIC_DRIVER
302 IFDH_power_icc = rContext->psFunctions.psFunctions_v2.pvfPowerICC;
303#endif
304
305 /* LOCK THIS CODE REGION */
306 (void)pthread_mutex_lock(rContext->mMutex);
307
308#ifndef PCSCLITE_STATIC_DRIVER
309 rv = (*IFDH_power_icc) (rContext->slot, dwAction, pucAtr, pdwAtrLen);
310#else
311 rv = IFDHPowerICC(rContext->slot, dwAction, pucAtr, pdwAtrLen);
312#endif
313
314 /* END OF LOCKED REGION */
315 (void)pthread_mutex_unlock(rContext->mMutex);
316
317 /* use clean values in case of error */
318 if (rv != IFD_SUCCESS)
319 {
320 *pdwAtrLen = 0;
321 pucAtr[0] = '\0';
322
323 if (rv == IFD_NO_SUCH_DEVICE)
324 {
325 (void)SendHotplugSignal();
327 }
328
330 }
331
332 return rv;
333}
334
339LONG IFDStatusICC(READER_CONTEXT * rContext, PDWORD pdwStatus)
340{
341 RESPONSECODE rv;
342 DWORD dwCardStatus = 0;
343
344#ifndef PCSCLITE_STATIC_DRIVER
345 RESPONSECODE(*IFDH_icc_presence) (DWORD) = NULL;
346
347 IFDH_icc_presence = rContext->psFunctions.psFunctions_v2.pvfICCPresence;
348#endif
349
350 /* LOCK THIS CODE REGION */
351 (void)pthread_mutex_lock(rContext->mMutex);
352
353#ifndef PCSCLITE_STATIC_DRIVER
354 rv = (*IFDH_icc_presence) (rContext->slot);
355#else
356 rv = IFDHICCPresence(rContext->slot);
357#endif
358
359 /* END OF LOCKED REGION */
360 (void)pthread_mutex_unlock(rContext->mMutex);
361
362 if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
363 dwCardStatus |= SCARD_PRESENT;
364 else
365 if (rv == IFD_ICC_NOT_PRESENT)
366 dwCardStatus |= SCARD_ABSENT;
367 else
368 {
369 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
370 *pdwStatus = SCARD_UNKNOWN;
371
372 if (rv == IFD_NO_SUCH_DEVICE)
373 {
374 (void)SendHotplugSignal();
376 }
377
379 }
380
381 *pdwStatus = dwCardStatus;
382
383 return SCARD_S_SUCCESS;
384}
385
386/*
387 * Function: IFDControl Purpose : This function provides a means for
388 * toggling a specific action on the reader such as swallow, eject,
389 * biometric.
390 */
391
392/*
393 * Valid only for IFDHandler version 2.0
394 */
395
396LONG IFDControl_v2(READER_CONTEXT * rContext, PUCHAR TxBuffer,
397 DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
398{
399 RESPONSECODE rv = IFD_SUCCESS;
400
401#ifndef PCSCLITE_STATIC_DRIVER
402 RESPONSECODE(*IFDH_control_v2) (DWORD, PUCHAR, DWORD, /*@out@*/ PUCHAR,
403 PDWORD);
404#endif
405
406 if (rContext->version != IFD_HVERSION_2_0)
408
409#ifndef PCSCLITE_STATIC_DRIVER
410 IFDH_control_v2 = rContext->psFunctions.psFunctions_v2.pvfControl;
411#endif
412
413 /* LOCK THIS CODE REGION */
414 (void)pthread_mutex_lock(rContext->mMutex);
415
416#ifndef PCSCLITE_STATIC_DRIVER
417 rv = (*IFDH_control_v2) (rContext->slot, TxBuffer, TxLength,
418 RxBuffer, RxLength);
419#elif defined(IFDHANDLERv2)
420 rv = IFDHControl(rContext->slot, TxBuffer, TxLength,
421 RxBuffer, RxLength);
422#endif
423
424 /* END OF LOCKED REGION */
425 (void)pthread_mutex_unlock(rContext->mMutex);
426
427 if (rv == IFD_SUCCESS)
428 return SCARD_S_SUCCESS;
429 else
430 {
431 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
432 LogXxd(PCSC_LOG_DEBUG, "TxBuffer ", TxBuffer, TxLength);
433 LogXxd(PCSC_LOG_DEBUG, "RxBuffer ", RxBuffer, *RxLength);
435 }
436}
437
443/*
444 * Valid only for IFDHandler version 3.0 and up
445 */
446
447LONG IFDControl(READER_CONTEXT * rContext, DWORD ControlCode,
448 LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength,
449 LPDWORD BytesReturned)
450{
451 RESPONSECODE rv = IFD_SUCCESS;
452
453#ifndef PCSCLITE_STATIC_DRIVER
454 RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
455#endif
456
457 if (rContext->version < IFD_HVERSION_3_0)
459
460#ifndef PCSCLITE_STATIC_DRIVER
461 IFDH_control = rContext->psFunctions.psFunctions_v3.pvfControl;
462#endif
463
464 /* LOCK THIS CODE REGION */
465 (void)pthread_mutex_lock(rContext->mMutex);
466
467#ifndef PCSCLITE_STATIC_DRIVER
468 rv = (*IFDH_control) (rContext->slot, ControlCode, TxBuffer,
469 TxLength, RxBuffer, RxLength, BytesReturned);
470#elif defined(IFDHANDLERv3)
471 rv = IFDHControl(rContext->slot, ControlCode, TxBuffer,
472 TxLength, RxBuffer, RxLength, BytesReturned);
473#endif
474
475 /* END OF LOCKED REGION */
476 (void)pthread_mutex_unlock(rContext->mMutex);
477
478 if (rv == IFD_SUCCESS)
479 return SCARD_S_SUCCESS;
480 else
481 {
482 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
483 Log3(PCSC_LOG_DEBUG, "ControlCode: 0x%.8lX BytesReturned: %ld",
484 ControlCode, *BytesReturned);
485 LogXxd(PCSC_LOG_DEBUG, "TxBuffer ", TxBuffer, TxLength);
486 LogXxd(PCSC_LOG_DEBUG, "RxBuffer ", RxBuffer, *BytesReturned);
487
488 if (rv == IFD_NO_SUCH_DEVICE)
489 {
490 (void)SendHotplugSignal();
492 }
493
494 if ((IFD_ERROR_NOT_SUPPORTED == rv) || (IFD_NOT_SUPPORTED == rv))
496
499
501 }
502}
503
508 PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer,
509 PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
510{
511 RESPONSECODE rv;
512
513#ifndef PCSCLITE_STATIC_DRIVER
514 RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
515 DWORD, /*@out@*/ PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
516#endif
517
518 /* log the APDU */
519 DebugLogCategory(DEBUG_CATEGORY_APDU, pucTxBuffer, dwTxLength);
520
521#ifndef PCSCLITE_STATIC_DRIVER
522 IFDH_transmit_to_icc =
523 rContext->psFunctions.psFunctions_v2.pvfTransmitToICC;
524#endif
525
526 /* LOCK THIS CODE REGION */
527 (void)pthread_mutex_lock(rContext->mMutex);
528
529#ifndef PCSCLITE_STATIC_DRIVER
530 rv = (*IFDH_transmit_to_icc) (rContext->slot, pioTxPci, (LPBYTE)
531 pucTxBuffer, dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
532#else
533 rv = IFDHTransmitToICC(rContext->slot, pioTxPci,
534 (LPBYTE) pucTxBuffer, dwTxLength,
535 pucRxBuffer, pdwRxLength, pioRxPci);
536#endif
537
538 /* END OF LOCKED REGION */
539 (void)pthread_mutex_unlock(rContext->mMutex);
540
541 /* log the returned status word */
542 DebugLogCategory(DEBUG_CATEGORY_SW, pucRxBuffer, *pdwRxLength);
543
544 if (rv == IFD_SUCCESS)
545 return SCARD_S_SUCCESS;
546 else
547 {
548 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
549
550 if (rv == IFD_NO_SUCH_DEVICE)
551 {
552 (void)SendHotplugSignal();
554 }
555
556 if (rv == IFD_ICC_NOT_PRESENT)
558
560 }
561}
562
This keeps track of smart card protocols, timing issues and Answer to Reset ATR handling.
This handles debugging.
This abstracts dynamic library loading functions.
#define SCARD_S_SUCCESS
No error was encountered.
Definition pcsclite.h:107
#define SCARD_W_REMOVED_CARD
The smart card has been removed, so further communication is not possible.
Definition pcsclite.h:219
#define SCARD_E_INSUFFICIENT_BUFFER
The data buffer to receive returned data is too small for the returned data.
Definition pcsclite.h:123
#define SCARD_E_NO_SMARTCARD
The operation requires a Smart Card, but no Smart Card is currently in the device.
Definition pcsclite.h:131
#define SCARD_E_NOT_TRANSACTED
An attempt was made to end a non-existent transaction.
Definition pcsclite.h:151
#define SCARD_E_READER_UNAVAILABLE
The specified reader is not currently available for use.
Definition pcsclite.h:153
#define SCARD_E_UNSUPPORTED_FEATURE
This smart card does not support the requested feature.
Definition pcsclite.h:171
RESPONSECODE IFDHCloseChannel(DWORD Lun)
This function should close the reader communication channel for the particular reader.
RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag, PDWORD Length, PUCHAR Value)
This function should get the slot/card capabilities for a particular slot/card specified by Lun.
RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol, UCHAR Flags, UCHAR PTS1, UCHAR PTS2, UCHAR PTS3)
This function should set the Protocol Type Selection (PTS) of a particular card/slot using the three ...
RESPONSECODE IFDHSetCapabilities(DWORD Lun, DWORD Tag, DWORD Length, PUCHAR Value)
This function should set the slot/card capabilities for a particular slot/card specified by Lun.
RESPONSECODE IFDHCreateChannelByName(DWORD Lun, LPSTR DeviceName)
This function is required to open a communications channel to the port listed by DeviceName.
RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, LPDWORD pdwBytesReturned)
This function performs a data exchange with the reader (not the card) specified by Lun.
RESPONSECODE IFDHICCPresence(DWORD Lun)
This function returns the status of the card inserted in the reader/slot specified by Lun.
RESPONSECODE IFDHTransmitToICC(DWORD Lun, SCARD_IO_HEADER SendPci, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength, PSCARD_IO_HEADER RecvPci)
This function performs an APDU exchange with the card/slot specified by Lun.
RESPONSECODE IFDHCreateChannel(DWORD Lun, DWORD Channel)
This function is required to open a communications channel to the port listed by Channel.
RESPONSECODE IFDHPowerICC(DWORD Lun, DWORD Action, PUCHAR Atr, PDWORD AtrLength)
This function controls the power and reset signals of the smart card reader at the particular reader/...
#define IFD_NO_SUCH_DEVICE
The IFD_NO_SUCH_DEVICE error must be returned by the driver when it detects the reader is no more pre...
Definition ifdhandler.h:372
#define IFD_NOT_SUPPORTED
request is not supported
Definition ifdhandler.h:364
struct _SCARD_IO_HEADER SCARD_IO_HEADER
Use by SCardTransmit()
#define IFD_ERROR_INSUFFICIENT_BUFFER
buffer is too small
Definition ifdhandler.h:373
#define IFD_ICC_PRESENT
card is present
Definition ifdhandler.h:365
#define IFD_ICC_NOT_PRESENT
card is absent
Definition ifdhandler.h:366
#define IFD_SUCCESS
no error
Definition ifdhandler.h:351
RESPONSECODE IFDCloseIFD(READER_CONTEXT *rContext)
Close a communication channel to the IFD.
Definition ifdwrapper.c:163
RESPONSECODE IFDOpenIFD(READER_CONTEXT *rContext)
Open a communication channel to the IFD.
Definition ifdwrapper.c:105
LONG IFDControl(READER_CONTEXT *rContext, DWORD ControlCode, LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength, LPDWORD BytesReturned)
Provide a means for toggling a specific action on the reader such as swallow, eject,...
Definition ifdwrapper.c:447
RESPONSECODE IFDGetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, PDWORD pdwLength, PUCHAR pucValue)
Gets capabilities in the reader.
Definition ifdwrapper.c:240
LONG IFDStatusICC(READER_CONTEXT *rContext, PDWORD pdwStatus)
Provide statistical information about the IFD and ICC including insertions, atr, powering status/etc.
Definition ifdwrapper.c:339
LONG IFDTransmit(READER_CONTEXT *rContext, SCARD_IO_HEADER pioTxPci, PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer, PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
Transmit an APDU to the ICC.
Definition ifdwrapper.c:507
RESPONSECODE IFDSetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, DWORD dwLength, PUCHAR pucValue)
Set capabilities in the reader.
Definition ifdwrapper.c:209
RESPONSECODE IFDSetPTS(READER_CONTEXT *rContext, DWORD dwProtocol, UCHAR ucFlags, UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
Set the protocol type selection (PTS).
Definition ifdwrapper.c:67
RESPONSECODE IFDPowerICC(READER_CONTEXT *rContext, DWORD dwAction, PUCHAR pucAtr, PDWORD pdwAtrLen)
Power up/down or reset's an ICC located in the IFD.
Definition ifdwrapper.c:270
This wraps the dynamic ifdhandler functions.
#define SCARD_PRESENT
Card is present.
Definition pcsclite.h:260
#define MAX_ATR_SIZE
Maximum ATR size.
Definition pcsclite.h:59
#define SCARD_ABSENT
Card is absent.
Definition pcsclite.h:259
#define SCARD_UNKNOWN
Unknown state.
Definition pcsclite.h:258
This keeps track of a list of currently available reader structures.
pthread_mutex_t * mMutex
Mutex for this connection.
FCT_MAP_V3 psFunctions_v3
API V3.0.
int port
Port ID.
union ReaderContext::@3 psFunctions
driver functions
int slot
Current Reader Slot.
int version
IFD Handler version number.
FCT_MAP_V2 psFunctions_v2
API V2.0.
char * device
Device Name.
Use by SCardTransmit()
Definition ifdhandler.h:311
This handles abstract system level calls.
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
Definition sys_unix.c:80