49 #if defined(__linux__) && !defined(HAVE_LIBUSB) && !defined(HAVE_LIBUDEV) 50 #include <sys/types.h> 71 #define PCSCLITE_USB_PATH "/proc/bus/usb" 76 pthread_mutex_t usbNotifierMutex;
78 struct usb_device_descriptor
81 u_int8_t bDescriptorType;
83 u_int8_t bDeviceClass;
84 u_int8_t bDeviceSubClass;
85 u_int8_t bDeviceProtocol;
86 u_int8_t bMaxPacketSize0;
90 u_int8_t iManufacturer;
92 u_int8_t iSerialNumber;
93 u_int8_t bNumConfigurations;
95 __attribute__ ((packed));
97 static LONG HPAddHotPluggable(
int,
unsigned long);
98 static LONG HPRemoveHotPluggable(
int,
unsigned long);
99 static LONG HPReadBundleValues(
void);
100 static void HPEstablishUSBNotifications(
void);
102 static pthread_t usbNotifyThread;
103 static int AraKiriHotPlug = FALSE;
104 static int bundleSize = 0;
109 static struct _bundleTracker
114 struct _deviceNumber {
125 static LONG HPReadBundleValues(
void)
129 struct dirent *currFP = 0;
130 char fullPath[FILENAME_MAX];
131 char fullLibPath[FILENAME_MAX];
132 unsigned int listCount = 0;
134 hpDir = opendir(PCSCLITE_HP_DROPDIR);
139 "Cannot open PC/SC drivers directory: " PCSCLITE_HP_DROPDIR);
140 Log1(PCSC_LOG_INFO,
"Disabling USB support for pcscd.");
144 #define GET_KEY(key, values) \ 145 rv = LTPBundleFindValueWithKey(&plist, key, values); \ 148 Log2(PCSC_LOG_ERROR, "Value/Key not defined for " key " in %s", \ 153 while ((currFP = readdir(hpDir)) != 0)
155 if (strstr(currFP->d_name,
".bundle") != 0)
159 list_t *manuIDs, *productIDs, *readerNames;
166 snprintf(fullPath, FILENAME_MAX,
"%s/%s/Contents/Info.plist",
167 PCSCLITE_HP_DROPDIR, currFP->d_name);
168 fullPath[FILENAME_MAX - 1] =
'\0';
175 GET_KEY(PCSCLITE_HP_LIBRKEY_NAME, &values)
176 libraryPath = list_get_at(values, 0);
177 (void)snprintf(fullLibPath,
sizeof(fullLibPath),
178 "%s/%s/Contents/%s/%s",
179 PCSCLITE_HP_DROPDIR, currFP->d_name, PCSC_ARCH,
181 fullLibPath[
sizeof(fullLibPath) - 1] =
'\0';
183 GET_KEY(PCSCLITE_HP_CPCTKEY_NAME, &values)
184 GET_KEY(PCSCLITE_HP_MANUKEY_NAME, &manuIDs)
185 GET_KEY(PCSCLITE_HP_PRODKEY_NAME, &productIDs)
186 GET_KEY(PCSCLITE_HP_NAMEKEY_NAME, &readerNames)
189 for (alias=0; alias<list_size(manuIDs); alias++)
194 value = list_get_at(manuIDs, alias);
195 bundleTracker[listCount].manuID = strtol(value, NULL, 16);
197 value = list_get_at(productIDs, alias);
198 bundleTracker[listCount].productID = strtol(value, NULL, 16);
200 bundleTracker[listCount].readerName = strdup(list_get_at(readerNames, alias));
203 bundleTracker[listCount].bundleName = strdup(currFP->d_name);
204 bundleTracker[listCount].libraryPath = strdup(fullLibPath);
207 Log2(PCSC_LOG_INFO,
"Found driver for: %s",
208 bundleTracker[listCount].readerName);
212 if (listCount >= COUNT_OF(bundleTracker))
214 Log2(PCSC_LOG_CRITICAL,
"Too many readers declared. Maximum is %zd", COUNT_OF(bundleTracker));
223 bundleSize = listCount;
228 "No bundle files in pcsc drivers directory: " PCSCLITE_HP_DROPDIR);
229 Log1(PCSC_LOG_INFO,
"Disabling USB support for pcscd");
236 static void HPEstablishUSBNotifications(
void)
239 int i, j, usbDeviceStatus;
241 struct dirent *entry, *entryB;
243 int suspectDeviceNumber;
244 char dirpath[FILENAME_MAX];
245 char filename[FILENAME_MAX];
247 struct usb_device_descriptor usbDescriptor;
250 suspectDeviceNumber = 0;
254 for (i = 0; i < bundleSize; i++)
257 suspectDeviceNumber = 0;
261 bundleTracker[i].deviceNumber[j].status = 0;
264 dir = opendir(PCSCLITE_USB_PATH);
268 "Cannot open USB path directory: " PCSCLITE_USB_PATH);
273 while ((entry = readdir(dir)) != 0)
279 if (entry->d_name[0] ==
'.')
281 if (!strchr(
"0123456789",
282 entry->d_name[strlen(entry->d_name) - 1]))
287 snprintf(dirpath,
sizeof dirpath,
"%s/%s",
288 PCSCLITE_USB_PATH, entry->d_name);
290 dirB = opendir(dirpath);
295 "USB path seems to have disappeared %s", dirpath);
300 while ((entryB = readdir(dirB)) != NULL)
305 if (entryB->d_name[0] ==
'.')
310 snprintf(filename,
sizeof filename,
"%s/%s",
311 dirpath, entryB->d_name);
312 deviceNumber = atoi(entryB->d_name);
314 fd = open(filename, O_RDONLY);
318 ret = read(fd, (
void *) &usbDescriptor,
319 sizeof(usbDescriptor));
330 if (usbDescriptor.idVendor == bundleTracker[i].manuID &&
331 usbDescriptor.idProduct == bundleTracker[i].productID &&
332 usbDescriptor.idVendor !=0 &&
333 usbDescriptor.idProduct != 0)
337 if (bundleTracker[i].deviceNumber[j].
id == deviceNumber &&
338 bundleTracker[i].deviceNumber[j].
id != 0)
340 bundleTracker[i].deviceNumber[j].status = 1;
345 if (j == PCSCLITE_MAX_READERS_CONTEXTS)
348 suspectDeviceNumber = deviceNumber;
359 if (usbDeviceStatus == 1)
361 pthread_mutex_lock(&usbNotifierMutex);
365 if (bundleTracker[i].deviceNumber[j].
id == 0)
369 if (j == PCSCLITE_MAX_READERS_CONTEXTS)
371 "Too many identical readers plugged in");
374 HPAddHotPluggable(i, j+1);
375 bundleTracker[i].deviceNumber[j].id = suspectDeviceNumber;
378 pthread_mutex_unlock(&usbNotifierMutex);
381 if (usbDeviceStatus == 0)
386 if (bundleTracker[i].deviceNumber[j].
id != 0 &&
387 bundleTracker[i].deviceNumber[j].status == 0)
389 pthread_mutex_lock(&usbNotifierMutex);
390 HPRemoveHotPluggable(i, j+1);
391 bundleTracker[i].deviceNumber[j].id = 0;
392 pthread_mutex_unlock(&usbNotifierMutex);
413 Log1(PCSC_LOG_INFO,
"Hotplug stopped");
414 pthread_exit(&retval);
420 LONG HPSearchHotPluggables(
void)
426 bundleTracker[i].productID = 0;
427 bundleTracker[i].manuID = 0;
430 bundleTracker[i].deviceNumber[j].
id = 0;
433 HPReadBundleValues();
435 ThreadCreate(&usbNotifyThread, THREAD_ATTR_DETACHED,
436 (PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, 0);
441 LONG HPStopHotPluggables(
void)
443 AraKiriHotPlug = TRUE;
448 static LONG HPAddHotPluggable(
int i,
unsigned long usbAddr)
452 RFAddReader(bundleTracker[i].readerName, PCSCLITE_HP_BASE_PORT + usbAddr,
453 bundleTracker[i].libraryPath,
"");
458 static LONG HPRemoveHotPluggable(
int i,
unsigned long usbAddr)
460 RFRemoveReader(bundleTracker[i].readerName, PCSCLITE_HP_BASE_PORT + usbAddr);
468 ULONG HPRegisterForHotplugEvents(
void)
470 (void)pthread_mutex_init(&usbNotifierMutex, NULL);
474 void HPReCheckSerialReaders(
void)
This handles abstract system level calls.
int SYS_Sleep(int)
Makes the current process sleep for some seconds.
Reads lexical config files and updates database.
#define PCSCLITE_MAX_READERS_CONTEXTS
Maximum readers context (a slot is count as a reader)
This defines some structures and #defines to be used over the transport layer.
This keeps a list of defines for pcsc-lite.
This keeps a list of defines for pcsc-lite.
This keeps track of a list of currently available reader structures.
This provides a search API for hot pluggble devices.
int bundleParse(const char *fileName, list_t *l)
Parse a Info.plist file and file a list.
void bundleRelease(list_t *l)
Free the list created by bundleParse()