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