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