00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00019 #include "config.h"
00020 #include <string.h>
00021
00022 #if defined(__linux__) && !defined(HAVE_LIBUSB) && !defined(HAVE_LIBHAL)
00023 #include <sys/types.h>
00024 #include <stdio.h>
00025 #include <dirent.h>
00026 #include <fcntl.h>
00027 #include <time.h>
00028 #include <stdlib.h>
00029 #include <unistd.h>
00030
00031 #include "misc.h"
00032 #include "pcsclite.h"
00033 #include "pcscd.h"
00034 #include "debuglog.h"
00035 #include "parser.h"
00036 #include "readerfactory.h"
00037 #include "winscard_msg.h"
00038 #include "sys_generic.h"
00039 #include "hotplug.h"
00040
00041 #define PCSCLITE_USB_PATH "/proc/bus/usb"
00042
00043 #define FALSE 0
00044 #define TRUE 1
00045
00046 char ReCheckSerialReaders = FALSE;
00047 extern PCSCLITE_MUTEX usbNotifierMutex;
00048
00049 struct usb_device_descriptor
00050 {
00051 u_int8_t bLength;
00052 u_int8_t bDescriptorType;
00053 u_int16_t bcdUSB;
00054 u_int8_t bDeviceClass;
00055 u_int8_t bDeviceSubClass;
00056 u_int8_t bDeviceProtocol;
00057 u_int8_t bMaxPacketSize0;
00058 u_int16_t idVendor;
00059 u_int16_t idProduct;
00060 u_int16_t bcdDevice;
00061 u_int8_t iManufacturer;
00062 u_int8_t iProduct;
00063 u_int8_t iSerialNumber;
00064 u_int8_t bNumConfigurations;
00065 }
00066 __attribute__ ((packed));
00067
00068 static LONG HPAddHotPluggable(int, unsigned long);
00069 static LONG HPRemoveHotPluggable(int, unsigned long);
00070 static LONG HPReadBundleValues(void);
00071 static void HPEstablishUSBNotifications(void);
00072
00073 static PCSCLITE_THREAD_T usbNotifyThread;
00074 static int AraKiriHotPlug = FALSE;
00075 static int bundleSize = 0;
00076
00080 static struct _bundleTracker
00081 {
00082 long manuID;
00083 long productID;
00084
00085 struct _deviceNumber {
00086 int id;
00087 char status;
00088 } deviceNumber[PCSCLITE_MAX_READERS_CONTEXTS];
00089
00090 char *bundleName;
00091 char *libraryPath;
00092 char *readerName;
00093 }
00094 bundleTracker[PCSCLITE_MAX_READERS_CONTEXTS];
00095
00096 static LONG HPReadBundleValues(void)
00097 {
00098
00099 LONG rv;
00100 DIR *hpDir;
00101 struct dirent *currFP = 0;
00102 char fullPath[FILENAME_MAX];
00103 char fullLibPath[FILENAME_MAX];
00104 char keyValue[TOKEN_MAX_VALUE_SIZE];
00105 int listCount = 0;
00106
00107 hpDir = opendir(PCSCLITE_HP_DROPDIR);
00108
00109 if (hpDir == NULL)
00110 {
00111 Log1(PCSC_LOG_INFO,
00112 "Cannot open PC/SC drivers directory: " PCSCLITE_HP_DROPDIR);
00113 Log1(PCSC_LOG_INFO, "Disabling USB support for pcscd.");
00114 return -1;
00115 }
00116
00117 while ((currFP = readdir(hpDir)) != 0)
00118 {
00119 if (strstr(currFP->d_name, ".bundle") != 0)
00120 {
00121 int alias = 0;
00122
00123
00124
00125
00126
00127 snprintf(fullPath, FILENAME_MAX, "%s/%s/Contents/Info.plist",
00128 PCSCLITE_HP_DROPDIR, currFP->d_name);
00129 fullPath[FILENAME_MAX - 1] = '\0';
00130
00131
00132 while (LTPBundleFindValueWithKey(fullPath, PCSCLITE_HP_MANUKEY_NAME,
00133 keyValue, alias) == 0)
00134 {
00135 bundleTracker[listCount].bundleName = strdup(currFP->d_name);
00136
00137
00138 rv = LTPBundleFindValueWithKey(fullPath, PCSCLITE_HP_MANUKEY_NAME,
00139 keyValue, alias);
00140 if (rv == 0)
00141 bundleTracker[listCount].manuID = strtol(keyValue, 0, 16);
00142
00143
00144 rv = LTPBundleFindValueWithKey(fullPath, PCSCLITE_HP_PRODKEY_NAME,
00145 keyValue, alias);
00146 if (rv == 0)
00147 bundleTracker[listCount].productID =
00148 strtol(keyValue, 0, 16);
00149
00150
00151 rv = LTPBundleFindValueWithKey(fullPath, PCSCLITE_HP_NAMEKEY_NAME,
00152 keyValue, alias);
00153 if (rv == 0)
00154 bundleTracker[listCount].readerName = strdup(keyValue);
00155
00156
00157 rv = LTPBundleFindValueWithKey(fullPath, PCSCLITE_HP_LIBRKEY_NAME,
00158 keyValue, 0);
00159 if (rv == 0)
00160 {
00161 snprintf(fullLibPath, sizeof(fullLibPath),
00162 "%s/%s/Contents/%s/%s",
00163 PCSCLITE_HP_DROPDIR, currFP->d_name, PCSC_ARCH, keyValue);
00164 fullLibPath[sizeof(fullLibPath) - 1] = '\0';
00165 bundleTracker[listCount].libraryPath = strdup(fullLibPath);
00166 }
00167
00168 listCount++;
00169 alias++;
00170
00171 if (listCount >= sizeof(bundleTracker)/sizeof(bundleTracker[0]))
00172 {
00173 Log2(PCSC_LOG_CRITICAL, "Too many readers declared. Maximum is %d", sizeof(bundleTracker)/sizeof(bundleTracker[0]));
00174 goto end;
00175 }
00176 }
00177 }
00178 }
00179
00180 end:
00181 bundleSize = listCount;
00182
00183 if (bundleSize == 0)
00184 {
00185 Log1(PCSC_LOG_INFO,
00186 "No bundle files in pcsc drivers directory: " PCSCLITE_HP_DROPDIR);
00187 Log1(PCSC_LOG_INFO, "Disabling USB support for pcscd");
00188 }
00189
00190 closedir(hpDir);
00191 return 0;
00192 }
00193
00194 static void HPEstablishUSBNotifications(void)
00195 {
00196
00197 int i, j, usbDeviceStatus;
00198 DIR *dir, *dirB;
00199 struct dirent *entry, *entryB;
00200 int deviceNumber;
00201 int suspectDeviceNumber;
00202 char dirpath[FILENAME_MAX];
00203 char filename[FILENAME_MAX];
00204 int fd, ret;
00205 struct usb_device_descriptor usbDescriptor;
00206
00207 usbDeviceStatus = 0;
00208 suspectDeviceNumber = 0;
00209
00210 while (1)
00211 {
00212 for (i = 0; i < bundleSize; i++)
00213 {
00214 usbDeviceStatus = 0;
00215 suspectDeviceNumber = 0;
00216
00217 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
00218
00219 bundleTracker[i].deviceNumber[j].status = 0;
00220
00221 dir = NULL;
00222 dir = opendir(PCSCLITE_USB_PATH);
00223 if (dir == NULL)
00224 {
00225 Log1(PCSC_LOG_ERROR,
00226 "Cannot open USB path directory: " PCSCLITE_USB_PATH);
00227 return;
00228 }
00229
00230 entry = NULL;
00231 while ((entry = readdir(dir)) != 0)
00232 {
00233
00234
00235
00236
00237 if (entry->d_name[0] == '.')
00238 continue;
00239 if (!strchr("0123456789",
00240 entry->d_name[strlen(entry->d_name) - 1]))
00241 {
00242 continue;
00243 }
00244
00245 sprintf(dirpath, "%s/%s", PCSCLITE_USB_PATH, entry->d_name);
00246
00247 dirB = opendir(dirpath);
00248
00249 if (dirB == NULL)
00250 {
00251 Log2(PCSC_LOG_ERROR,
00252 "USB path seems to have disappeared %s", dirpath);
00253 closedir(dir);
00254 return;
00255 }
00256
00257 while ((entryB = readdir(dirB)) != NULL)
00258 {
00259
00260
00261
00262 if (entryB->d_name[0] == '.')
00263 continue;
00264
00265
00266
00267 sprintf(filename, "%s/%s", dirpath, entryB->d_name);
00268 sscanf(entryB->d_name, "%d", &deviceNumber);
00269
00270 fd = open(filename, O_RDONLY);
00271 if (fd < 0)
00272 continue;
00273
00274 ret = read(fd, (void *) &usbDescriptor,
00275 sizeof(usbDescriptor));
00276
00277 close(fd);
00278
00279 if (ret < 0)
00280 continue;
00281
00282
00283
00284
00285
00286 if (usbDescriptor.idVendor == bundleTracker[i].manuID &&
00287 usbDescriptor.idProduct == bundleTracker[i].productID &&
00288 usbDescriptor.idVendor !=0 &&
00289 usbDescriptor.idProduct != 0)
00290 {
00291 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
00292 {
00293 if (bundleTracker[i].deviceNumber[j].id == deviceNumber &&
00294 bundleTracker[i].deviceNumber[j].id != 0)
00295 {
00296 bundleTracker[i].deviceNumber[j].status = 1;
00297 break;
00298 }
00299 }
00300
00301 if (j == PCSCLITE_MAX_READERS_CONTEXTS)
00302 {
00303 usbDeviceStatus = 1;
00304 suspectDeviceNumber = deviceNumber;
00305 }
00306 }
00307
00308 }
00309
00310 closedir(dirB);
00311
00312 }
00313
00314
00315 if (usbDeviceStatus == 1)
00316 {
00317 SYS_MutexLock(&usbNotifierMutex);
00318
00319 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
00320 {
00321 if (bundleTracker[i].deviceNumber[j].id == 0)
00322 break;
00323 }
00324
00325 if (j == PCSCLITE_MAX_READERS_CONTEXTS)
00326 Log1(PCSC_LOG_ERROR,
00327 "Too many identical readers plugged in");
00328 else
00329 {
00330 HPAddHotPluggable(i, j+1);
00331 bundleTracker[i].deviceNumber[j].id = suspectDeviceNumber;
00332 }
00333
00334 SYS_MutexUnLock(&usbNotifierMutex);
00335 }
00336 else
00337 if (usbDeviceStatus == 0)
00338 {
00339
00340 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
00341 {
00342 if (bundleTracker[i].deviceNumber[j].id != 0 &&
00343 bundleTracker[i].deviceNumber[j].status == 0)
00344 {
00345 SYS_MutexLock(&usbNotifierMutex);
00346 HPRemoveHotPluggable(i, j+1);
00347 bundleTracker[i].deviceNumber[j].id = 0;
00348 SYS_MutexUnLock(&usbNotifierMutex);
00349 }
00350 }
00351 }
00352 else
00353 {
00354
00355
00356
00357 }
00358
00359 if (dir)
00360 closedir(dir);
00361
00362 }
00363
00364 SYS_Sleep(1);
00365 if (AraKiriHotPlug)
00366 {
00367 int retval;
00368
00369 Log1(PCSC_LOG_INFO, "Hotplug stopped");
00370 pthread_exit(&retval);
00371 }
00372
00373 }
00374 }
00375
00376 LONG HPSearchHotPluggables(void)
00377 {
00378 int i, j;
00379
00380 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00381 {
00382 bundleTracker[i].productID = 0;
00383 bundleTracker[i].manuID = 0;
00384
00385 for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
00386 bundleTracker[i].deviceNumber[j].id = 0;
00387 }
00388
00389 HPReadBundleValues();
00390
00391 SYS_ThreadCreate(&usbNotifyThread, THREAD_ATTR_DETACHED,
00392 (PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, 0);
00393
00394 return 0;
00395 }
00396
00397 LONG HPStopHotPluggables(void)
00398 {
00399 AraKiriHotPlug = TRUE;
00400
00401 return 0;
00402 }
00403
00404 static LONG HPAddHotPluggable(int i, unsigned long usbAddr)
00405 {
00406
00407
00408 RFAddReader(bundleTracker[i].readerName, PCSCLITE_HP_BASE_PORT + usbAddr,
00409 bundleTracker[i].libraryPath, "");
00410
00411 return 1;
00412 }
00413
00414 static LONG HPRemoveHotPluggable(int i, unsigned long usbAddr)
00415 {
00416 RFRemoveReader(bundleTracker[i].readerName, PCSCLITE_HP_BASE_PORT + usbAddr);
00417
00418 return 1;
00419 }
00420
00424 ULONG HPRegisterForHotplugEvents(void)
00425 {
00426 return 0;
00427 }
00428
00429 void HPReCheckSerialReaders(void)
00430 {
00431 }
00432
00433 #endif