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