00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00019 #include <errno.h>
00020 #include <unistd.h>
00021 #include <pthread.h>
00022
00023 #include "config.h"
00024 #include "misc.h"
00025 #include "pcscd.h"
00026 #include "ifdhandler.h"
00027 #include "debuglog.h"
00028 #include "readerfactory.h"
00029 #include "ifdwrapper.h"
00030 #include "atrhandler.h"
00031 #include "dyn_generic.h"
00032 #include "sys_generic.h"
00033 #include "utils.h"
00034
00039 LONG IFDSetPTS(READER_CONTEXT * rContext, DWORD dwProtocol, UCHAR ucFlags,
00040 UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
00041 {
00042 RESPONSECODE rv = IFD_SUCCESS;
00043 UCHAR ucValue[1];
00044
00045 #ifndef PCSCLITE_STATIC_DRIVER
00046 RESPONSECODE(*IFD_set_protocol_parameters) (DWORD, UCHAR, UCHAR,
00047 UCHAR, UCHAR) = NULL;
00048 RESPONSECODE(*IFDH_set_protocol_parameters) (DWORD, DWORD, UCHAR,
00049 UCHAR, UCHAR, UCHAR) = NULL;
00050
00051 if (rContext->version == IFD_HVERSION_1_0)
00052 {
00053 IFD_set_protocol_parameters = (RESPONSECODE(*)(DWORD, UCHAR, UCHAR,
00054 UCHAR, UCHAR)) rContext->psFunctions.psFunctions_v1.pvfSetProtocolParameters;
00055
00056 if (NULL == IFD_set_protocol_parameters)
00057 return SCARD_E_UNSUPPORTED_FEATURE;
00058 }
00059 else
00060 {
00061 IFDH_set_protocol_parameters = (RESPONSECODE(*)(DWORD, DWORD, UCHAR,
00062 UCHAR, UCHAR, UCHAR))
00063 rContext->psFunctions.psFunctions_v2.pvfSetProtocolParameters;
00064
00065 if (NULL == IFDH_set_protocol_parameters)
00066 return SCARD_E_UNSUPPORTED_FEATURE;
00067 }
00068 #endif
00069
00070
00071
00072
00073
00074
00075
00076
00077 ucValue[0] = rContext->slot;
00078
00079 #ifndef PCSCLITE_STATIC_DRIVER
00080 if (rContext->version == IFD_HVERSION_1_0)
00081 {
00082 ucValue[0] = rContext->slot;
00083 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00084 rv = (*IFD_set_protocol_parameters) (dwProtocol,
00085 ucFlags, ucPTS1, ucPTS2, ucPTS3);
00086 }
00087 else
00088 {
00089 rv = (*IFDH_set_protocol_parameters) (rContext->slot,
00090 dwProtocol, ucFlags, ucPTS1, ucPTS2, ucPTS3);
00091 }
00092 #else
00093 #ifdef IFDHANDLERv1
00094 {
00095 ucValue[0] = rContext->slot;
00096 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00097 rv = IFD_Set_Protocol_Parameters(dwProtocol, ucFlags, ucPTS1,
00098 ucPTS2, ucPTS3);
00099 }
00100 #else
00101 rv = IFDHSetProtocolParameters(rContext->slot, dwProtocol, ucFlags,
00102 ucPTS1, ucPTS2, ucPTS3);
00103 #endif
00104 #endif
00105
00106 return rv;
00107 }
00108
00112 LONG IFDOpenIFD(READER_CONTEXT * rContext)
00113 {
00114 RESPONSECODE rv = 0;
00115
00116 #ifndef PCSCLITE_STATIC_DRIVER
00117 RESPONSECODE(*IO_create_channel) (DWORD) = NULL;
00118 RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
00119 RESPONSECODE(*IFDH_create_channel_by_name) (DWORD, LPSTR) = NULL;
00120
00121 if (rContext->version == IFD_HVERSION_1_0)
00122 IO_create_channel =
00123 rContext->psFunctions.psFunctions_v1.pvfCreateChannel;
00124 else
00125 if (rContext->version == IFD_HVERSION_2_0)
00126 IFDH_create_channel =
00127 rContext->psFunctions.psFunctions_v2.pvfCreateChannel;
00128 else
00129 {
00130 IFDH_create_channel =
00131 rContext->psFunctions.psFunctions_v3.pvfCreateChannel;
00132 IFDH_create_channel_by_name =
00133 rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName;
00134 }
00135 #endif
00136
00137
00138 (void)pthread_mutex_lock(rContext->mMutex);
00139
00140 #ifndef PCSCLITE_STATIC_DRIVER
00141 if (rContext->version == IFD_HVERSION_1_0)
00142 {
00143 rv = (*IO_create_channel) (rContext->port);
00144 } else if (rContext->version == IFD_HVERSION_2_0)
00145 {
00146 rv = (*IFDH_create_channel) (rContext->slot, rContext->port);
00147 } else
00148 {
00149
00150 if (rContext->lpcDevice[0] != '\0')
00151 rv = (*IFDH_create_channel_by_name) (rContext->slot, rContext->lpcDevice);
00152 else
00153 rv = (*IFDH_create_channel) (rContext->slot, rContext->port);
00154 }
00155 #else
00156 #ifdef IFDHANDLERv1
00157 rv = IO_Create_Channel(rContext->port);
00158 #elif IFDHANDLERv2
00159 rv = IFDHCreateChannel(rContext->slot, rContext->port);
00160 #else
00161 {
00162
00163 if (rContext->lpcDevice[0] != '\0')
00164 rv = IFDHCreateChannelByName(rContext->slot, rContext->lpcDevice);
00165 else
00166 rv = IFDHCreateChannel(rContext->slot, rContext->port);
00167 }
00168 #endif
00169 #endif
00170
00171
00172 (void)pthread_mutex_unlock(rContext->mMutex);
00173
00174 return rv;
00175 }
00176
00180 LONG IFDCloseIFD(READER_CONTEXT * rContext)
00181 {
00182 RESPONSECODE rv = IFD_SUCCESS;
00183 int repeat;
00184
00185 #ifndef PCSCLITE_STATIC_DRIVER
00186 RESPONSECODE(*IO_close_channel) (void) = NULL;
00187 RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;
00188
00189 if (rContext->version == IFD_HVERSION_1_0)
00190 IO_close_channel = rContext->psFunctions.psFunctions_v1.pvfCloseChannel;
00191 else
00192 IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
00193 #endif
00194
00195
00196 repeat = 5;
00197 again:
00198 rv = pthread_mutex_trylock(rContext->mMutex);
00199 if (EBUSY == rv)
00200 {
00201 Log1(PCSC_LOG_ERROR, "Locking failed");
00202 repeat--;
00203 if (repeat)
00204 {
00205 (void)SYS_USleep(100*1000);
00206 goto again;
00207 }
00208 }
00209
00210 #ifndef PCSCLITE_STATIC_DRIVER
00211 if (rContext->version == IFD_HVERSION_1_0)
00212
00213 rv = (*IO_close_channel) ();
00214 else
00215 rv = (*IFDH_close_channel) (rContext->slot);
00216 #else
00217 #ifdef IFDHANDLERv1
00218 rv = IO_Close_Channel();
00219 #else
00220 rv = IFDHCloseChannel(rContext->slot);
00221 #endif
00222 #endif
00223
00224
00225 (void)pthread_mutex_unlock(rContext->mMutex);
00226
00227 return rv;
00228 }
00229
00233 LONG IFDSetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
00234 DWORD dwLength, PUCHAR pucValue)
00235 {
00236 RESPONSECODE rv = IFD_SUCCESS;
00237
00238 #ifndef PCSCLITE_STATIC_DRIVER
00239 RESPONSECODE(*IFD_set_capabilities) (DWORD, PUCHAR) = NULL;
00240 RESPONSECODE(*IFDH_set_capabilities) (DWORD, DWORD, DWORD, PUCHAR) = NULL;
00241
00242 if (rContext->version == IFD_HVERSION_1_0)
00243 IFD_set_capabilities = rContext->psFunctions.psFunctions_v1.pvfSetCapabilities;
00244 else
00245 IFDH_set_capabilities = rContext->psFunctions.psFunctions_v2.pvfSetCapabilities;
00246 #endif
00247
00248
00249
00250
00251
00252
00253 #ifndef PCSCLITE_STATIC_DRIVER
00254 if (rContext->version == IFD_HVERSION_1_0)
00255 rv = (*IFD_set_capabilities) (dwTag, pucValue);
00256 else
00257 rv = (*IFDH_set_capabilities) (rContext->slot, dwTag,
00258 dwLength, pucValue);
00259 #else
00260 #ifdef IFDHANDLERv1
00261 rv = IFD_Set_Capabilities(dwTag, pucValue);
00262 #else
00263 rv = IFDHSetCapabilities(rContext->slot, dwTag, dwLength, pucValue);
00264 #endif
00265 #endif
00266
00267 return rv;
00268 }
00269
00275 LONG IFDGetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
00276 PDWORD pdwLength, PUCHAR pucValue)
00277 {
00278 RESPONSECODE rv = IFD_SUCCESS;
00279
00280 #ifndef PCSCLITE_STATIC_DRIVER
00281 RESPONSECODE(*IFD_get_capabilities) (DWORD, PUCHAR) = NULL;
00282 RESPONSECODE(*IFDH_get_capabilities) (DWORD, DWORD, PDWORD, PUCHAR) = NULL;
00283
00284 if (rContext->version == IFD_HVERSION_1_0)
00285 IFD_get_capabilities =
00286 rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
00287 else
00288 IFDH_get_capabilities =
00289 rContext->psFunctions.psFunctions_v2.pvfGetCapabilities;
00290 #endif
00291
00292
00293 (void)pthread_mutex_lock(rContext->mMutex);
00294
00295 #ifndef PCSCLITE_STATIC_DRIVER
00296 if (rContext->version == IFD_HVERSION_1_0)
00297 rv = (*IFD_get_capabilities) (dwTag, pucValue);
00298 else
00299 rv = (*IFDH_get_capabilities) (rContext->slot, dwTag,
00300 pdwLength, pucValue);
00301 #else
00302 #ifdef IFDHANDLERv1
00303 rv = IFD_Get_Capabilities(dwTag, pucValue);
00304 #else
00305 rv = IFDHGetCapabilities(rContext->slot, dwTag, pdwLength, pucValue);
00306 #endif
00307 #endif
00308
00309
00310 (void)pthread_mutex_unlock(rContext->mMutex);
00311
00312 return rv;
00313 }
00314
00318 LONG IFDPowerICC(READER_CONTEXT * rContext, DWORD dwAction,
00319 PUCHAR pucAtr, PDWORD pdwAtrLen)
00320 {
00321 RESPONSECODE rv;
00322 #ifndef PCSCLITE_STATIC_DRIVER
00323 short ret;
00324 SMARTCARD_EXTENSION sSmartCard;
00325 #endif
00326 DWORD dwStatus;
00327 UCHAR ucValue[1];
00328
00329 #ifndef PCSCLITE_STATIC_DRIVER
00330 RESPONSECODE(*IFD_power_icc) (DWORD) = NULL;
00331 RESPONSECODE(*IFDH_power_icc) (DWORD, DWORD, PUCHAR, PDWORD) = NULL;
00332 #endif
00333
00334
00335
00336
00337 rv = IFD_SUCCESS;
00338 dwStatus = 0;
00339 ucValue[0] = 0;
00340
00341
00342
00343
00344 (void)IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
00345
00346 if (dwStatus & SCARD_ABSENT)
00347 return SCARD_W_REMOVED_CARD;
00348 #ifndef PCSCLITE_STATIC_DRIVER
00349 if (rContext->version == IFD_HVERSION_1_0)
00350 IFD_power_icc = rContext->psFunctions.psFunctions_v1.pvfPowerICC;
00351 else
00352 IFDH_power_icc = rContext->psFunctions.psFunctions_v2.pvfPowerICC;
00353 #endif
00354
00355
00356 (void)pthread_mutex_lock(rContext->mMutex);
00357
00358 #ifndef PCSCLITE_STATIC_DRIVER
00359 if (rContext->version == IFD_HVERSION_1_0)
00360 {
00361 ucValue[0] = rContext->slot;
00362 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00363 rv = (*IFD_power_icc) (dwAction);
00364 }
00365 else
00366 {
00367 rv = (*IFDH_power_icc) (rContext->slot, dwAction,
00368 pucAtr, pdwAtrLen);
00369
00370 ret = ATRDecodeAtr(&sSmartCard, pucAtr, *pdwAtrLen);
00371 }
00372 #else
00373 #ifdef IFDHANDLERv1
00374 {
00375 ucValue[0] = rContext->slot;
00376 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00377 rv = IFD_Power_ICC(dwAction);
00378 }
00379 #else
00380 rv = IFDHPowerICC(rContext->slot, dwAction, pucAtr, pdwAtrLen);
00381 #endif
00382 #endif
00383
00384
00385 (void)pthread_mutex_unlock(rContext->mMutex);
00386
00387
00388 if (rv != IFD_SUCCESS)
00389 {
00390 *pdwAtrLen = 0;
00391 pucAtr[0] = '\0';
00392
00393 if (rv == IFD_NO_SUCH_DEVICE)
00394 {
00395 (void)SendHotplugSignal();
00396 return SCARD_E_READER_UNAVAILABLE;
00397 }
00398
00399 return SCARD_E_NOT_TRANSACTED;
00400 }
00401
00402
00403
00404
00405 if (rContext->version == IFD_HVERSION_1_0)
00406 (void)IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
00407
00408 return rv;
00409 }
00410
00415 LONG IFDStatusICC(READER_CONTEXT * rContext, PDWORD pdwStatus,
00416 PUCHAR pucAtr, PDWORD pdwAtrLen)
00417 {
00418 RESPONSECODE rv = IFD_SUCCESS;
00419 DWORD dwTag = 0, dwCardStatus = 0;
00420 SMARTCARD_EXTENSION sSmartCard;
00421 UCHAR ucValue[1] = "\x00";
00422
00423 #ifndef PCSCLITE_STATIC_DRIVER
00424 RESPONSECODE(*IFD_is_icc_present) (void) = NULL;
00425 RESPONSECODE(*IFDH_icc_presence) (DWORD) = NULL;
00426 RESPONSECODE(*IFD_get_capabilities) (DWORD, PUCHAR) = NULL;
00427
00428 if (rContext->version == IFD_HVERSION_1_0)
00429 {
00430 IFD_is_icc_present =
00431 rContext->psFunctions.psFunctions_v1.pvfICCPresence;
00432 IFD_get_capabilities =
00433 rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
00434 }
00435 else
00436 IFDH_icc_presence = rContext->psFunctions.psFunctions_v2.pvfICCPresence;
00437 #endif
00438
00439
00440 (void)pthread_mutex_lock(rContext->mMutex);
00441
00442 #ifndef PCSCLITE_STATIC_DRIVER
00443 if (rContext->version == IFD_HVERSION_1_0)
00444 {
00445 ucValue[0] = rContext->slot;
00446 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00447 rv = (*IFD_is_icc_present) ();
00448 }
00449 else
00450 rv = (*IFDH_icc_presence) (rContext->slot);
00451 #else
00452 #ifdef IFDHANDLERv1
00453 {
00454 ucValue[0] = rContext->slot;
00455 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00456 rv = IFD_Is_ICC_Present();
00457 }
00458 #else
00459 rv = IFDHICCPresence(rContext->slot);
00460 #endif
00461 #endif
00462
00463
00464 (void)pthread_mutex_unlock(rContext->mMutex);
00465
00466 if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
00467 dwCardStatus |= SCARD_PRESENT;
00468 else
00469 if (rv == IFD_ICC_NOT_PRESENT)
00470 dwCardStatus |= SCARD_ABSENT;
00471 else
00472 {
00473 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00474 *pdwStatus = SCARD_UNKNOWN;
00475
00476 if (rv == IFD_NO_SUCH_DEVICE)
00477 {
00478 (void)SendHotplugSignal();
00479 return SCARD_E_READER_UNAVAILABLE;
00480 }
00481
00482 return SCARD_E_NOT_TRANSACTED;
00483 }
00484
00485
00486
00487
00488
00489
00490
00491 if (rContext->version == IFD_HVERSION_1_0)
00492 {
00493 if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
00494 {
00495 short ret;
00496
00497 dwTag = TAG_IFD_ATR;
00498
00499
00500 (void)pthread_mutex_lock(rContext->mMutex);
00501
00502 ucValue[0] = rContext->slot;
00503 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00504
00505 #ifndef PCSCLITE_STATIC_DRIVER
00506 rv = (*IFD_get_capabilities) (dwTag, pucAtr);
00507 #else
00508 #ifdef IFDHANDLERv1
00509 rv = IFD_Get_Capabilities(dwTag, pucAtr);
00510 #endif
00511 #endif
00512
00513
00514 (void)pthread_mutex_unlock(rContext->mMutex);
00515
00516
00517
00518
00519
00520
00521 ret = ATRDecodeAtr(&sSmartCard, pucAtr, MAX_ATR_SIZE);
00522
00523
00524
00525
00526 if (ret == 0)
00527 *pdwAtrLen = 0;
00528 else
00529 *pdwAtrLen = sSmartCard.ATR.Length;
00530 }
00531 else
00532 {
00533
00534
00535
00536 *pdwAtrLen = 0;
00537 }
00538
00539
00540
00541 }
00542
00543 *pdwStatus = dwCardStatus;
00544
00545 return SCARD_S_SUCCESS;
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 LONG IFDControl_v2(READER_CONTEXT * rContext, PUCHAR TxBuffer,
00559 DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
00560 {
00561 RESPONSECODE rv = IFD_SUCCESS;
00562
00563 #ifndef PCSCLITE_STATIC_DRIVER
00564 RESPONSECODE(*IFDH_control_v2) (DWORD, PUCHAR, DWORD, PUCHAR,
00565 PDWORD);
00566 #endif
00567
00568 if (rContext->version != IFD_HVERSION_2_0)
00569 return SCARD_E_UNSUPPORTED_FEATURE;
00570
00571 #ifndef PCSCLITE_STATIC_DRIVER
00572 IFDH_control_v2 = rContext->psFunctions.psFunctions_v2.pvfControl;
00573 #endif
00574
00575
00576 (void)pthread_mutex_lock(rContext->mMutex);
00577
00578 #ifndef PCSCLITE_STATIC_DRIVER
00579 rv = (*IFDH_control_v2) (rContext->slot, TxBuffer, TxLength,
00580 RxBuffer, RxLength);
00581 #elif IFDHANDLERv2
00582 rv = IFDHControl(rContext->slot, TxBuffer, TxLength,
00583 RxBuffer, RxLength);
00584 #endif
00585
00586
00587 (void)pthread_mutex_unlock(rContext->mMutex);
00588
00589 if (rv == IFD_SUCCESS)
00590 return SCARD_S_SUCCESS;
00591 else
00592 {
00593 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00594 LogXxd(PCSC_LOG_DEBUG, "TxBuffer ", TxBuffer, TxLength);
00595 LogXxd(PCSC_LOG_DEBUG, "RxBuffer ", RxBuffer, *RxLength);
00596 return SCARD_E_NOT_TRANSACTED;
00597 }
00598 }
00599
00605
00606
00607
00608
00609 LONG IFDControl(READER_CONTEXT * rContext, DWORD ControlCode,
00610 LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength,
00611 LPDWORD BytesReturned)
00612 {
00613 RESPONSECODE rv = IFD_SUCCESS;
00614
00615 #ifndef PCSCLITE_STATIC_DRIVER
00616 RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
00617 #endif
00618
00619 if (rContext->version < IFD_HVERSION_3_0)
00620 return SCARD_E_UNSUPPORTED_FEATURE;
00621
00622 #ifndef PCSCLITE_STATIC_DRIVER
00623 IFDH_control = rContext->psFunctions.psFunctions_v3.pvfControl;
00624 #endif
00625
00626
00627 (void)pthread_mutex_lock(rContext->mMutex);
00628
00629 #ifndef PCSCLITE_STATIC_DRIVER
00630 rv = (*IFDH_control) (rContext->slot, ControlCode, TxBuffer,
00631 TxLength, RxBuffer, RxLength, BytesReturned);
00632 #elif IFDHANDLERv3
00633 rv = IFDHControl(rContext->slot, ControlCode, TxBuffer,
00634 TxLength, RxBuffer, RxLength, BytesReturned);
00635 #endif
00636
00637
00638 (void)pthread_mutex_unlock(rContext->mMutex);
00639
00640 if (rv == IFD_SUCCESS)
00641 return SCARD_S_SUCCESS;
00642 else
00643 {
00644 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00645 Log3(PCSC_LOG_DEBUG, "ControlCode: 0x%.8LX BytesReturned: %ld",
00646 ControlCode, *BytesReturned);
00647 LogXxd(PCSC_LOG_DEBUG, "TxBuffer ", TxBuffer, TxLength);
00648 LogXxd(PCSC_LOG_DEBUG, "RxBuffer ", RxBuffer, *BytesReturned);
00649
00650 if (rv == IFD_NO_SUCH_DEVICE)
00651 {
00652 (void)SendHotplugSignal();
00653 return SCARD_E_READER_UNAVAILABLE;
00654 }
00655
00656 if ((IFD_ERROR_NOT_SUPPORTED == rv) || (IFD_NOT_SUPPORTED == rv))
00657 return SCARD_E_UNSUPPORTED_FEATURE;
00658
00659 if (IFD_ERROR_INSUFFICIENT_BUFFER ==rv)
00660 return SCARD_E_INSUFFICIENT_BUFFER;
00661
00662 return SCARD_E_NOT_TRANSACTED;
00663 }
00664 }
00665
00669 LONG IFDTransmit(READER_CONTEXT * rContext, SCARD_IO_HEADER pioTxPci,
00670 PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer,
00671 PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
00672 {
00673 RESPONSECODE rv = IFD_SUCCESS;
00674
00675 #ifndef PCSCLITE_STATIC_DRIVER
00676 RESPONSECODE(*IFD_transmit_to_icc) (SCARD_IO_HEADER, PUCHAR, DWORD,
00677 PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00678 RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
00679 DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
00680 #endif
00681
00682
00683 DebugLogCategory(DEBUG_CATEGORY_APDU, pucTxBuffer, dwTxLength);
00684
00685 #ifndef PCSCLITE_STATIC_DRIVER
00686 if (rContext->version == IFD_HVERSION_1_0)
00687 IFD_transmit_to_icc =
00688 rContext->psFunctions.psFunctions_v1.pvfTransmitToICC;
00689 else
00690 IFDH_transmit_to_icc =
00691 rContext->psFunctions.psFunctions_v2.pvfTransmitToICC;
00692 #endif
00693
00694
00695 (void)pthread_mutex_lock(rContext->mMutex);
00696
00697 #ifndef PCSCLITE_STATIC_DRIVER
00698 if (rContext->version == IFD_HVERSION_1_0)
00699 {
00700 UCHAR ucValue[1];
00701
00702 ucValue[0] = rContext->slot;
00703 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00704 rv = (*IFD_transmit_to_icc) (pioTxPci, (LPBYTE) pucTxBuffer,
00705 dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
00706 }
00707 else
00708 rv = (*IFDH_transmit_to_icc) (rContext->slot, pioTxPci,
00709 (LPBYTE) pucTxBuffer, dwTxLength,
00710 pucRxBuffer, pdwRxLength, pioRxPci);
00711 #else
00712 #ifdef IFDHANDLERv1
00713 {
00714 UCHAR ucValue[1];
00715
00716 ucValue[0] = rContext->slot;
00717 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
00718 rv = IFD_Transmit_to_ICC(pioTxPci, (LPBYTE) pucTxBuffer,
00719 dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
00720 }
00721 #else
00722 rv = IFDHTransmitToICC(rContext->slot, pioTxPci,
00723 (LPBYTE) pucTxBuffer, dwTxLength,
00724 pucRxBuffer, pdwRxLength, pioRxPci);
00725 #endif
00726 #endif
00727
00728
00729 (void)pthread_mutex_unlock(rContext->mMutex);
00730
00731
00732 DebugLogCategory(DEBUG_CATEGORY_SW, pucRxBuffer, *pdwRxLength);
00733
00734 if (rv == IFD_SUCCESS)
00735 return SCARD_S_SUCCESS;
00736 else
00737 {
00738 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
00739
00740 if (rv == IFD_NO_SUCH_DEVICE)
00741 {
00742 (void)SendHotplugSignal();
00743 return SCARD_E_READER_UNAVAILABLE;
00744 }
00745
00746 return SCARD_E_NOT_TRANSACTED;
00747 }
00748 }
00749