LONG EHDestroyEventHandler(PREADER_CONTEXT rContext) { if (NULL == rContext->readerState) { Log1(PCSC_LOG_ERROR, "Thread never started (reader init failed?)"); return SCARD_S_SUCCESS; } PCSCD::SharedReaderState *rs = PCSCD::SharedReaderState::overlay(rContext->readerState); if ((rContext->pthThread == 0) || !rs || (rs->readerNameLength() == 0)) { Log1(PCSC_LOG_INFO, "Thread already stomped."); return SCARD_S_SUCCESS; } secdebug("pcscd", "EHDestroyEventHandler: pthThread: %p, reader name len: %ld", rContext->pthThread, rs->readerNameLength()); /* * Zero out the public status struct to allow it to be recycled and * used again */ rs->xreaderNameClear(); rs->xcardAtrClear(); rs->xreaderID(0); rs->xreaderState(0); rs->xlockState(0); rs->sharing(0); rs->xcardAtrLength(0); rs->xcardProtocol(SCARD_PROTOCOL_UNSET); // we only set this one to write to memory cache /* * Set the thread to 0 to exit thread */ ReaderContextLock(rContext); Log1(PCSC_LOG_INFO, "Stomping thread."); int ix; for (ix = 0; (ix < 100) && ReaderContextIsLocked(rContext); ++ix) { /* * Wait 0.05 seconds for the child to respond */ SYS_USleep(50000); } secdebug("pcscd", "EHDestroyEventHandler: post-stop dwLockId: %d", rContext->dwLockId); /* Zero the thread */ rContext->pthThread = 0; Log1(PCSC_LOG_INFO, "Thread stomped."); return SCARD_S_SUCCESS; }
/** * Close a communication channel to the IFD. */ LONG IFDCloseIFD(PREADER_CONTEXT rContext) { RESPONSECODE rv = IFD_SUCCESS; int repeat; #ifndef PCSCLITE_STATIC_DRIVER RESPONSECODE(*IO_close_channel) (void) = NULL; RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL; if (rContext->dwVersion == IFD_HVERSION_1_0) IO_close_channel = rContext->psFunctions.psFunctions_v1.pvfCloseChannel; else IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel; #endif /* TRY TO LOCK THIS CODE REGION */ repeat = 5; again: rv = SYS_MutexTryLock(rContext->mMutex); if (EBUSY == rv) { Log1(PCSC_LOG_ERROR, "Locking failed"); repeat--; if (repeat) { (void)SYS_USleep(100*1000); /* 100 ms */ goto again; } } #ifndef PCSCLITE_STATIC_DRIVER if (rContext->dwVersion == IFD_HVERSION_1_0) rv = (*IO_close_channel) (); else rv = (*IFDH_close_channel) (rContext->dwSlot); #else if (rContext->dwVersion == IFD_HVERSION_1_0) rv = IO_Close_Channel(); else rv = IFDHCloseChannel(rContext->dwSlot); #endif /* END OF LOCKED REGION */ (void)SYS_MutexUnLock(rContext->mMutex); return rv; }
/** * Close a communication channel to the IFD. */ LONG IFDCloseIFD(READER_CONTEXT * rContext) { RESPONSECODE rv; int repeat; #ifndef PCSCLITE_STATIC_DRIVER RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL; IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel; #endif /* TRY TO LOCK THIS CODE REGION */ repeat = 5; again: rv = pthread_mutex_trylock(rContext->mMutex); if (EBUSY == rv) { Log1(PCSC_LOG_ERROR, "Locking failed"); repeat--; if (repeat) { (void)SYS_USleep(100*1000); /* 100 ms */ goto again; } } #ifndef PCSCLITE_STATIC_DRIVER rv = (*IFDH_close_channel) (rContext->slot); #else rv = IFDHCloseChannel(rContext->slot); #endif /* END OF LOCKED REGION */ (void)pthread_mutex_unlock(rContext->mMutex); return rv; }
LONG SCardConnect(/*@unused@*/ SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) { LONG rv; PREADER_CONTEXT rContext = NULL; DWORD dwStatus; (void)hContext; PROFILE_START /* * Check for NULL parameters */ if (szReader == NULL || phCard == NULL || pdwActiveProtocol == NULL) return SCARD_E_INVALID_PARAMETER; else *phCard = 0; if ((dwShareMode != SCARD_SHARE_DIRECT) && !(dwPreferredProtocols & SCARD_PROTOCOL_T0) && !(dwPreferredProtocols & SCARD_PROTOCOL_T1) && !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) && !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)) return SCARD_E_PROTO_MISMATCH; if (dwShareMode != SCARD_SHARE_EXCLUSIVE && dwShareMode != SCARD_SHARE_SHARED && dwShareMode != SCARD_SHARE_DIRECT) return SCARD_E_INVALID_VALUE; Log3(PCSC_LOG_DEBUG, "Attempting Connect to %s using protocol: %d", szReader, dwPreferredProtocols); rv = RFReaderInfo((LPSTR) szReader, &rContext); if (rv != SCARD_S_SUCCESS) { Log2(PCSC_LOG_ERROR, "Reader %s Not Found", szReader); return rv; } /* * Make sure the reader is working properly */ rv = RFCheckReaderStatus(rContext); if (rv != SCARD_S_SUCCESS) return rv; /******************************************* * * This section checks for simple errors * *******************************************/ /* * Connect if not exclusive mode */ if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT) { Log1(PCSC_LOG_ERROR, "Error Reader Exclusive"); return SCARD_E_SHARING_VIOLATION; } /* * wait until a possible transaction is finished */ if (rContext->dwLockId != 0) { Log1(PCSC_LOG_INFO, "Waiting for release of lock"); while (rContext->dwLockId != 0) (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE); Log1(PCSC_LOG_INFO, "Lock released"); } /* the reader has been removed while we were waiting */ if (NULL == rContext->readerState) return SCARD_E_NO_SMARTCARD; /******************************************* * * This section tries to determine the * presence of a card or not * *******************************************/ dwStatus = rContext->readerState->readerState; if (dwShareMode != SCARD_SHARE_DIRECT) { if (!(dwStatus & SCARD_PRESENT)) { Log1(PCSC_LOG_ERROR, "Card Not Inserted"); return SCARD_E_NO_SMARTCARD; } if (dwStatus & SCARD_SWALLOWED) { Log1(PCSC_LOG_ERROR, "Card Not Powered"); return SCARD_W_UNPOWERED_CARD; } } /******************************************* * * This section tries to decode the ATR * and set up which protocol to use * *******************************************/ if (dwPreferredProtocols & SCARD_PROTOCOL_RAW) rContext->readerState->cardProtocol = SCARD_PROTOCOL_RAW; else { if (dwShareMode != SCARD_SHARE_DIRECT) { /* lock here instead in IFDSetPTS() to lock up to * setting rContext->readerState->cardProtocol */ (void)SYS_MutexLock(rContext->mMutex); /* the protocol is not yet set (no PPS yet) */ if (SCARD_PROTOCOL_UNDEFINED == rContext->readerState->cardProtocol) { UCHAR ucAvailable, ucDefault; int ret; ucDefault = PHGetDefaultProtocol(rContext->readerState->cardAtr, rContext->readerState->cardAtrLength); ucAvailable = PHGetAvailableProtocols(rContext->readerState->cardAtr, rContext->readerState->cardAtrLength); /* * If it is set to ANY let it do any of the protocols */ if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD) dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1; ret = PHSetProtocol(rContext, dwPreferredProtocols, ucAvailable, ucDefault); /* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error */ if (SET_PROTOCOL_PPS_FAILED == ret) { (void)SYS_MutexUnLock(rContext->mMutex); return SCARD_W_UNRESPONSIVE_CARD; } if (SET_PROTOCOL_WRONG_ARGUMENT == ret) { (void)SYS_MutexUnLock(rContext->mMutex); return SCARD_E_PROTO_MISMATCH; } /* use negotiated protocol */ rContext->readerState->cardProtocol = ret; (void)SYS_MutexUnLock(rContext->mMutex); } else { (void)SYS_MutexUnLock(rContext->mMutex); if (! (dwPreferredProtocols & rContext->readerState->cardProtocol)) return SCARD_E_PROTO_MISMATCH; } } else rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; } *pdwActiveProtocol = rContext->readerState->cardProtocol; if (dwShareMode != SCARD_SHARE_DIRECT) { if ((*pdwActiveProtocol != SCARD_PROTOCOL_T0) && (*pdwActiveProtocol != SCARD_PROTOCOL_T1)) Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %d", *pdwActiveProtocol); else Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d", (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1); } else Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected"); /* * Prepare the SCARDHANDLE identity */ *phCard = RFCreateReaderHandle(rContext); Log2(PCSC_LOG_DEBUG, "hCard Identity: %x", *phCard); /******************************************* * * This section tries to set up the * exclusivity modes. -1 is exclusive * *******************************************/ if (dwShareMode == SCARD_SHARE_EXCLUSIVE) { if (rContext->dwContexts == SCARD_NO_CONTEXT) { rContext->dwContexts = SCARD_EXCLUSIVE_CONTEXT; (void)RFLockSharing(*phCard); } else { (void)RFDestroyReaderHandle(*phCard); *phCard = 0; return SCARD_E_SHARING_VIOLATION; } } else { /* * Add a connection to the context stack */ rContext->dwContexts += 1; } /* * Add this handle to the handle list */ rv = RFAddReaderHandle(rContext, *phCard); if (rv != SCARD_S_SUCCESS) { /* * Clean up - there is no more room */ (void)RFDestroyReaderHandle(*phCard); if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT) rContext->dwContexts = SCARD_NO_CONTEXT; else if (rContext->dwContexts > SCARD_NO_CONTEXT) rContext->dwContexts -= 1; *phCard = 0; PROFILE_END return SCARD_F_INTERNAL_ERROR; }
static void EHStatusHandlerThread(READER_CONTEXT * rContext) { LONG rv; const char *readerName; DWORD dwStatus; uint32_t readerState; int32_t readerSharing; DWORD dwCurrentState; DWORD dwAtrLen; /* * Zero out everything */ dwStatus = 0; readerName = rContext->readerState->readerName; rv = IFDStatusICC(rContext, &dwStatus); if ((SCARD_S_SUCCESS == rv) && (dwStatus & SCARD_PRESENT)) { #ifdef DISABLE_AUTO_POWER_ON rContext->readerState->cardAtrLength = 0; rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; readerState = SCARD_PRESENT; Log1(PCSC_LOG_INFO, "Skip card power on"); #else dwAtrLen = sizeof(rContext->readerState->cardAtr); rv = IFDPowerICC(rContext, IFD_POWER_UP, rContext->readerState->cardAtr, &dwAtrLen); rContext->readerState->cardAtrLength = dwAtrLen; /* the protocol is unset after a power on */ rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; if (rv == IFD_SUCCESS) { readerState = SCARD_PRESENT | SCARD_POWERED | SCARD_NEGOTIABLE; rContext->powerState = POWER_STATE_POWERED; Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_POWERED"); if (rContext->readerState->cardAtrLength > 0) { LogXxd(PCSC_LOG_INFO, "Card ATR: ", rContext->readerState->cardAtr, rContext->readerState->cardAtrLength); } else Log1(PCSC_LOG_INFO, "Card ATR: (NULL)"); } else { readerState = SCARD_PRESENT | SCARD_SWALLOWED; rContext->powerState = POWER_STATE_UNPOWERED; Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_UNPOWERED"); Log3(PCSC_LOG_ERROR, "Error powering up card: %d 0x%04X", rv, rv); } #endif dwCurrentState = SCARD_PRESENT; } else { readerState = SCARD_ABSENT; rContext->readerState->cardAtrLength = 0; rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; dwCurrentState = SCARD_ABSENT; } /* * Set all the public attributes to this reader */ rContext->readerState->readerState = readerState; rContext->readerState->readerSharing = readerSharing = rContext->contexts; (void)EHSignalEventToClients(); while (1) { dwStatus = 0; rv = IFDStatusICC(rContext, &dwStatus); if (rv != SCARD_S_SUCCESS) { Log2(PCSC_LOG_ERROR, "Error communicating to: %s", readerName); /* * Set error status on this reader while errors occur */ rContext->readerState->readerState = SCARD_UNKNOWN; rContext->readerState->cardAtrLength = 0; rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; dwCurrentState = SCARD_UNKNOWN; (void)EHSignalEventToClients(); } if (dwStatus & SCARD_ABSENT) { if (dwCurrentState == SCARD_PRESENT || dwCurrentState == SCARD_UNKNOWN) { /* * Change the status structure */ Log2(PCSC_LOG_INFO, "Card Removed From %s", readerName); /* * Notify the card has been removed */ (void)RFSetReaderEventState(rContext, SCARD_REMOVED); rContext->readerState->cardAtrLength = 0; rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; rContext->readerState->readerState = SCARD_ABSENT; dwCurrentState = SCARD_ABSENT; rContext->readerState->eventCounter++; (void)EHSignalEventToClients(); } } else if (dwStatus & SCARD_PRESENT) { if (dwCurrentState == SCARD_ABSENT || dwCurrentState == SCARD_UNKNOWN) { #ifdef DISABLE_AUTO_POWER_ON rContext->readerState->cardAtrLength = 0; rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; rContext->readerState->readerState = SCARD_PRESENT; rContext->powerState = POWER_STATE_UNPOWERED; Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_UNPOWERED"); readerState = SCARD_PRESENT; rv = IFD_SUCCESS; Log1(PCSC_LOG_INFO, "Skip card power on"); #else /* * Power and reset the card */ dwAtrLen = sizeof(rContext->readerState->cardAtr); rv = IFDPowerICC(rContext, IFD_POWER_UP, rContext->readerState->cardAtr, &dwAtrLen); rContext->readerState->cardAtrLength = dwAtrLen; /* the protocol is unset after a power on */ rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; if (rv == IFD_SUCCESS) { rContext->readerState->readerState = SCARD_PRESENT | SCARD_POWERED | SCARD_NEGOTIABLE; rContext->powerState = POWER_STATE_POWERED; Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_POWERED"); } else { rContext->readerState->readerState = SCARD_PRESENT | SCARD_SWALLOWED; rContext->powerState = POWER_STATE_UNPOWERED; Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_UNPOWERED"); rContext->readerState->cardAtrLength = 0; } #endif dwCurrentState = SCARD_PRESENT; rContext->readerState->eventCounter++; Log2(PCSC_LOG_INFO, "Card inserted into %s", readerName); (void)EHSignalEventToClients(); if (rv == IFD_SUCCESS) { if (rContext->readerState->cardAtrLength > 0) { LogXxd(PCSC_LOG_INFO, "Card ATR: ", rContext->readerState->cardAtr, rContext->readerState->cardAtrLength); } else Log1(PCSC_LOG_INFO, "Card ATR: (NULL)"); } else Log1(PCSC_LOG_ERROR,"Error powering up card."); } } /* * Sharing may change w/o an event pass it on */ if (readerSharing != rContext->contexts) { readerSharing = rContext->contexts; rContext->readerState->readerSharing = readerSharing; (void)EHSignalEventToClients(); } if (rContext->pthCardEvent) { int ret; int timeout; #ifndef DISABLE_ON_DEMAND_POWER_ON if (POWER_STATE_POWERED == rContext->powerState) /* The card is powered but not yet used */ timeout = PCSCLITE_POWER_OFF_GRACE_PERIOD; else /* The card is already in use or not used at all */ #endif timeout = PCSCLITE_STATUS_EVENT_TIMEOUT; ret = rContext->pthCardEvent(rContext->slot, timeout); if (IFD_SUCCESS != ret) (void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE); } else (void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE); #ifndef DISABLE_ON_DEMAND_POWER_ON /* the card is powered but not used */ (void)pthread_mutex_lock(&rContext->powerState_lock); if (POWER_STATE_POWERED == rContext->powerState) { /* power down */ IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL); rContext->powerState = POWER_STATE_UNPOWERED; Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_UNPOWERED"); /* the protocol is unset after a power down */ rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; } /* the card was in use */ if (POWER_STATE_GRACE_PERIOD == rContext->powerState) { /* the next state should be UNPOWERED unless the * card is used again */ rContext->powerState = POWER_STATE_POWERED; Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_POWERED"); } (void)pthread_mutex_unlock(&rContext->powerState_lock); #endif if (rContext->hLockId == 0xFFFF) { /* * Exit and notify the caller */ (void)EHSignalEventToClients(); Log1(PCSC_LOG_INFO, "Die"); rContext->hLockId = 0; (void)pthread_exit(NULL); } } }
void EHStatusHandlerThread(PREADER_CONTEXT rContext) { LONG rv; LPCSTR lpcReader; DWORD dwStatus, dwReaderSharing; DWORD dwCurrentState; int pageSize = SYS_GetPageSize(); /* * Zero out everything */ dwStatus = 0; dwReaderSharing = 0; dwCurrentState = 0; secdebug("pcscd", "EHStatusHandlerThread: rContext: 0x%p", rContext); lpcReader = rContext->lpcReader; PCSCD::SharedReaderState *rs = PCSCD::SharedReaderState::overlay(rContext->readerState); DWORD tmpCardAtrLength = MAX_ATR_SIZE; rv = IFDStatusICC(rContext, &dwStatus, rs->xcardAtr(), &tmpCardAtrLength); secdebug("pcscd", "EHStatusHandlerThread: initial call to IFDStatusICC: %d [%04X]", rv, rv); if (dwStatus & SCARD_PRESENT) { tmpCardAtrLength = MAX_ATR_SIZE; rv = IFDPowerICC(rContext, IFD_POWER_UP, rs->xcardAtr(), &tmpCardAtrLength); /* the protocol is unset after a power on */ rs->xcardProtocol(SCARD_PROTOCOL_UNSET); secdebug("pcscd", "EHStatusHandlerThread: initial call to IFDPowerICC: %d [%04X]", rv, rv); if (rv == IFD_SUCCESS) { rs->xcardAtrLength(tmpCardAtrLength); dwStatus |= SCARD_PRESENT; dwStatus &= ~SCARD_ABSENT; dwStatus |= SCARD_POWERED; dwStatus |= SCARD_NEGOTIABLE; dwStatus &= ~SCARD_SPECIFIC; dwStatus &= ~SCARD_SWALLOWED; dwStatus &= ~SCARD_UNKNOWN; if (rs->xcardAtrLength() > 0) { LogXxd(PCSC_LOG_INFO, "Card ATR: ", rs->xcardAtr(), rs->xcardAtrLength()); } else Log1(PCSC_LOG_INFO, "Card ATR: (NULL)"); } else { dwStatus |= SCARD_PRESENT; dwStatus &= ~SCARD_ABSENT; dwStatus |= SCARD_SWALLOWED; dwStatus &= ~SCARD_POWERED; dwStatus &= ~SCARD_NEGOTIABLE; dwStatus &= ~SCARD_SPECIFIC; dwStatus &= ~SCARD_UNKNOWN; Log3(PCSC_LOG_ERROR, "Error powering up card: %d 0x%04X", rv, rv); } dwCurrentState = SCARD_PRESENT; } else { dwStatus |= SCARD_ABSENT; dwStatus &= ~SCARD_PRESENT; dwStatus &= ~SCARD_POWERED; dwStatus &= ~SCARD_NEGOTIABLE; dwStatus &= ~SCARD_SPECIFIC; dwStatus &= ~SCARD_SWALLOWED; dwStatus &= ~SCARD_UNKNOWN; rs->xcardAtrLength(0); rs->xcardProtocol(SCARD_PROTOCOL_UNSET); dwCurrentState = SCARD_ABSENT; } /* * Set all the public attributes to this reader */ rs->xreaderState(dwStatus); dwReaderSharing = rContext->dwContexts; rs->sharing(dwReaderSharing); SYS_MMapSynchronize((void *) rContext->readerState, pageSize); while (1) { dwStatus = 0; // Defensive measure if (!rContext->vHandle) { // Exit and notify the caller secdebug("pcscd", "EHStatusHandlerThread: lost dynamic callbacks ??"); ReaderContextUnlock(rContext); SYS_ThreadDetach(rContext->pthThread); SYS_ThreadExit(0); } DWORD tmpCardAtrLength = MAX_ATR_SIZE; rv = IFDStatusICC(rContext, &dwStatus, rs->xcardAtr(), &tmpCardAtrLength); if (rv != SCARD_S_SUCCESS) { Log2(PCSC_LOG_ERROR, "Error communicating to: %s", lpcReader); /* * Set error status on this reader while errors occur */ DWORD readerStateTmp = rs->xreaderState(); readerStateTmp &= ~SCARD_ABSENT; readerStateTmp &= ~SCARD_PRESENT; readerStateTmp &= ~SCARD_POWERED; readerStateTmp &= ~SCARD_NEGOTIABLE; readerStateTmp &= ~SCARD_SPECIFIC; readerStateTmp &= ~SCARD_SWALLOWED; readerStateTmp |= SCARD_UNKNOWN; rs->xcardAtrLength(0); rs->xcardProtocol(SCARD_PROTOCOL_UNSET); rs->xreaderState(readerStateTmp); dwCurrentState = SCARD_UNKNOWN; SYS_MMapSynchronize((void *) rContext->readerState, pageSize); /* * This code causes race conditions on G4's with USB * insertion */ /* * dwErrorCount += 1; SYS_Sleep(1); */ /* * After 10 seconds of errors, try to reinitialize the reader * This sometimes helps bring readers out of *crazy* states. */ /* * if ( dwErrorCount == 10 ) { RFUnInitializeReader( rContext * ); RFInitializeReader( rContext ); dwErrorCount = 0; } */ /* * End of race condition code block */ } if (dwStatus & SCARD_ABSENT) { if (dwCurrentState == SCARD_PRESENT || dwCurrentState == SCARD_UNKNOWN) { /* * Change the status structure */ Log2(PCSC_LOG_INFO, "Card Removed From %s", lpcReader); /* * Notify the card has been removed */ RFSetReaderEventState(rContext, SCARD_REMOVED); rs->xcardAtrLength(0); rs->xcardProtocol(SCARD_PROTOCOL_UNSET); DWORD readerStateTmp = rs->xreaderState(); readerStateTmp |= SCARD_ABSENT; readerStateTmp &= ~SCARD_UNKNOWN; readerStateTmp &= ~SCARD_PRESENT; readerStateTmp &= ~SCARD_POWERED; readerStateTmp &= ~SCARD_NEGOTIABLE; readerStateTmp &= ~SCARD_SWALLOWED; readerStateTmp &= ~SCARD_SPECIFIC; rs->xreaderState(readerStateTmp); dwCurrentState = SCARD_ABSENT; SYS_MMapSynchronize((void *) rContext->readerState, pageSize); } } else if (dwStatus & SCARD_PRESENT) { if (dwCurrentState == SCARD_ABSENT || dwCurrentState == SCARD_UNKNOWN) { /* * Power and reset the card */ SYS_USleep(PCSCLITE_STATUS_WAIT); DWORD tmpCardAtrLength = MAX_ATR_SIZE; rv = IFDPowerICC(rContext, IFD_POWER_UP, rs->xcardAtr(), &tmpCardAtrLength); /* the protocol is unset after a power on */ rs->xcardProtocol(SCARD_PROTOCOL_UNSET); secdebug("pcscd", "EHStatusHandlerThread: power-and-reset call to IFDPowerICC: %d [%04X]", rv, rv); DWORD readerStateTmp = rs->xreaderState(); if (rv == IFD_SUCCESS) { rs->xcardAtrLength(tmpCardAtrLength); readerStateTmp |= SCARD_PRESENT; readerStateTmp &= ~SCARD_ABSENT; readerStateTmp |= SCARD_POWERED; readerStateTmp |= SCARD_NEGOTIABLE; readerStateTmp &= ~SCARD_SPECIFIC; readerStateTmp &= ~SCARD_UNKNOWN; readerStateTmp &= ~SCARD_SWALLOWED; rs->xreaderState(readerStateTmp); /* * Notify the card has been reset */ RFSetReaderEventState(rContext, SCARD_RESET); } else { readerStateTmp |= SCARD_PRESENT; readerStateTmp &= ~SCARD_ABSENT; readerStateTmp |= SCARD_SWALLOWED; readerStateTmp &= ~SCARD_POWERED; readerStateTmp &= ~SCARD_NEGOTIABLE; readerStateTmp &= ~SCARD_SPECIFIC; readerStateTmp &= ~SCARD_UNKNOWN; rs->xreaderState(readerStateTmp); rs->xcardAtrLength(0); } dwCurrentState = SCARD_PRESENT; SYS_MMapSynchronize((void *) rContext->readerState, pageSize); Log2(PCSC_LOG_INFO, "Card inserted into %s", lpcReader); if (rv == IFD_SUCCESS) { if (rs->xcardAtrLength() > 0) LogXxd(PCSC_LOG_INFO, "Card ATR: ", rs->xcardAtr(), rs->xcardAtrLength()); else Log1(PCSC_LOG_INFO, "Card ATR: (NULL)"); } else Log1(PCSC_LOG_ERROR,"Error powering up card."); } } if (ReaderContextIsLocked(rContext)) { /* * Exit and notify the caller */ secdebug("pcscd", "EHStatusHandlerThread: parent requested shutdown"); ReaderContextUnlock(rContext); SYS_ThreadDetach(rContext->pthThread); SYS_ThreadExit(0); } /* * Sharing may change w/o an event pass it on */ if (dwReaderSharing != (uint32_t)rContext->dwContexts) { dwReaderSharing = rContext->dwContexts; rs->sharing(dwReaderSharing); SYS_MMapSynchronize((void *) rContext->readerState, pageSize); } SYS_USleep(PCSCLITE_STATUS_POLL_RATE); } }