40 #include <sys/types.h>
66 LONG EHRegisterClientForEvent(int32_t filedes)
70 (void)list_append(&ClientsWaitingForEvent, &filedes);
88 ret = list_delete(&ClientsWaitingForEvent, &filedes);
106 Log2(PCSC_LOG_ERROR,
"Can't remove client: %d", filedes);
120 (void)list_iterator_start(&ClientsWaitingForEvent);
121 while (list_iterator_hasnext(&ClientsWaitingForEvent))
123 filedes = *(int32_t *)list_iterator_next(&ClientsWaitingForEvent);
126 (void)list_iterator_stop(&ClientsWaitingForEvent);
128 (void)list_clear(&ClientsWaitingForEvent);
133 LONG EHInitializeEventStructures(
void)
135 (void)list_init(&ClientsWaitingForEvent);
138 (void)list_attributes_copy(&ClientsWaitingForEvent, list_meter_int32_t, 1);
141 (void)list_attributes_comparator(&ClientsWaitingForEvent, list_comparator_int32_t);
148 LONG EHDeinitializeEventStructures(
void)
150 list_destroy(&ClientsWaitingForEvent);
164 Log1(PCSC_LOG_INFO,
"Thread already stomped.");
173 Log1(PCSC_LOG_INFO,
"Stomping thread.");
176 dwGetSize =
sizeof(ucGetData);
178 &dwGetSize, ucGetData);
180 if ((
IFD_SUCCESS == rv) && (1 == dwGetSize) && ucGetData[0])
182 Log1(PCSC_LOG_INFO,
"Killing polling thread");
183 (void)pthread_cancel(rContext->
pthThread);
188 RESPONSECODE (*fct)(DWORD) = NULL;
190 dwGetSize =
sizeof(fct);
192 &dwGetSize, (PUCHAR)&fct);
194 if ((
IFD_SUCCESS == rv) && (dwGetSize ==
sizeof(fct)))
196 Log1(PCSC_LOG_INFO,
"Request stopping of polling thread");
200 Log1(PCSC_LOG_INFO,
"Waiting polling thread");
204 rv = pthread_join(rContext->
pthThread, NULL);
206 Log2(PCSC_LOG_ERROR,
"pthread_join failed: %s", strerror(rv));
211 Log1(PCSC_LOG_INFO,
"Thread stomped.");
224 Log2(PCSC_LOG_ERROR,
"Initial Check Failed on %s",
229 rv = ThreadCreate(&rContext->
pthThread, 0,
230 (PCSCLITE_THREAD_FUNCTION( ))EHStatusHandlerThread, (LPVOID) rContext);
233 Log2(PCSC_LOG_ERROR,
"ThreadCreate failed: %s", strerror(rv));
244 const char *readerName;
247 uint32_t readerState;
248 int32_t readerSharing;
249 DWORD dwCurrentState;
250 #ifndef DISABLE_AUTO_POWER_ON
267 #ifdef DISABLE_AUTO_POWER_ON
271 Log1(PCSC_LOG_INFO,
"Skip card power on");
284 RFSetPowerState(rContext, POWER_STATE_POWERED);
285 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_POWERED");
289 LogXxd(PCSC_LOG_INFO,
"Card ATR: ",
294 Log1(PCSC_LOG_INFO,
"Card ATR: (NULL)");
299 RFSetPowerState(rContext, POWER_STATE_UNPOWERED);
300 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_UNPOWERED");
301 Log2(PCSC_LOG_ERROR,
"Error powering up card: %s", rv2text(rv));
332 Log2(PCSC_LOG_ERROR,
"Error communicating to: %s", readerName);
348 if (dwCurrentState == SCARD_PRESENT ||
354 Log2(PCSC_LOG_INFO,
"Card Removed From %s", readerName);
358 (void)RFSetReaderEventState(rContext, SCARD_REMOVED);
373 else if (dwStatus & SCARD_PRESENT)
375 if (dwCurrentState == SCARD_ABSENT ||
378 #ifdef DISABLE_AUTO_POWER_ON
382 RFSetPowerState(rContext, POWER_STATE_UNPOWERED);
383 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_UNPOWERED");
385 Log1(PCSC_LOG_INFO,
"Skip card power on");
401 RFSetPowerState(rContext, POWER_STATE_POWERED);
402 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_POWERED");
407 RFSetPowerState(rContext, POWER_STATE_UNPOWERED);
408 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_UNPOWERED");
419 Log2(PCSC_LOG_INFO,
"Card inserted into %s", readerName);
427 LogXxd(PCSC_LOG_INFO,
"Card ATR: ",
432 Log1(PCSC_LOG_INFO,
"Card ATR: (NULL)");
435 Log1(PCSC_LOG_ERROR,
"Error powering up card.");
442 if (readerSharing != rContext->
contexts)
454 #ifndef DISABLE_ON_DEMAND_POWER_ON
457 timeout = PCSCLITE_POWER_OFF_GRACE_PERIOD;
461 timeout = PCSCLITE_STATUS_EVENT_TIMEOUT;
470 #ifndef DISABLE_ON_DEMAND_POWER_ON
473 if (POWER_STATE_POWERED == rContext->
powerState)
478 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_UNPOWERED");
485 if (POWER_STATE_GRACE_PERIOD == rContext->
powerState)
490 Log1(PCSC_LOG_DEBUG,
"powerState: POWER_STATE_POWERED");
495 if (rContext->
hLockId == 0xFFFF)
500 Log1(PCSC_LOG_INFO,
"Die");
502 (void)pthread_exit(NULL);
LONG EHUnregisterClientForEvent(int32_t filedes)
Unregister a client and log an error if the client is not found.
LONG IFDStatusICC(READER_CONTEXT *rContext, PDWORD pdwStatus)
Provide statistical information about the IFD and ICC including insertions, atr, powering status/etc...
This abstracts dynamic library loading functions.
#define TAG_IFD_STOP_POLLING_THREAD
method used to stop the polling thread (instead of just pthread_kill())
#define SCARD_S_SUCCESS
No error was encountered.
void EHSignalEventToClients(void)
Sends an asynchronous event to any waiting client.
pthread_t pthThread
Event polling thread.
UCHAR cardAtr[MAX_ATR_SIZE]
ATR.
#define SCARD_UNKNOWN
Unknown state.
RESPONSECODE(* pthCardEvent)(DWORD, int)
Card Event sync.
This handles protocol defaults, PTS, etc.
This handles abstract system level calls.
int slot
Current Reader Slot.
This wraps the dynamic ifdhandler functions.
This demarshalls functions over the message queue and keeps track of clients and their handles...
#define SCARD_PRESENT
Card is present.
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
RESPONSECODE IFDGetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, PDWORD pdwLength, PUCHAR pucValue)
Gets capabilities in the reader.
#define SCARD_NEGOTIABLE
Ready for PTS.
_Atomic SCARDHANDLE hLockId
Lock Id.
#define SCARD_F_UNKNOWN_ERROR
An internal error has been detected, but the source is unknown.
#define SCARD_E_NO_MEMORY
Not enough memory available to complete this command.
#define IFD_POWER_DOWN
power down the card
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.
uint32_t cardProtocol
SCARD_PROTOCOL_* value.
This handles card insertion/removal events, updates ATR, protocol, and status information.
RESPONSECODE IFDPowerICC(READER_CONTEXT *rContext, DWORD dwAction, PUCHAR pucAtr, PDWORD pdwAtrLen)
Power up/down or reset's an ICC located in the IFD.
READER_STATE readerState
reader state
pthread_mutex_t ClientsWaitingForEvent_lock
lock for the above list
uint32_t readerState
SCARD_* bit field.
#define SCARD_SWALLOWED
Card not powered.
int powerState
auto power off state
#define SCARD_PROTOCOL_UNDEFINED
protocol not set
#define SCARD_POWERED
Card is powered.
_Atomic uint32_t cardAtrLength
ATR length.
_Atomic int32_t contexts
Number of open contexts.
#define SCARD_ABSENT
Card is absent.
This keeps track of a list of currently available reader structures.
char readerName[MAX_READERNAME]
reader name
#define SCARD_F_INTERNAL_ERROR
An internal consistency check failed.
int RFGetPowerState(READER_CONTEXT *rContext)
Wait until all connected readers have a chance to power up a possibly inserted card.
pthread_mutex_t powerState_lock
powerState mutex
_Atomic int32_t readerSharing
PCSCLITE_SHARING_* sharing status.
uint32_t eventCounter
number of card events
#define IFD_POWER_UP
power up the card
#define TAG_IFD_POLLING_THREAD_KILLABLE
the polling thread can be killed
#define IFD_SUCCESS
no error