00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00018 #include "config.h"
00019 #include <sys/types.h>
00020 #include <sys/stat.h>
00021 #include <errno.h>
00022 #include <fcntl.h>
00023 #include <string.h>
00024 #include <stdlib.h>
00025
00026 #include "misc.h"
00027 #include "pcscd.h"
00028 #include "ifdhandler.h"
00029 #include "debuglog.h"
00030 #include "thread_generic.h"
00031 #include "readerfactory.h"
00032 #include "eventhandler.h"
00033 #include "dyn_generic.h"
00034 #include "sys_generic.h"
00035 #include "ifdwrapper.h"
00036 #include "prothandler.h"
00037 #include "strlcpycat.h"
00038 #include "utils.h"
00039
00040 static PREADER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
00041
00042 static void EHStatusHandlerThread(PREADER_CONTEXT);
00043
00044 LONG EHInitializeEventStructures(void)
00045 {
00046 int fd, i, pageSize;
00047 int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
00048
00049 fd = 0;
00050 i = 0;
00051 pageSize = 0;
00052
00053 (void)SYS_RemoveFile(PCSCLITE_PUBSHM_FILE);
00054
00055 fd = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDWR | O_CREAT, mode);
00056 if (fd < 0)
00057 {
00058 Log3(PCSC_LOG_CRITICAL, "Cannot create public shared file %s: %s",
00059 PCSCLITE_PUBSHM_FILE, strerror(errno));
00060 exit(1);
00061 }
00062
00063
00064 (void)SYS_Chmod(PCSCLITE_PUBSHM_FILE, mode);
00065
00066 pageSize = SYS_GetPageSize();
00067
00068
00069
00070
00071 (void)SYS_SeekFile(fd, pageSize * PCSCLITE_MAX_READERS_CONTEXTS);
00072 (void)SYS_WriteFile(fd, "", 1);
00073
00074
00075
00076
00077 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00078 {
00079 readerStates[i] = (PREADER_STATE)
00080 SYS_MemoryMap(sizeof(READER_STATE), fd, (i * pageSize));
00081 if (readerStates[i] == MAP_FAILED)
00082 {
00083 Log3(PCSC_LOG_CRITICAL, "Cannot memory map public shared file %s: %s",
00084 PCSCLITE_PUBSHM_FILE, strerror(errno));
00085 exit(1);
00086 }
00087
00088
00089
00090
00091 memset((readerStates[i])->readerName, 0, MAX_READERNAME);
00092 memset((readerStates[i])->cardAtr, 0, MAX_ATR_SIZE);
00093 (readerStates[i])->readerID = 0;
00094 (readerStates[i])->readerState = 0;
00095 (readerStates[i])->readerSharing = 0;
00096 (readerStates[i])->cardAtrLength = 0;
00097 (readerStates[i])->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
00098 }
00099
00100 return SCARD_S_SUCCESS;
00101 }
00102
00103 LONG EHDestroyEventHandler(PREADER_CONTEXT rContext)
00104 {
00105 int rv;
00106 DWORD dwGetSize;
00107 UCHAR ucGetData[1];
00108
00109 if (NULL == rContext->readerState)
00110 {
00111 Log1(PCSC_LOG_ERROR, "Thread never started (reader init failed?)");
00112 return SCARD_S_SUCCESS;
00113 }
00114
00115 if ('\0' == rContext->readerState->readerName[0])
00116 {
00117 Log1(PCSC_LOG_INFO, "Thread already stomped.");
00118 return SCARD_S_SUCCESS;
00119 }
00120
00121
00122
00123
00124 rContext->dwLockId = 0xFFFF;
00125
00126 Log1(PCSC_LOG_INFO, "Stomping thread.");
00127
00128
00129 dwGetSize = sizeof(ucGetData);
00130 rv = IFDGetCapabilities(rContext, TAG_IFD_POLLING_THREAD_KILLABLE,
00131 &dwGetSize, ucGetData);
00132
00133 if ((IFD_SUCCESS == rv) && (1 == dwGetSize) && ucGetData[0])
00134 {
00135 Log1(PCSC_LOG_INFO, "Killing polling thread");
00136 (void)SYS_ThreadCancel(rContext->pthThread);
00137 }
00138 else
00139 Log1(PCSC_LOG_INFO, "Waiting polling thread");
00140
00141
00142 rv = SYS_ThreadJoin(rContext->pthThread, NULL);
00143 if (rv)
00144 Log2(PCSC_LOG_ERROR, "SYS_ThreadJoin failed: %s", strerror(rv));
00145
00146
00147
00148
00149
00150 memset(rContext->readerState->readerName, 0,
00151 sizeof(rContext->readerState->readerName));
00152 memset(rContext->readerState->cardAtr, 0,
00153 sizeof(rContext->readerState->cardAtr));
00154 rContext->readerState->readerID = 0;
00155 rContext->readerState->readerState = 0;
00156 rContext->readerState->readerSharing = 0;
00157 rContext->readerState->cardAtrLength = 0;
00158 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
00159
00160
00161 rContext->pthThread = 0;
00162
00163 Log1(PCSC_LOG_INFO, "Thread stomped.");
00164
00165 return SCARD_S_SUCCESS;
00166 }
00167
00168 LONG EHSpawnEventHandler(PREADER_CONTEXT rContext,
00169 RESPONSECODE (*card_event)(DWORD))
00170 {
00171 LONG rv;
00172 DWORD dwStatus = 0;
00173 int i;
00174 UCHAR ucAtr[MAX_ATR_SIZE];
00175 DWORD dwAtrLen = 0;
00176
00177 rv = IFDStatusICC(rContext, &dwStatus, ucAtr, &dwAtrLen);
00178 if (rv != SCARD_S_SUCCESS)
00179 {
00180 Log2(PCSC_LOG_ERROR, "Initial Check Failed on %s", rContext->lpcReader);
00181 return SCARD_F_UNKNOWN_ERROR;
00182 }
00183
00184
00185
00186
00187 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00188 {
00189 if ((readerStates[i])->readerID == 0)
00190 break;
00191 }
00192
00193 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00194 return SCARD_F_INTERNAL_ERROR;
00195
00196
00197
00198
00199 rContext->readerState = readerStates[i];
00200 (void)strlcpy(rContext->readerState->readerName, rContext->lpcReader,
00201 sizeof(rContext->readerState->readerName));
00202 memcpy(rContext->readerState->cardAtr, ucAtr, dwAtrLen);
00203 rContext->readerState->readerID = i + 100;
00204 rContext->readerState->readerState = dwStatus;
00205 rContext->readerState->readerSharing = rContext->dwContexts;
00206 rContext->readerState->cardAtrLength = dwAtrLen;
00207 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
00208
00209 rContext->pthCardEvent = card_event;
00210 rv = SYS_ThreadCreate(&rContext->pthThread, 0,
00211 (PCSCLITE_THREAD_FUNCTION( ))EHStatusHandlerThread, (LPVOID) rContext);
00212 if (rv)
00213 {
00214 Log2(PCSC_LOG_ERROR, "SYS_ThreadCreate failed: %s", strerror(rv));
00215 return SCARD_E_NO_MEMORY;
00216 }
00217 else
00218 return SCARD_S_SUCCESS;
00219 }
00220
00221 static void incrementEventCounter(struct pubReaderStatesList *readerState)
00222 {
00223 int counter;
00224
00225 counter = (readerState -> readerState >> 16) & 0xFFFF;
00226 counter++;
00227 readerState -> readerState = (readerState -> readerState & 0xFFFF)
00228 + (counter << 16);
00229 }
00230
00231 static void EHStatusHandlerThread(PREADER_CONTEXT rContext)
00232 {
00233 LONG rv;
00234 LPCSTR lpcReader;
00235 DWORD dwStatus, dwReaderSharing;
00236 DWORD dwCurrentState;
00237 DWORD dwAtrLen;
00238
00239
00240
00241
00242 dwStatus = 0;
00243 dwReaderSharing = 0;
00244 dwCurrentState = 0;
00245
00246 lpcReader = rContext->lpcReader;
00247
00248 dwAtrLen = rContext->readerState->cardAtrLength;
00249 rv = IFDStatusICC(rContext, &dwStatus, rContext->readerState->cardAtr,
00250 &dwAtrLen);
00251 rContext->readerState->cardAtrLength = dwAtrLen;
00252
00253 if (dwStatus & SCARD_PRESENT)
00254 {
00255 dwAtrLen = MAX_ATR_SIZE;
00256 rv = IFDPowerICC(rContext, IFD_POWER_UP,
00257 rContext->readerState->cardAtr,
00258 &dwAtrLen);
00259 rContext->readerState->cardAtrLength = dwAtrLen;
00260
00261
00262 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
00263
00264 if (rv == IFD_SUCCESS)
00265 {
00266 dwStatus |= SCARD_PRESENT;
00267 dwStatus &= ~SCARD_ABSENT;
00268 dwStatus |= SCARD_POWERED;
00269 dwStatus |= SCARD_NEGOTIABLE;
00270 dwStatus &= ~SCARD_SPECIFIC;
00271 dwStatus &= ~SCARD_SWALLOWED;
00272 dwStatus &= ~SCARD_UNKNOWN;
00273
00274 if (rContext->readerState->cardAtrLength > 0)
00275 {
00276 LogXxd(PCSC_LOG_INFO, "Card ATR: ",
00277 rContext->readerState->cardAtr,
00278 rContext->readerState->cardAtrLength);
00279 }
00280 else
00281 Log1(PCSC_LOG_INFO, "Card ATR: (NULL)");
00282 }
00283 else
00284 {
00285 dwStatus |= SCARD_PRESENT;
00286 dwStatus &= ~SCARD_ABSENT;
00287 dwStatus |= SCARD_SWALLOWED;
00288 dwStatus &= ~SCARD_POWERED;
00289 dwStatus &= ~SCARD_NEGOTIABLE;
00290 dwStatus &= ~SCARD_SPECIFIC;
00291 dwStatus &= ~SCARD_UNKNOWN;
00292 Log3(PCSC_LOG_ERROR, "Error powering up card: %d 0x%04X", rv, rv);
00293 }
00294
00295 dwCurrentState = SCARD_PRESENT;
00296 }
00297 else
00298 {
00299 dwStatus |= SCARD_ABSENT;
00300 dwStatus &= ~SCARD_PRESENT;
00301 dwStatus &= ~SCARD_POWERED;
00302 dwStatus &= ~SCARD_NEGOTIABLE;
00303 dwStatus &= ~SCARD_SPECIFIC;
00304 dwStatus &= ~SCARD_SWALLOWED;
00305 dwStatus &= ~SCARD_UNKNOWN;
00306 rContext->readerState->cardAtrLength = 0;
00307 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
00308
00309 dwCurrentState = SCARD_ABSENT;
00310 }
00311
00312
00313
00314
00315 rContext->readerState->readerState = dwStatus;
00316 rContext->readerState->readerSharing = dwReaderSharing =
00317 rContext->dwContexts;
00318
00319 (void)StatSynchronize(rContext->readerState);
00320
00321 while (1)
00322 {
00323 dwStatus = 0;
00324
00325 dwAtrLen = rContext->readerState->cardAtrLength;
00326 rv = IFDStatusICC(rContext, &dwStatus,
00327 rContext->readerState->cardAtr,
00328 &dwAtrLen);
00329 rContext->readerState->cardAtrLength = dwAtrLen;
00330
00331 if (rv != SCARD_S_SUCCESS)
00332 {
00333 Log2(PCSC_LOG_ERROR, "Error communicating to: %s", lpcReader);
00334
00335
00336
00337
00338 rContext->readerState->readerState &= ~SCARD_ABSENT;
00339 rContext->readerState->readerState &= ~SCARD_PRESENT;
00340 rContext->readerState->readerState &= ~SCARD_POWERED;
00341 rContext->readerState->readerState &= ~SCARD_NEGOTIABLE;
00342 rContext->readerState->readerState &= ~SCARD_SPECIFIC;
00343 rContext->readerState->readerState &= ~SCARD_SWALLOWED;
00344 rContext->readerState->readerState |= SCARD_UNKNOWN;
00345 rContext->readerState->cardAtrLength = 0;
00346 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
00347
00348 dwCurrentState = SCARD_UNKNOWN;
00349
00350 (void)StatSynchronize(rContext->readerState);
00351 }
00352
00353 if (dwStatus & SCARD_ABSENT)
00354 {
00355 if (dwCurrentState == SCARD_PRESENT ||
00356 dwCurrentState == SCARD_UNKNOWN)
00357 {
00358
00359
00360
00361 Log2(PCSC_LOG_INFO, "Card Removed From %s", lpcReader);
00362
00363
00364
00365 (void)RFSetReaderEventState(rContext, SCARD_REMOVED);
00366
00367 rContext->readerState->cardAtrLength = 0;
00368 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
00369 rContext->readerState->readerState |= SCARD_ABSENT;
00370 rContext->readerState->readerState &= ~SCARD_UNKNOWN;
00371 rContext->readerState->readerState &= ~SCARD_PRESENT;
00372 rContext->readerState->readerState &= ~SCARD_POWERED;
00373 rContext->readerState->readerState &= ~SCARD_NEGOTIABLE;
00374 rContext->readerState->readerState &= ~SCARD_SWALLOWED;
00375 rContext->readerState->readerState &= ~SCARD_SPECIFIC;
00376 dwCurrentState = SCARD_ABSENT;
00377
00378 incrementEventCounter(rContext->readerState);
00379
00380 (void)StatSynchronize(rContext->readerState);
00381 }
00382
00383 }
00384 else if (dwStatus & SCARD_PRESENT)
00385 {
00386 if (dwCurrentState == SCARD_ABSENT ||
00387 dwCurrentState == SCARD_UNKNOWN)
00388 {
00389
00390
00391
00392 dwAtrLen = MAX_ATR_SIZE;
00393 rv = IFDPowerICC(rContext, IFD_POWER_UP,
00394 rContext->readerState->cardAtr,
00395 &dwAtrLen);
00396 rContext->readerState->cardAtrLength = dwAtrLen;
00397
00398
00399 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
00400
00401 if (rv == IFD_SUCCESS)
00402 {
00403 rContext->readerState->readerState |= SCARD_PRESENT;
00404 rContext->readerState->readerState &= ~SCARD_ABSENT;
00405 rContext->readerState->readerState |= SCARD_POWERED;
00406 rContext->readerState->readerState |= SCARD_NEGOTIABLE;
00407 rContext->readerState->readerState &= ~SCARD_SPECIFIC;
00408 rContext->readerState->readerState &= ~SCARD_UNKNOWN;
00409 rContext->readerState->readerState &= ~SCARD_SWALLOWED;
00410 }
00411 else
00412 {
00413 rContext->readerState->readerState |= SCARD_PRESENT;
00414 rContext->readerState->readerState &= ~SCARD_ABSENT;
00415 rContext->readerState->readerState |= SCARD_SWALLOWED;
00416 rContext->readerState->readerState &= ~SCARD_POWERED;
00417 rContext->readerState->readerState &= ~SCARD_NEGOTIABLE;
00418 rContext->readerState->readerState &= ~SCARD_SPECIFIC;
00419 rContext->readerState->readerState &= ~SCARD_UNKNOWN;
00420 rContext->readerState->cardAtrLength = 0;
00421 }
00422
00423 dwCurrentState = SCARD_PRESENT;
00424
00425 incrementEventCounter(rContext->readerState);
00426
00427 (void)StatSynchronize(rContext->readerState);
00428
00429 Log2(PCSC_LOG_INFO, "Card inserted into %s", lpcReader);
00430
00431 if (rv == IFD_SUCCESS)
00432 {
00433 if (rContext->readerState->cardAtrLength > 0)
00434 {
00435 LogXxd(PCSC_LOG_INFO, "Card ATR: ",
00436 rContext->readerState->cardAtr,
00437 rContext->readerState->cardAtrLength);
00438 }
00439 else
00440 Log1(PCSC_LOG_INFO, "Card ATR: (NULL)");
00441 }
00442 else
00443 Log1(PCSC_LOG_ERROR,"Error powering up card.");
00444 }
00445 }
00446
00447
00448
00449
00450 if (dwReaderSharing != rContext->dwContexts)
00451 {
00452 dwReaderSharing = rContext->dwContexts;
00453 rContext->readerState->readerSharing = dwReaderSharing;
00454 (void)StatSynchronize(rContext->readerState);
00455 }
00456
00457 if (rContext->pthCardEvent)
00458 {
00459 int ret;
00460
00461 ret = rContext->pthCardEvent(rContext->dwSlot);
00462 if (IFD_NO_SUCH_DEVICE == ret)
00463 (void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE);
00464 }
00465 else
00466 (void)SYS_USleep(PCSCLITE_STATUS_POLL_RATE);
00467
00468 if (rContext->dwLockId == 0xFFFF)
00469 {
00470
00471
00472
00473 (void)StatSynchronize(rContext->readerState);
00474 Log1(PCSC_LOG_INFO, "Die");
00475 rContext->dwLockId = 0;
00476 (void)SYS_ThreadExit(NULL);
00477 }
00478 }
00479 }
00480