46 #if defined(__linux__) && !defined(HAVE_LIBUSB) && !defined(HAVE_LIBUDEV)
47 #include <sys/types.h>
68 #define PCSCLITE_USB_PATH "/proc/bus/usb"
73 pthread_mutex_t usbNotifierMutex;
75 struct usb_device_descriptor
78 u_int8_t bDescriptorType;
80 u_int8_t bDeviceClass;
81 u_int8_t bDeviceSubClass;
82 u_int8_t bDeviceProtocol;
83 u_int8_t bMaxPacketSize0;
87 u_int8_t iManufacturer;
89 u_int8_t iSerialNumber;
90 u_int8_t bNumConfigurations;
92 __attribute__ ((packed));
94 static LONG HPAddHotPluggable(
int,
unsigned long);
95 static LONG HPRemoveHotPluggable(
int,
unsigned long);
96 static LONG HPReadBundleValues(
void);
97 static void HPEstablishUSBNotifications(
void);
99 static pthread_t usbNotifyThread;
100 static int AraKiriHotPlug = FALSE;
101 static int bundleSize = 0;
106 static struct _bundleTracker
111 struct _deviceNumber {
122 static LONG HPReadBundleValues(
void)
126 struct dirent *currFP = 0;
127 char fullPath[FILENAME_MAX];
128 char fullLibPath[FILENAME_MAX];
129 unsigned int listCount = 0;
131 hpDir = opendir(PCSCLITE_HP_DROPDIR);
136 "Cannot open PC/SC drivers directory: " PCSCLITE_HP_DROPDIR);
137 Log1(PCSC_LOG_INFO,
"Disabling USB support for pcscd.");
141 #define GET_KEY(key, values) \
142 rv = LTPBundleFindValueWithKey(&plist, key, values); \
145 Log2(PCSC_LOG_ERROR, "Value/Key not defined for " key " in %s", \
150 while ((currFP = readdir(hpDir)) != 0)
152 if (strstr(currFP->d_name,
".bundle") != 0)
156 list_t *manuIDs, *productIDs, *readerNames;
163 snprintf(fullPath, FILENAME_MAX,
"%s/%s/Contents/Info.plist",
164 PCSCLITE_HP_DROPDIR, currFP->d_name);
165 fullPath[FILENAME_MAX - 1] =
'\0';
167 rv = bundleParse(fullPath, &plist);
172 GET_KEY(PCSCLITE_HP_LIBRKEY_NAME, &values)
173 libraryPath = list_get_at(values, 0);
174 (
void)snprintf(fullLibPath, sizeof(fullLibPath),
175 "%s/%s/Contents/%s/%s",
176 PCSCLITE_HP_DROPDIR, currFP->d_name, PCSC_ARCH,
178 fullLibPath[sizeof(fullLibPath) - 1] = '\0';
180 GET_KEY(PCSCLITE_HP_CPCTKEY_NAME, &values)
181 GET_KEY(PCSCLITE_HP_MANUKEY_NAME, &manuIDs)
182 GET_KEY(PCSCLITE_HP_PRODKEY_NAME, &productIDs)
183 GET_KEY(PCSCLITE_HP_NAMEKEY_NAME, &readerNames)
186 for (alias=0; alias<list_size(manuIDs); alias++)
191 value = list_get_at(manuIDs, alias);
192 bundleTracker[listCount].manuID = strtol(value, NULL, 16);
194 value = list_get_at(productIDs, alias);
195 bundleTracker[listCount].productID = strtol(value, NULL, 16);
197 bundleTracker[listCount].readerName = strdup(list_get_at(readerNames, alias));
200 bundleTracker[listCount].bundleName = strdup(currFP->d_name);
201 bundleTracker[listCount].libraryPath = strdup(fullLibPath);
204 Log2(PCSC_LOG_INFO,
"Found driver for: %s",
205 bundleTracker[listCount].readerName);
209 if (listCount >= COUNT_OF(bundleTracker))
211 Log2(PCSC_LOG_CRITICAL,
"Too many readers declared. Maximum is %zd", COUNT_OF(bundleTracker));
215 bundleRelease(&plist);
220 bundleSize = listCount;
225 "No bundle files in pcsc drivers directory: " PCSCLITE_HP_DROPDIR);
226 Log1(PCSC_LOG_INFO,
"Disabling USB support for pcscd");
233 static void HPEstablishUSBNotifications(
void)
236 int i, j, usbDeviceStatus;
238 struct dirent *entry, *entryB;
240 int suspectDeviceNumber;
241 char dirpath[FILENAME_MAX];
242 char filename[FILENAME_MAX];
244 struct usb_device_descriptor usbDescriptor;
247 suspectDeviceNumber = 0;
251 for (i = 0; i < bundleSize; i++)
254 suspectDeviceNumber = 0;
258 bundleTracker[i].deviceNumber[j].status = 0;
261 dir = opendir(PCSCLITE_USB_PATH);
265 "Cannot open USB path directory: " PCSCLITE_USB_PATH);
270 while ((entry = readdir(dir)) != 0)
276 if (entry->d_name[0] ==
'.')
278 if (!strchr(
"0123456789",
279 entry->d_name[strlen(entry->d_name) - 1]))
284 snprintf(dirpath,
sizeof dirpath,
"%s/%s",
285 PCSCLITE_USB_PATH, entry->d_name);
287 dirB = opendir(dirpath);
292 "USB path seems to have disappeared %s", dirpath);
297 while ((entryB = readdir(dirB)) != NULL)
302 if (entryB->d_name[0] ==
'.')
307 snprintf(filename,
sizeof filename,
"%s/%s",
308 dirpath, entryB->d_name);
309 deviceNumber = atoi(entryB->d_name);
311 fd = open(filename, O_RDONLY);
315 ret = read(fd, (
void *) &usbDescriptor,
316 sizeof(usbDescriptor));
327 if (usbDescriptor.idVendor == bundleTracker[i].manuID &&
328 usbDescriptor.idProduct == bundleTracker[i].productID &&
329 usbDescriptor.idVendor !=0 &&
330 usbDescriptor.idProduct != 0)
334 if (bundleTracker[i].deviceNumber[j].
id == deviceNumber &&
335 bundleTracker[i].deviceNumber[j].
id != 0)
337 bundleTracker[i].deviceNumber[j].status = 1;
342 if (j == PCSCLITE_MAX_READERS_CONTEXTS)
345 suspectDeviceNumber = deviceNumber;
356 if (usbDeviceStatus == 1)
358 pthread_mutex_lock(&usbNotifierMutex);
362 if (bundleTracker[i].deviceNumber[j].
id == 0)
366 if (j == PCSCLITE_MAX_READERS_CONTEXTS)
368 "Too many identical readers plugged in");
371 HPAddHotPluggable(i, j+1);
372 bundleTracker[i].deviceNumber[j].id = suspectDeviceNumber;
375 pthread_mutex_unlock(&usbNotifierMutex);
378 if (usbDeviceStatus == 0)
383 if (bundleTracker[i].deviceNumber[j].
id != 0 &&
384 bundleTracker[i].deviceNumber[j].status == 0)
386 pthread_mutex_lock(&usbNotifierMutex);
387 HPRemoveHotPluggable(i, j+1);
388 bundleTracker[i].deviceNumber[j].id = 0;
389 pthread_mutex_unlock(&usbNotifierMutex);
410 Log1(PCSC_LOG_INFO,
"Hotplug stopped");
411 pthread_exit(&retval);
417 LONG HPSearchHotPluggables(
void)
423 bundleTracker[i].productID = 0;
424 bundleTracker[i].manuID = 0;
427 bundleTracker[i].deviceNumber[j].
id = 0;
430 HPReadBundleValues();
432 ThreadCreate(&usbNotifyThread, THREAD_ATTR_DETACHED,
433 (PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, 0);
438 LONG HPStopHotPluggables(
void)
440 AraKiriHotPlug = TRUE;
445 static LONG HPAddHotPluggable(
int i,
unsigned long usbAddr)
449 RFAddReader(bundleTracker[i].readerName, PCSCLITE_HP_BASE_PORT + usbAddr,
450 bundleTracker[i].libraryPath,
"");
455 static LONG HPRemoveHotPluggable(
int i,
unsigned long usbAddr)
457 RFRemoveReader(bundleTracker[i].readerName, PCSCLITE_HP_BASE_PORT + usbAddr);
465 ULONG HPRegisterForHotplugEvents(
void)
467 (void)pthread_mutex_init(&usbNotifierMutex, NULL);
471 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.