64static void * EHStatusHandlerThread(READER_CONTEXT *);
66LONG EHRegisterClientForEvent(int32_t filedes)
81 Log2(PCSC_LOG_ERROR,
"Client %d already in list", filedes);
119 Log2(PCSC_LOG_ERROR,
"Can't remove client: %d", filedes);
146LONG EHInitializeEventStructures(
void)
161LONG EHDeinitializeEventStructures(
void)
169void EHDestroyEventHandler(READER_CONTEXT * rContext)
177 Log1(PCSC_LOG_INFO,
"Thread already stomped.");
186 Log1(PCSC_LOG_INFO,
"Stomping thread.");
189 dwGetSize =
sizeof(ucGetData);
191 &dwGetSize, ucGetData);
193 if ((
IFD_SUCCESS == rv) && (1 == dwGetSize) && ucGetData[0])
195 Log1(PCSC_LOG_INFO,
"Killing polling thread");
196 (void)pthread_cancel(rContext->
pthThread);
201 RESPONSECODE (*fct)(DWORD) = NULL;
203 dwGetSize =
sizeof(fct);
205 &dwGetSize, (PUCHAR)&fct);
207 if ((
IFD_SUCCESS == rv) && (dwGetSize ==
sizeof(fct)))
209 Log1(PCSC_LOG_INFO,
"Request stopping of polling thread");
213 Log1(PCSC_LOG_INFO,
"Waiting polling thread");
217 rv = pthread_join(rContext->
pthThread, NULL);
219 Log2(PCSC_LOG_ERROR,
"pthread_join failed: %s", strerror(rv));
224 Log1(PCSC_LOG_INFO,
"Thread stomped.");
229LONG EHSpawnEventHandler(READER_CONTEXT * rContext)
237 Log2(PCSC_LOG_ERROR,
"Initial Check Failed on %s",
242 rv = ThreadCreate(&rContext->
pthThread, 0,
243 (PCSCLITE_THREAD_FUNCTION( ))EHStatusHandlerThread, (LPVOID) rContext);
246 Log2(PCSC_LOG_ERROR,
"ThreadCreate failed: %s", strerror(rv));
253static void * EHStatusHandlerThread(READER_CONTEXT * rContext)
257 const char *readerName;
260 uint32_t readerState;
261 int32_t readerSharing;
262 DWORD dwCurrentState;
263#ifndef DISABLE_AUTO_POWER_ON
280#ifdef DISABLE_AUTO_POWER_ON
284 Log1(PCSC_LOG_INFO,
"Skip card power on");
297 RFSetPowerState(rContext, POWER_STATE_POWERED);
298 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_POWERED");
302 LogXxd(PCSC_LOG_INFO,
"Card ATR: ",
307 Log1(PCSC_LOG_INFO,
"Card ATR: (NULL)");
312 RFSetPowerState(rContext, POWER_STATE_UNPOWERED);
313 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_UNPOWERED");
314 Log2(PCSC_LOG_ERROR,
"Error powering up card: %s", rv2text(rv));
345 Log2(PCSC_LOG_ERROR,
"Error communicating to: %s", readerName);
367 Log2(PCSC_LOG_INFO,
"Card Removed From %s", readerName);
371 (void)RFSetReaderEventState(rContext, SCARD_REMOVED);
391#ifdef DISABLE_AUTO_POWER_ON
395 RFSetPowerState(rContext, POWER_STATE_UNPOWERED);
396 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_UNPOWERED");
398 Log1(PCSC_LOG_INFO,
"Skip card power on");
414 RFSetPowerState(rContext, POWER_STATE_POWERED);
415 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_POWERED");
420 RFSetPowerState(rContext, POWER_STATE_UNPOWERED);
421 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_UNPOWERED");
432 Log2(PCSC_LOG_INFO,
"Card inserted into %s", readerName);
440 LogXxd(PCSC_LOG_INFO,
"Card ATR: ",
445 Log1(PCSC_LOG_INFO,
"Card ATR: (NULL)");
448 Log1(PCSC_LOG_ERROR,
"Error powering up card.");
455 if (readerSharing != rContext->
contexts)
467#ifndef DISABLE_ON_DEMAND_POWER_ON
470 timeout = PCSCLITE_POWER_OFF_GRACE_PERIOD;
474 timeout = PCSCLITE_STATUS_EVENT_TIMEOUT;
483#ifndef DISABLE_ON_DEMAND_POWER_ON
486 if (POWER_STATE_POWERED == rContext->
powerState)
491 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_UNPOWERED");
498 if (POWER_STATE_GRACE_PERIOD == rContext->
powerState)
503 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_POWERED");
508 if (rContext->
hLockId == 0xFFFF)
513 Log1(PCSC_LOG_INFO,
"Die");
515 (void)pthread_exit(NULL);
This abstracts dynamic library loading functions.
static list_t ClientsWaitingForEvent
list of client file descriptors
LONG EHTryToUnregisterClientForEvent(int32_t filedes)
Try to unregister a client If no client is found then do not log an error.
void EHSignalEventToClients(void)
Sends an asynchronous event to any waiting client.
pthread_mutex_t ClientsWaitingForEvent_lock
lock for the above list
LONG EHUnregisterClientForEvent(int32_t filedes)
Unregister a client and log an error if the client is not found.
This handles card insertion/removal events, updates ATR, protocol, and status information.
#define SCARD_F_INTERNAL_ERROR
An internal consistency check failed.
#define SCARD_F_UNKNOWN_ERROR
An internal error has been detected, but the source is unknown.
#define SCARD_S_SUCCESS
No error was encountered.
#define SCARD_E_NO_MEMORY
Not enough memory available to complete this command.
#define SCARD_E_INVALID_VALUE
One or more of the supplied parameters values could not be properly interpreted.
#define IFD_POWER_UP
power up the card
#define TAG_IFD_STOP_POLLING_THREAD
method used to stop the polling thread (instead of just pthread_kill())
#define IFD_POWER_DOWN
power down the card
#define TAG_IFD_POLLING_THREAD_KILLABLE
the polling thread can be killed
#define IFD_SUCCESS
no error
LONG IFDStatusICC(READER_CONTEXT *rContext, PDWORD pdwStatus, bool hotplug)
Provide statistical information about the IFD and ICC including insertions, atr, powering status/etc.
RESPONSECODE IFDGetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, PDWORD pdwLength, PUCHAR pucValue)
Gets capabilities in the reader.
RESPONSECODE IFDPowerICC(READER_CONTEXT *rContext, DWORD dwAction, PUCHAR pucAtr, PDWORD pdwAtrLen)
Power up/down or reset's an ICC located in the IFD.
This wraps the dynamic ifdhandler functions.
#define SCARD_SWALLOWED
Card not powered.
#define SCARD_PROTOCOL_UNDEFINED
protocol not set
#define SCARD_PRESENT
Card is present.
#define SCARD_POWERED
Card is powered.
#define SCARD_ABSENT
Card is absent.
#define SCARD_UNKNOWN
Unknown state.
#define SCARD_NEGOTIABLE
Ready for PTS.
This handles protocol defaults, PTS, etc.
int RFGetPowerState(READER_CONTEXT *rContext)
Wait until all connected readers have a chance to power up a possibly inserted card.
This keeps track of a list of currently available reader structures.
READER_STATE readerState
reader state
RESPONSECODE(* pthCardEvent)(DWORD, int)
Card Event sync.
pthread_mutex_t powerState_lock
powerState mutex
pthread_t pthThread
Event polling thread.
_Atomic int32_t contexts
Number of open contexts.
int slot
Current Reader Slot.
_Atomic SCARDHANDLE hLockId
Lock Id.
int powerState
auto power off state
_Atomic int32_t readerSharing
PCSCLITE_SHARING_* sharing status.
char readerName[MAX_READERNAME]
reader name
uint32_t cardProtocol
SCARD_PROTOCOL_* value.
UCHAR cardAtr[MAX_ATR_SIZE]
ATR.
uint32_t eventCounter
number of card events
_Atomic uint32_t cardAtrLength
ATR length.
uint32_t readerState
SCARD_* bit field.
This handles abstract system level calls.
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
This demarshalls functions over the message queue and keeps track of clients and their handles.