26 #include <sys/types.h>
42 #include "configfile.h"
52 static int maxReaderHandles = PCSC_MAX_READER_HANDLES;
53 static DWORD dwNumReadersContexts = 0;
55 static char *ConfigFile = NULL;
56 static int ConfigFileCRC = 0;
58 static pthread_mutex_t LockMutex = PTHREAD_MUTEX_INITIALIZER;
60 #define IDENTITY_SHIFT 16
63 static int RDR_CLIHANDLES_seeker(
const void *el,
const void *key)
67 if ((el == NULL) || (key == NULL))
69 Log3(PCSC_LOG_CRITICAL,
70 "RDR_CLIHANDLES_seeker called with NULL pointer: el=%p, key=%p",
104 removeReader(sReader);
109 LONG RFAllocateReaderSpace(
unsigned int customMaxReaderHandles)
113 if (customMaxReaderHandles != 0)
114 maxReaderHandles = customMaxReaderHandles;
120 sReadersContexts[i]->
vHandle = NULL;
123 memset(readerStates[i].readerName, 0, MAX_READERNAME);
130 sReadersContexts[i]->
readerState = &readerStates[i];
134 return EHInitializeEventStructures();
137 LONG RFAddReader(
const char *readerNameLong,
int port,
const char *library,
140 DWORD dwContext = 0, dwGetSize;
141 UCHAR ucGetData[1], ucThread[1];
145 char *readerName = NULL;
147 if ((readerNameLong == NULL) || (library == NULL) || (device == NULL))
151 readerName = alloca(strlen(readerNameLong)+1);
152 strcpy(readerName, readerNameLong);
155 if (strlen(readerName) > MAX_READERNAME -
sizeof(
" 00 00"))
158 "Reader name too long: %zd chars instead of max %zd. Truncating!",
159 strlen(readerName), MAX_READERNAME -
sizeof(
" 00 00"));
160 readerName[MAX_READERNAME -
sizeof(
" 00 00")] =
'\0';
164 if (dwNumReadersContexts != 0)
168 if (sReadersContexts[i]->vHandle != 0)
170 char lpcStripReader[MAX_READERNAME];
174 strncpy(lpcStripReader,
175 sReadersContexts[i]->readerState->readerName,
176 sizeof(lpcStripReader));
177 tmplen = strlen(lpcStripReader);
178 lpcStripReader[tmplen - 6] = 0;
180 if ((strcmp(readerName, lpcStripReader) == 0) &&
181 (port == sReadersContexts[i]->port))
183 Log1(PCSC_LOG_ERROR,
"Duplicate reader found.");
193 if (sReadersContexts[i]->vHandle == 0)
200 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
207 parentNode = RFSetReaderName(sReadersContexts[dwContext], readerName,
212 sReadersContexts[dwContext]->
library = strdup(library);
213 sReadersContexts[dwContext]->
device = strdup(device);
214 sReadersContexts[dwContext]->
version = 0;
215 sReadersContexts[dwContext]->
port = port;
216 sReadersContexts[dwContext]->
mMutex = NULL;
217 sReadersContexts[dwContext]->
contexts = 0;
218 sReadersContexts[dwContext]->
pthThread = 0;
219 sReadersContexts[dwContext]->
hLockId = 0;
220 sReadersContexts[dwContext]->
LockCount = 0;
221 sReadersContexts[dwContext]->
vHandle = NULL;
222 sReadersContexts[dwContext]->
pFeeds = NULL;
223 sReadersContexts[dwContext]->
pMutex = NULL;
226 lrv = list_init(&sReadersContexts[dwContext]->handlesList);
229 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d", lrv);
233 lrv = list_attributes_seeker(&sReadersContexts[dwContext]->handlesList,
234 RDR_CLIHANDLES_seeker);
237 Log2(PCSC_LOG_CRITICAL,
238 "list_attributes_seeker failed with return value: %d", lrv);
242 (void)pthread_mutex_init(&sReadersContexts[dwContext]->handlesList_lock,
245 (void)pthread_mutex_init(&sReadersContexts[dwContext]->powerState_lock,
250 (void)pthread_mutex_init(&sReadersContexts[dwContext]->reference_lock,
252 sReadersContexts[dwContext]->
reference = 1;
255 if (parentNode >= 0 && parentNode < PCSCLITE_MAX_READERS_CONTEXTS)
257 sReadersContexts[dwContext]->
pFeeds =
258 sReadersContexts[parentNode]->
pFeeds;
259 *(sReadersContexts[dwContext])->pFeeds += 1;
260 sReadersContexts[dwContext]->
vHandle =
261 sReadersContexts[parentNode]->
vHandle;
262 sReadersContexts[dwContext]->
mMutex =
263 sReadersContexts[parentNode]->
mMutex;
264 sReadersContexts[dwContext]->
pMutex =
265 sReadersContexts[parentNode]->
pMutex;
268 dwGetSize =
sizeof(ucThread);
272 if (rv ==
IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
274 Log1(PCSC_LOG_INFO,
"Driver is thread safe");
275 sReadersContexts[dwContext]->
mMutex = NULL;
276 sReadersContexts[dwContext]->
pMutex = NULL;
279 *(sReadersContexts[dwContext])->pMutex += 1;
282 if (sReadersContexts[dwContext]->pFeeds == NULL)
284 sReadersContexts[dwContext]->
pFeeds = malloc(
sizeof(
int));
290 *(sReadersContexts[dwContext])->pFeeds = 1;
293 if (sReadersContexts[dwContext]->mMutex == 0)
295 sReadersContexts[dwContext]->
mMutex =
296 malloc(
sizeof(pthread_mutex_t));
297 (void)pthread_mutex_init(sReadersContexts[dwContext]->mMutex, NULL);
300 if (sReadersContexts[dwContext]->pMutex == NULL)
302 sReadersContexts[dwContext]->
pMutex = malloc(
sizeof(
int));
303 *(sReadersContexts[dwContext])->pMutex = 1;
306 dwNumReadersContexts += 1;
308 rv = RFInitializeReader(sReadersContexts[dwContext]);
312 Log2(PCSC_LOG_ERROR,
"%s init failed.", readerName);
313 (void)RFRemoveReader(readerName, port);
319 RESPONSECODE (*fct)(DWORD, int) = NULL;
321 dwGetSize =
sizeof(fct);
327 Log1(PCSC_LOG_INFO,
"Using the pcscd polling thread");
332 Log1(PCSC_LOG_INFO,
"Using the reader polling thread");
335 rv = EHSpawnEventHandler(sReadersContexts[dwContext]);
338 Log2(PCSC_LOG_ERROR,
"%s init failed.", readerName);
339 (void)RFRemoveReader(readerName, port);
345 dwGetSize =
sizeof(ucGetData);
349 if (rv !=
IFD_SUCCESS || dwGetSize != 1 || ucGetData[0] == 0)
354 if (rv ==
IFD_SUCCESS && dwGetSize == 1 && ucGetData[0] == 1)
364 for (j = 1; j < ucGetData[0]; j++)
366 char *tmpReader = NULL;
367 DWORD dwContextB = 0;
368 RESPONSECODE (*fct)(DWORD, int) = NULL;
373 if (sReadersContexts[i]->vHandle == 0)
380 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
383 RFRemoveReader(readerName, port);
389 (void)strlcpy(tmpReader,
390 sReadersContexts[dwContext]->readerState->readerName,
392 snprintf(tmpReader + strlen(tmpReader) - 2, 3,
"%02X", j);
394 sReadersContexts[dwContextB]->
library =
395 sReadersContexts[dwContext]->
library;
396 sReadersContexts[dwContextB]->
device =
397 sReadersContexts[dwContext]->
device;
398 sReadersContexts[dwContextB]->
version =
399 sReadersContexts[dwContext]->
version;
400 sReadersContexts[dwContextB]->
port =
401 sReadersContexts[dwContext]->
port;
402 sReadersContexts[dwContextB]->
vHandle =
403 sReadersContexts[dwContext]->
vHandle;
404 sReadersContexts[dwContextB]->
mMutex =
405 sReadersContexts[dwContext]->
mMutex;
406 sReadersContexts[dwContextB]->
pMutex =
407 sReadersContexts[dwContext]->
pMutex;
408 sReadersContexts[dwContextB]->
slot =
409 sReadersContexts[dwContext]->
slot + j;
416 sReadersContexts[dwContextB]->
pFeeds =
417 sReadersContexts[dwContext]->
pFeeds;
420 *(sReadersContexts[dwContextB])->pFeeds += 1;
422 sReadersContexts[dwContextB]->
contexts = 0;
423 sReadersContexts[dwContextB]->
hLockId = 0;
424 sReadersContexts[dwContextB]->
LockCount = 0;
426 lrv = list_init(&sReadersContexts[dwContextB]->handlesList);
429 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d", lrv);
433 lrv = list_attributes_seeker(&sReadersContexts[dwContextB]->handlesList,
434 RDR_CLIHANDLES_seeker);
437 Log2(PCSC_LOG_CRITICAL,
438 "list_attributes_seeker failed with return value: %d", lrv);
442 (void)pthread_mutex_init(&sReadersContexts[dwContextB]->handlesList_lock, NULL);
443 (void)pthread_mutex_init(&sReadersContexts[dwContextB]->powerState_lock,
448 (void)pthread_mutex_init(&sReadersContexts[dwContextB]->reference_lock,
450 sReadersContexts[dwContextB]->
reference = 1;
453 dwGetSize =
sizeof(ucThread);
457 if (rv ==
IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
459 sReadersContexts[dwContextB]->
mMutex =
460 malloc(
sizeof(pthread_mutex_t));
461 (void)pthread_mutex_init(sReadersContexts[dwContextB]->mMutex,
464 sReadersContexts[dwContextB]->
pMutex = malloc(
sizeof(
int));
465 *(sReadersContexts[dwContextB])->pMutex = 1;
468 *(sReadersContexts[dwContextB])->pMutex += 1;
470 dwNumReadersContexts += 1;
472 rv = RFInitializeReader(sReadersContexts[dwContextB]);
476 (void)RFRemoveReader(readerName, port);
481 dwGetSize =
sizeof(fct);
487 Log1(PCSC_LOG_INFO,
"Using the pcscd polling thread");
492 Log1(PCSC_LOG_INFO,
"Using the reader polling thread");
495 rv = EHSpawnEventHandler(sReadersContexts[dwContextB]);
498 Log2(PCSC_LOG_ERROR,
"%s init failed.", readerName);
499 (void)RFRemoveReader(readerName, port);
507 LONG RFRemoveReader(
const char *readerName,
int port)
509 char lpcStripReader[MAX_READERNAME];
512 if (readerName == NULL)
517 if (sReadersContexts[i]->vHandle != 0)
519 strncpy(lpcStripReader,
520 sReadersContexts[i]->readerState->readerName,
521 sizeof(lpcStripReader));
522 lpcStripReader[strlen(lpcStripReader) - 6] = 0;
525 if ((strncmp(readerName, lpcStripReader, MAX_READERNAME -
sizeof(
" 00 00")) == 0)
526 && (port == sReadersContexts[i]->port))
529 UNREF_READER(sReadersContexts[i])
543 if (sContext -> pthThread)
544 (void)EHDestroyEventHandler(sContext);
546 if ((NULL == sContext->
pMutex) || (NULL == sContext->
pFeeds))
549 "Trying to remove an already removed driver");
553 rv = RFUnInitializeReader(sContext);
560 if (0 == *sContext->
pMutex)
562 (void)pthread_mutex_destroy(sContext->
mMutex);
574 if (*sContext->
pFeeds == 0)
590 while (list_size(&sContext->handlesList) != 0)
595 currentHandle = list_get_at(&sContext->handlesList, 0);
596 lrv = list_delete_at(&sContext->handlesList, 0);
598 Log2(PCSC_LOG_CRITICAL,
599 "list_delete_at failed with return value: %d", lrv);
605 list_destroy(&sContext->handlesList);
606 dwNumReadersContexts -= 1;
615 LONG RFSetReaderName(
READER_CONTEXT * rContext,
const char *readerName,
616 const char *libraryName,
int port)
620 int currentDigit = -1;
621 int supportedChannels = 0;
627 usedDigits[i] = FALSE;
629 if (dwNumReadersContexts != 0)
633 if (sReadersContexts[i]->vHandle != 0)
635 if (strcmp(sReadersContexts[i]->library, libraryName) == 0)
641 valueLength =
sizeof(tagValue);
644 &valueLength, tagValue);
649 supportedChannels = tagValue[0];
651 "Support %d simultaneous readers", tagValue[0]);
654 supportedChannels = 1;
657 if ((((sReadersContexts[i]->port & 0xFFFF0000) ==
658 PCSCLITE_HP_BASE_PORT)
659 && (sReadersContexts[i]->port != port))
660 || (supportedChannels > 1))
676 currentDigit = strtol(reader + strlen(reader) - 5, NULL, 16);
679 usedDigits[currentDigit] = TRUE;
690 if (currentDigit != -1)
695 if (usedDigits[i] == FALSE)
699 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
701 Log2(PCSC_LOG_ERROR,
"Max number of readers reached: %d", PCSCLITE_MAX_READERS_CONTEXTS);
705 if (i >= supportedChannels)
707 Log3(PCSC_LOG_ERROR,
"Driver %s does not support more than "
708 "%d reader(s). Maybe the driver should support "
709 "TAG_IFD_SIMULTANEOUS_ACCESS", libraryName, supportedChannels);
719 rContext->
slot = i << 16;
724 LONG RFReaderInfo(
const char *readerName,
READER_CONTEXT ** sReader)
728 if (readerName == NULL)
733 if (sReadersContexts[i]->vHandle != 0)
735 if (strcmp(readerName,
736 sReadersContexts[i]->readerState->readerName) == 0)
739 REF_READER(sReadersContexts[i])
741 *sReader = sReadersContexts[i];
756 if (sReadersContexts[i]->vHandle != 0)
759 (void)pthread_mutex_lock(&sReadersContexts[i]->handlesList_lock);
760 currentHandle = list_seek(&sReadersContexts[i]->handlesList,
762 (void)pthread_mutex_unlock(&sReadersContexts[i]->handlesList_lock);
763 if (currentHandle != NULL)
766 REF_READER(sReadersContexts[i])
768 *sReader = sReadersContexts[i];
781 Log2(PCSC_LOG_INFO,
"Reusing already loaded driver for %s",
795 rv = DYN_GetAddress(rContext->
vHandle, &f,
"IFDHCreateChannelByName");
799 rContext->
version = IFD_HVERSION_3_0;
803 rv = DYN_GetAddress(rContext->
vHandle, &f,
"IFDHCreateChannel");
807 rContext->
version = IFD_HVERSION_2_0;
812 Log1(PCSC_LOG_CRITICAL,
"IFDHandler functions missing");
817 if (rContext->
version == IFD_HVERSION_2_0)
820 #define GET_ADDRESS_OPTIONALv2(s, code) \
823 int rvl = DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s); \
824 if (SCARD_S_SUCCESS != rvl) \
828 rContext->psFunctions.psFunctions_v2.pvf ## s = f1; \
831 #define GET_ADDRESSv2(s) \
832 GET_ADDRESS_OPTIONALv2(s, \
833 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
836 Log1(PCSC_LOG_INFO,
"Loading IFD Handler 2.0");
838 GET_ADDRESSv2(CreateChannel)
839 GET_ADDRESSv2(CloseChannel)
840 GET_ADDRESSv2(GetCapabilities)
841 GET_ADDRESSv2(SetCapabilities)
842 GET_ADDRESSv2(PowerICC)
843 GET_ADDRESSv2(TransmitToICC)
844 GET_ADDRESSv2(ICCPresence)
845 GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
847 GET_ADDRESSv2(Control)
849 else if (rContext->version == IFD_HVERSION_3_0)
852 #define GET_ADDRESS_OPTIONALv3(s, code) \
855 int rvl = DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s); \
856 if (SCARD_S_SUCCESS != rvl) \
860 rContext->psFunctions.psFunctions_v3.pvf ## s = f1; \
863 #define GET_ADDRESSv3(s) \
864 GET_ADDRESS_OPTIONALv3(s, \
865 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
868 Log1(PCSC_LOG_INFO,
"Loading IFD Handler 3.0");
870 GET_ADDRESSv2(CreateChannel)
871 GET_ADDRESSv2(CloseChannel)
872 GET_ADDRESSv2(GetCapabilities)
873 GET_ADDRESSv2(SetCapabilities)
874 GET_ADDRESSv2(PowerICC)
875 GET_ADDRESSv2(TransmitToICC)
876 GET_ADDRESSv2(ICCPresence)
877 GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
879 GET_ADDRESSv3(CreateChannelByName)
880 GET_ADDRESSv3(Control)
885 Log1(PCSC_LOG_CRITICAL,
"IFD Handler not 1.0/2.0 or 3.0");
903 if (*rContext->
pFeeds == 1)
905 Log1(PCSC_LOG_INFO,
"Unloading reader driver.");
906 (void)DYN_CloseLibrary(&rContext->
vHandle);
926 (void)pthread_mutex_lock(&LockMutex);
927 rv = RFCheckSharing(hCard, rContext);
933 (void)pthread_mutex_unlock(&LockMutex);
942 (void)pthread_mutex_lock(&LockMutex);
943 rv = RFCheckSharing(hCard, rContext);
951 (void)pthread_mutex_unlock(&LockMutex);
960 (void)pthread_mutex_lock(&LockMutex);
961 rv = RFCheckSharing(hCard, rContext);
967 (void)pthread_mutex_unlock(&LockMutex);
977 Log3(PCSC_LOG_INFO,
"Attempting startup of %s using %s",
980 #ifndef PCSCLITE_STATIC_DRIVER
982 rv = RFLoadReader(rContext);
985 Log2(PCSC_LOG_ERROR,
"RFLoadReader failed: 0x%lX", rv);
990 rv = RFBindFunctions(rContext);
994 Log2(PCSC_LOG_ERROR,
"RFBindFunctions failed: 0x%lX", rv);
995 (void)RFUnloadReader(rContext);
1000 rContext->
vHandle = RFInitializeReader;
1008 Log3(PCSC_LOG_CRITICAL,
"Open Port 0x%X Failed (%s)",
1012 rContext->
slot = -1;
1015 rContext->
slot = -1;
1028 Log2(PCSC_LOG_INFO,
"Attempting shutdown of %s.",
1032 if (rContext->
slot != -1)
1035 (void)RFUnBindFunctions(rContext);
1036 (void)RFUnloadReader(rContext);
1070 randHandle = SYS_RandomInt(0, -1);
1073 ret = RFReaderInfoById(randHandle, &dummy_reader);
1075 UNREF_READER(dummy_reader)
1092 int listLength, lrv;
1097 listLength = list_size(&rContext->handlesList);
1100 if (listLength >= maxReaderHandles)
1102 Log2(PCSC_LOG_CRITICAL,
1103 "Too many handles opened, exceeding configured max (%d)",
1110 if (NULL == newHandle)
1112 Log1(PCSC_LOG_CRITICAL,
"malloc failed");
1117 newHandle->
hCard = hCard;
1120 lrv = list_append(&rContext->handlesList, newHandle);
1124 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
1140 currentHandle = list_seek(&rContext->handlesList, &hCard);
1141 if (NULL == currentHandle)
1143 Log2(PCSC_LOG_CRITICAL,
"list_seek failed to locate hCard=%lX", hCard);
1148 lrv = list_delete(&rContext->handlesList, currentHandle);
1150 Log2(PCSC_LOG_CRITICAL,
1151 "list_delete failed with return value: %d", lrv);
1153 free(currentHandle);
1162 LONG RFSetReaderEventState(
READER_CONTEXT * rContext, DWORD dwEvent)
1165 int list_index, listSize;
1169 listSize = list_size(&rContext->handlesList);
1171 for (list_index = 0; list_index < listSize; list_index++)
1173 currentHandle = list_get_at(&rContext->handlesList, list_index);
1174 if (NULL == currentHandle)
1176 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed at index %d",
1201 currentHandle = list_seek(&rContext->handlesList, &hCard);
1203 if (NULL == currentHandle)
1206 Log2(PCSC_LOG_CRITICAL,
"list_seek failed for hCard 0x%lX", hCard);
1236 currentHandle = list_seek(&rContext->handlesList, &hCard);
1238 if (NULL == currentHandle)
1258 void RFCleanupReaders(
void)
1262 Log1(PCSC_LOG_INFO,
"entering cleaning function");
1265 if (sReadersContexts[i]->vHandle != 0)
1268 char lpcStripReader[MAX_READERNAME];
1270 Log2(PCSC_LOG_INFO,
"Stopping reader: %s",
1271 sReadersContexts[i]->readerState->readerName);
1273 strncpy(lpcStripReader,
1274 sReadersContexts[i]->readerState->readerName,
1275 sizeof(lpcStripReader));
1277 lpcStripReader[strlen(lpcStripReader) - 6] =
'\0';
1279 rv = RFRemoveReader(lpcStripReader, sReadersContexts[i]->port);
1282 Log2(PCSC_LOG_ERROR,
"RFRemoveReader error: 0x%08lX", rv);
1292 void RFWaitForReaderInit(
void)
1294 int i, need_to_wait;
1298 need_to_wait = FALSE;
1302 if (sReadersContexts[i]->vHandle != NULL)
1306 == sReadersContexts[i]->readerState->cardAtrLength)
1308 Log2(PCSC_LOG_DEBUG,
"Waiting init for reader: %s",
1309 sReadersContexts[i]->readerState->readerName);
1310 need_to_wait = TRUE;
1317 }
while (need_to_wait);
1322 int RFStartSerialReaders(
const char *readerconf)
1328 ConfigFile = strdup(readerconf);
1330 rv = DBGetReaderListDir(readerconf, &reader_list);
1333 if (NULL == reader_list)
1340 (void)RFAddReader(reader_list[i].pcFriendlyname,
1341 reader_list[i].channelId,
1342 reader_list[i].pcLibpath, reader_list[i].pcDevicename);
1346 ConfigFileCRC += reader_list[i].pcFriendlyname[j];
1347 for (j=0; j<reader_list[i].
pcLibpath[j]; j++)
1348 ConfigFileCRC += reader_list[i].pcLibpath[j];
1350 ConfigFileCRC += reader_list[i].pcDevicename[j];
1353 free(reader_list[i].pcFriendlyname);
1354 free(reader_list[i].pcLibpath);
1355 free(reader_list[i].pcDevicename);
1362 void RFReCheckReaderConf(
void)
1367 (void)DBGetReaderListDir(ConfigFile, &reader_list);
1370 if (NULL == reader_list)
1380 crc += reader_list[i].pcFriendlyname[j];
1381 for (j=0; j<reader_list[i].
pcLibpath[j]; j++)
1382 crc += reader_list[i].pcLibpath[j];
1384 crc += reader_list[i].pcDevicename[j];
1388 if (crc != ConfigFileCRC)
1390 Log2(PCSC_LOG_CRITICAL,
1391 "configuration file: %s has been modified. Recheck canceled",
1399 char present = FALSE;
1401 Log2(PCSC_LOG_DEBUG,
"refresh reader: %s",
1402 reader_list[i].pcFriendlyname);
1407 if (sReadersContexts[r]->vHandle != 0)
1409 char lpcStripReader[MAX_READERNAME];
1413 strncpy(lpcStripReader,
1414 sReadersContexts[i]->readerState->readerName,
1415 sizeof(lpcStripReader));
1416 tmplen = strlen(lpcStripReader);
1417 lpcStripReader[tmplen - 6] = 0;
1419 if ((strcmp(reader_list[i].pcFriendlyname, lpcStripReader) == 0)
1420 && (reader_list[r].channelId == sReadersContexts[i]->port))
1431 Log2(PCSC_LOG_INFO,
"Reader %s disappeared",
1432 reader_list[i].pcFriendlyname);
1433 (void)RFRemoveReader(reader_list[i].pcFriendlyname,
1434 reader_list[r].channelId);
1443 (void)RFAddReader(reader_list[i].pcFriendlyname,
1444 reader_list[i].channelId, reader_list[i].pcLibpath,
1445 reader_list[i].pcDevicename);
1448 free(reader_list[i].pcFriendlyname);
1449 free(reader_list[i].pcLibpath);
1450 free(reader_list[i].pcDevicename);
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.
struct pubReaderStatesList * readerState
link to the reader state
uint32_t cardAtrLength
ATR length.
int32_t contexts
Number of open contexts.
#define IFD_NO_SUCH_DEVICE
The IFD_NO_SUCH_DEVICE error must be returned by the driver when it detects the reader is no more pre...
#define TAG_IFD_THREAD_SAFE
driver is thread safe
volatile SCARDHANDLE hLockId
Lock Id.
pthread_t pthThread
Event polling thread.
#define SCARD_E_READER_UNAVAILABLE
The specified reader is not currently available for use.
RESPONSECODE(* pthCardEvent)(DWORD, int)
Card Event sync.
#define SCARD_E_DUPLICATE_READER
The reader driver did not produce a unique reader name.
LONG IFDGetCapabilities(READER_CONTEXT *rContext, DWORD dwTag, PDWORD pdwLength, PUCHAR pucValue)
Get's capabilities in the reader.
#define SCARD_UNKNOWN
Unknown state.
DWORD dwEventStatus
Recent event that must be sent.
char readerName[MAX_READERNAME]
reader name
int32_t readerSharing
PCSCLITE_SHARING_* sharing status.
This handles abstract system level calls.
int slot
Current Reader Slot.
union ReaderContext::@3 psFunctions
driver functions
LONG EHSignalEventToClients(void)
Sends an asynchronous event to any waiting client.
This wraps the dynamic ifdhandler functions.
int * pMutex
Number of client to mutex.
pthread_mutex_t handlesList_lock
lock for the above list
#define SCARD_F_UNKNOWN_ERROR
An internal error has been detected, but the source is unknown.
#define SCARD_E_INVALID_HANDLE
The supplied handle was invalid.
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
char * library
Library Path.
#define SCARD_E_INVALID_VALUE
One or more of the supplied parameters values could not be properly interpreted.
#define SCARD_RESET
Card was reset.
#define PCSCLITE_MAX_READERS_CONTEXTS
Maximum readers context (a slot is count as a reader)
prototypes of strlcpy()/strlcat() imported from OpenBSD
int * pFeeds
Number of shared client to lib.
#define TAG_IFD_SLOTS_NUMBER
number of slots of the reader
int version
IFD Handler version number.
pthread_mutex_t * mMutex
Mutex for this connection.
static READER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS]
Area used to read status information about the readers.
This handles card insertion/removal events, updates ATR, protocol, and status information.
LONG IFDCloseIFD(READER_CONTEXT *rContext)
Close a communication channel to the IFD.
#define SCARD_W_REMOVED_CARD
The smart card has been removed, so further communication is not possible.
#define TAG_IFD_SLOT_THREAD_SAFE
support access to different slots of the reader
int powerState
auto power off state
#define SCARD_PROTOCOL_UNDEFINED
protocol not set
UCHAR cardAtr[MAX_ATR_SIZE]
ATR.
LONG SCARDHANDLE
hCard returned by SCardConnect()
LONG IFDOpenIFD(READER_CONTEXT *rContext)
Open a communication channel to the IFD.
int LockCount
number of recursive locks
#define TAG_IFD_POLLING_THREAD_WITH_TIMEOUT
driver uses a polling thread with a timeout parameter
LPVOID vHandle
Dlopen handle.
This keeps a list of defines for pcsc-lite.
#define TAG_IFD_SIMULTANEOUS_ACCESS
number of reader the driver can manage
pthread_mutex_t reference_lock
reference mutex
#define SCARD_W_RESET_CARD
The smart card has been reset, so any shared state information is invalid.
#define SCARD_E_SHARING_VIOLATION
The smart card cannot be accessed because of other connections outstanding.
uint32_t cardProtocol
SCARD_PROTOCOL_* value.
Define an exported public reader state structure so each application gets instant notification of cha...
char * device
Device Name.
#define SCARD_E_NO_MEMORY
Not enough memory available to complete this command.
This keeps track of a list of currently available reader structures.
#define MAX_ATR_SIZE
Maximum ATR size.
char * pcDevicename
DEVICENAME.
uint32_t readerState
SCARD_* bit field.
int reference
number of users of the structure
This provides a search API for hot pluggble devices.
pthread_mutex_t powerState_lock
powerState mutex
#define SCARD_E_INVALID_TARGET
Registry startup information is missing or invalid.
char * pcFriendlyname
FRIENDLYNAME.
#define SCARD_E_UNKNOWN_READER
The specified reader name is not recognized.
#define SCARD_S_SUCCESS
error codes from http://msdn.microsoft.com/en-us/library/aa924526.aspx
#define IFD_SUCCESS
no error
#define SCARD_REMOVED
Card was removed.
SCARDHANDLE hCard
hCard for this connection
#define READER_NOT_INITIALIZED
Special value to indicate that power up has not yet happen This is used to auto start mode to wait un...