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