pcsc-lite 2.5.2
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
39
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 (IFDH_create_channel_by_name)
130 {
131 if (rContext->device[0] != '\0')
132 rv = (*IFDH_create_channel_by_name) (rContext->slot, rContext->device);
133 else
134 rv = (*IFDH_create_channel) (rContext->slot, rContext->port);
135 }
136 else
137 rv = (*IFDH_create_channel) (rContext->slot, rContext->port);
138#else
139#if defined(IFDHANDLERv2)
140 rv = IFDHCreateChannel(rContext->slot, rContext->port);
141#else
142 {
143 /* Use device name only if defined */
144 if (rContext->device[0] != '\0')
145 rv = IFDHCreateChannelByName(rContext->slot, rContext->device);
146 else
147 rv = IFDHCreateChannel(rContext->slot, rContext->port);
148 }
149#endif
150#endif
151
152 /* END OF LOCKED REGION */
153 (void)pthread_mutex_unlock(rContext->mMutex);
154
155 return rv;
156}
157
161RESPONSECODE IFDCloseIFD(READER_CONTEXT * rContext)
162{
163 RESPONSECODE rv;
164 int repeat;
165 bool do_unlock = true;
166
167#ifndef PCSCLITE_STATIC_DRIVER
168 RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;
169
170 IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
171#endif
172
173 /* TRY TO LOCK THIS CODE REGION */
174 repeat = 5;
175again:
176 rv = pthread_mutex_trylock(rContext->mMutex);
177 if (EBUSY == rv)
178 {
179 Log2(PCSC_LOG_ERROR, "Locking failed. %d tries remaining.", repeat);
180 repeat--;
181 if (repeat)
182 {
183 (void)SYS_USleep(100*1000); /* 100 ms */
184 goto again;
185 }
186 else
187 /* locking failed but we need to close the IFD */
188 do_unlock = false;
189 }
190
191#ifndef PCSCLITE_STATIC_DRIVER
192 rv = (*IFDH_close_channel) (rContext->slot);
193#else
194 rv = IFDHCloseChannel(rContext->slot);
195#endif
196
197 /* END OF LOCKED REGION */
198 if (do_unlock)
199 (void)pthread_mutex_unlock(rContext->mMutex);
200
201 return rv;
202}
203
207RESPONSECODE IFDSetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
208 DWORD dwLength, PUCHAR pucValue)
209{
210 RESPONSECODE rv;
211
212#ifndef PCSCLITE_STATIC_DRIVER
213 RESPONSECODE(*IFDH_set_capabilities) (DWORD, DWORD, DWORD, PUCHAR) = NULL;
214
215 IFDH_set_capabilities = rContext->psFunctions.psFunctions_v2.pvfSetCapabilities;
216#endif
217
218 /*
219 * Let the calling function lock this otherwise a deadlock will
220 * result
221 */
222
223#ifndef PCSCLITE_STATIC_DRIVER
224 rv = (*IFDH_set_capabilities) (rContext->slot, dwTag,
225 dwLength, pucValue);
226#else
227 rv = IFDHSetCapabilities(rContext->slot, dwTag, dwLength, pucValue);
228#endif
229
230 return rv;
231}
232
238RESPONSECODE IFDGetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
239 PDWORD pdwLength, PUCHAR pucValue)
240{
241 RESPONSECODE rv;
242
243#ifndef PCSCLITE_STATIC_DRIVER
244 RESPONSECODE(*IFDH_get_capabilities) (DWORD, DWORD, PDWORD, /*@out@*/ PUCHAR) = NULL;
245
246 IFDH_get_capabilities =
247 rContext->psFunctions.psFunctions_v2.pvfGetCapabilities;
248#endif
249
250 /* LOCK THIS CODE REGION */
251 (void)pthread_mutex_lock(rContext->mMutex);
252
253#ifndef PCSCLITE_STATIC_DRIVER
254 rv = (*IFDH_get_capabilities) (rContext->slot, dwTag, pdwLength, pucValue);
255#else
256 rv = IFDHGetCapabilities(rContext->slot, dwTag, pdwLength, pucValue);
257#endif
258
259 /* END OF LOCKED REGION */
260 (void)pthread_mutex_unlock(rContext->mMutex);
261
262 return rv;
263}
264
268RESPONSECODE IFDPowerICC(READER_CONTEXT * rContext, DWORD dwAction,
269 PUCHAR pucAtr, PDWORD pdwAtrLen)
270{
271 RESPONSECODE rv;
272 DWORD dwStatus;
273 UCHAR dummyAtr[MAX_ATR_SIZE];
274 DWORD dummyAtrLen = sizeof(dummyAtr);
275
276#ifndef PCSCLITE_STATIC_DRIVER
277 RESPONSECODE(*IFDH_power_icc) (DWORD, DWORD, PUCHAR, PDWORD) = NULL;
278#endif
279
280 /*
281 * Zero out everything
282 */
283 dwStatus = 0;
284
285 if (NULL == pucAtr)
286 pucAtr = dummyAtr;
287 if (NULL == pdwAtrLen)
288 pdwAtrLen = &dummyAtrLen;
289
290 /*
291 * Check that the card is inserted first
292 */
293 rv = IFDStatusICC(rContext, &dwStatus, true);
294 if (rv != SCARD_S_SUCCESS)
295 return rv;
296
297 if (dwStatus & SCARD_ABSENT)
299#ifndef PCSCLITE_STATIC_DRIVER
300 IFDH_power_icc = rContext->psFunctions.psFunctions_v2.pvfPowerICC;
301#endif
302
303 /* LOCK THIS CODE REGION */
304 (void)pthread_mutex_lock(rContext->mMutex);
305
306#ifndef PCSCLITE_STATIC_DRIVER
307 rv = (*IFDH_power_icc) (rContext->slot, dwAction, pucAtr, pdwAtrLen);
308#else
309 rv = IFDHPowerICC(rContext->slot, dwAction, pucAtr, pdwAtrLen);
310#endif
311
312 /* END OF LOCKED REGION */
313 (void)pthread_mutex_unlock(rContext->mMutex);
314
315 /* use clean values in case of error */
316 if (rv != IFD_SUCCESS)
317 {
318 *pdwAtrLen = 0;
319 pucAtr[0] = '\0';
320
321 if (rv == IFD_NO_SUCH_DEVICE)
322 {
323 (void)SendHotplugSignal();
325 }
326
328 }
329
330 if (*pdwAtrLen > MAX_ATR_SIZE)
331 {
332 Log3(PCSC_LOG_CRITICAL,
333 "Driver reported ATR length %lu exceeds maximum of %u",
334 *pdwAtrLen, MAX_ATR_SIZE);
335 *pdwAtrLen = 0;
337 }
338
339 return rv;
340}
341
346LONG IFDStatusICC(READER_CONTEXT * rContext, PDWORD pdwStatus, bool hotplug)
347{
348 RESPONSECODE rv;
349 DWORD dwCardStatus = 0;
350
351#ifndef PCSCLITE_STATIC_DRIVER
352 RESPONSECODE(*IFDH_icc_presence) (DWORD) = NULL;
353
354 IFDH_icc_presence = rContext->psFunctions.psFunctions_v2.pvfICCPresence;
355#endif
356
357 /* LOCK THIS CODE REGION */
358 (void)pthread_mutex_lock(rContext->mMutex);
359
360#ifndef PCSCLITE_STATIC_DRIVER
361 rv = (*IFDH_icc_presence) (rContext->slot);
362#else
363 rv = IFDHICCPresence(rContext->slot);
364#endif
365
366 /* END OF LOCKED REGION */
367 (void)pthread_mutex_unlock(rContext->mMutex);
368
369 if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
370 dwCardStatus |= SCARD_PRESENT;
371 else
372 if (rv == IFD_ICC_NOT_PRESENT)
373 dwCardStatus |= SCARD_ABSENT;
374 else
375 {
376 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
377 *pdwStatus = SCARD_UNKNOWN;
378
379 if (rv == IFD_NO_SUCH_DEVICE)
380 {
381 if (hotplug)
382 (void)SendHotplugSignal();
384 }
385
387 }
388
389 *pdwStatus = dwCardStatus;
390
391 return SCARD_S_SUCCESS;
392}
393
394/*
395 * Function: IFDControl Purpose : This function provides a means for
396 * toggling a specific action on the reader such as swallow, eject,
397 * biometric.
398 */
399
400/*
401 * Valid only for IFDHandler version 2.0
402 */
403
404LONG IFDControl_v2(READER_CONTEXT * rContext, PUCHAR TxBuffer,
405 DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
406{
407 RESPONSECODE rv = IFD_SUCCESS;
408
409#ifndef PCSCLITE_STATIC_DRIVER
410 RESPONSECODE(*IFDH_control_v2) (DWORD, PUCHAR, DWORD, /*@out@*/ PUCHAR,
411 PDWORD);
412#endif
413
414 if (rContext->version != IFD_HVERSION_2_0)
416
417#ifndef PCSCLITE_STATIC_DRIVER
418 IFDH_control_v2 = rContext->psFunctions.psFunctions_v2.pvfControl;
419#endif
420
421 /* LOCK THIS CODE REGION */
422 (void)pthread_mutex_lock(rContext->mMutex);
423
424#ifndef PCSCLITE_STATIC_DRIVER
425 rv = (*IFDH_control_v2) (rContext->slot, TxBuffer, TxLength,
426 RxBuffer, RxLength);
427#elif defined(IFDHANDLERv2)
428 rv = IFDHControl(rContext->slot, TxBuffer, TxLength,
429 RxBuffer, RxLength);
430#endif
431
432 /* END OF LOCKED REGION */
433 (void)pthread_mutex_unlock(rContext->mMutex);
434
435 if (rv == IFD_SUCCESS)
436 return SCARD_S_SUCCESS;
437 else
438 {
439 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
440 LogXxd(PCSC_LOG_DEBUG, "TxBuffer ", TxBuffer, TxLength);
441 LogXxd(PCSC_LOG_DEBUG, "RxBuffer ", RxBuffer, *RxLength);
443 }
444}
445
450
451/*
452 * Valid only for IFDHandler version 3.0 and up
453 */
454
455LONG IFDControl(READER_CONTEXT * rContext, DWORD ControlCode,
456 LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength,
457 LPDWORD BytesReturned)
458{
459 RESPONSECODE rv = IFD_SUCCESS;
460
461#ifndef PCSCLITE_STATIC_DRIVER
462 RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
463#endif
464
465 if (rContext->version < IFD_HVERSION_3_0)
467
468#ifndef PCSCLITE_STATIC_DRIVER
469 IFDH_control = rContext->psFunctions.psFunctions_v3.pvfControl;
470#endif
471
472 /* LOCK THIS CODE REGION */
473 (void)pthread_mutex_lock(rContext->mMutex);
474
475#ifndef PCSCLITE_STATIC_DRIVER
476 rv = (*IFDH_control) (rContext->slot, ControlCode, TxBuffer,
477 TxLength, RxBuffer, RxLength, BytesReturned);
478#elif defined(IFDHANDLERv3)
479 rv = IFDHControl(rContext->slot, ControlCode, TxBuffer,
480 TxLength, RxBuffer, RxLength, BytesReturned);
481#endif
482
483 /* END OF LOCKED REGION */
484 (void)pthread_mutex_unlock(rContext->mMutex);
485
486 if (rv == IFD_SUCCESS)
487 return SCARD_S_SUCCESS;
488 else
489 {
490 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
491 Log3(PCSC_LOG_DEBUG, "ControlCode: 0x%.8lX BytesReturned: %ld",
492 ControlCode, *BytesReturned);
493 LogXxd(PCSC_LOG_DEBUG, "TxBuffer ", TxBuffer, TxLength);
494 LogXxd(PCSC_LOG_DEBUG, "RxBuffer ", RxBuffer, *BytesReturned);
495
496 if (rv == IFD_NO_SUCH_DEVICE)
497 {
498 (void)SendHotplugSignal();
500 }
501
502 if ((IFD_ERROR_NOT_SUPPORTED == rv) || (IFD_NOT_SUPPORTED == rv))
504
507
509 }
510}
511
515LONG IFDTransmit(READER_CONTEXT * rContext, SCARD_IO_HEADER pioTxPci,
516 PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer,
517 PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
518{
519 RESPONSECODE rv;
520
521#ifndef PCSCLITE_STATIC_DRIVER
522 RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
523 DWORD, /*@out@*/ PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
524#endif
525
526 /* log the APDU */
527 DebugLogCategory(DEBUG_CATEGORY_APDU, pucTxBuffer, dwTxLength);
528
529#ifndef PCSCLITE_STATIC_DRIVER
530 IFDH_transmit_to_icc =
531 rContext->psFunctions.psFunctions_v2.pvfTransmitToICC;
532#endif
533
534 /* LOCK THIS CODE REGION */
535 (void)pthread_mutex_lock(rContext->mMutex);
536
537#ifndef PCSCLITE_STATIC_DRIVER
538 rv = (*IFDH_transmit_to_icc) (rContext->slot, pioTxPci, (LPBYTE)
539 pucTxBuffer, dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
540#else
541 rv = IFDHTransmitToICC(rContext->slot, pioTxPci,
542 (LPBYTE) pucTxBuffer, dwTxLength,
543 pucRxBuffer, pdwRxLength, pioRxPci);
544#endif
545
546 /* END OF LOCKED REGION */
547 (void)pthread_mutex_unlock(rContext->mMutex);
548
549 /* log the returned status word */
550 DebugLogCategory(DEBUG_CATEGORY_SW, pucRxBuffer, *pdwRxLength);
551
552 if (rv == IFD_SUCCESS)
553 return SCARD_S_SUCCESS;
554 else
555 {
556 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
557
558 if (rv == IFD_NO_SUCH_DEVICE)
559 {
560 (void)SendHotplugSignal();
562 }
563
564 if (rv == IFD_ICC_NOT_PRESENT)
566
568 }
569}
570
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:161
LONG IFDStatusICC(READER_CONTEXT *rContext, PDWORD pdwStatus, bool hotplug)
Provide statistical information about the IFD and ICC including insertions, atr, powering status/etc.
Definition ifdwrapper.c:346
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:455
RESPONSECODE IFDGetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, PDWORD pdwLength, PUCHAR pucValue)
Gets capabilities in the reader.
Definition ifdwrapper.c:238
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:515
RESPONSECODE IFDSetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, DWORD dwLength, PUCHAR pucValue)
Set capabilities in the reader.
Definition ifdwrapper.c:207
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:268
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.
Definition readers.h:110
union ReaderContext::@326266165201103155124353152063316062370301160101 psFunctions
driver functions
FCT_MAP_V3 psFunctions_v3
API V3.0.
Definition readers.h:117
int port
Port ID.
Definition readers.h:122
int slot
Current Reader Slot.
Definition readers.h:123
int version
IFD Handler version number.
Definition readers.h:121
FCT_MAP_V2 psFunctions_v2
API V2.0.
Definition readers.h:116
char * device
Device Name.
Definition readers.h:107
This handles abstract system level calls.
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
Definition sys_unix.c:80