23 #if defined(__linux__) && !defined(HAVE_LIBUSB) && !defined(HAVE_LIBUDEV)
24 #include <sys/types.h>
45 #define PCSCLITE_USB_PATH "/proc/bus/usb"
50 pthread_mutex_t usbNotifierMutex;
52 struct usb_device_descriptor
55 u_int8_t bDescriptorType;
57 u_int8_t bDeviceClass;
58 u_int8_t bDeviceSubClass;
59 u_int8_t bDeviceProtocol;
60 u_int8_t bMaxPacketSize0;
64 u_int8_t iManufacturer;
66 u_int8_t iSerialNumber;
67 u_int8_t bNumConfigurations;
69 __attribute__ ((packed));
71 static LONG HPAddHotPluggable(
int,
unsigned long);
72 static LONG HPRemoveHotPluggable(
int,
unsigned long);
73 static LONG HPReadBundleValues(
void);
74 static void HPEstablishUSBNotifications(
void);
76 static pthread_t usbNotifyThread;
77 static int AraKiriHotPlug = FALSE;
78 static int bundleSize = 0;
83 static struct _bundleTracker
88 struct _deviceNumber {
99 static LONG HPReadBundleValues(
void)
103 struct dirent *currFP = 0;
104 char fullPath[FILENAME_MAX];
105 char fullLibPath[FILENAME_MAX];
106 unsigned int listCount = 0;
108 hpDir = opendir(PCSCLITE_HP_DROPDIR);
113 "Cannot open PC/SC drivers directory: " PCSCLITE_HP_DROPDIR);
114 Log1(PCSC_LOG_INFO,
"Disabling USB support for pcscd.");
118 #define GET_KEY(key, values) \
119 rv = LTPBundleFindValueWithKey(&plist, key, values); \
122 Log2(PCSC_LOG_ERROR, "Value/Key not defined for " key " in %s", \
127 while ((currFP = readdir(hpDir)) != 0)
129 if (strstr(currFP->d_name,
".bundle") != 0)
133 list_t *manuIDs, *productIDs, *readerNames;
140 snprintf(fullPath, FILENAME_MAX,
"%s/%s/Contents/Info.plist",
141 PCSCLITE_HP_DROPDIR, currFP->d_name);
142 fullPath[FILENAME_MAX - 1] =
'\0';
149 GET_KEY(PCSCLITE_HP_LIBRKEY_NAME, &values)
150 libraryPath = list_get_at(values, 0);
151 (
void)snprintf(fullLibPath, sizeof(fullLibPath),
152 "%s/%s/Contents/%s/%s",
153 PCSCLITE_HP_DROPDIR, currFP->d_name, PCSC_ARCH,
155 fullLibPath[sizeof(fullLibPath) - 1] = '\0';
157 GET_KEY(PCSCLITE_HP_CPCTKEY_NAME, &values)
158 GET_KEY(PCSCLITE_HP_MANUKEY_NAME, &manuIDs)
159 GET_KEY(PCSCLITE_HP_PRODKEY_NAME, &productIDs)
160 GET_KEY(PCSCLITE_HP_NAMEKEY_NAME, &readerNames)
163 for (alias=0; alias<list_size(manuIDs); alias++)
168 value = list_get_at(manuIDs, alias);
169 bundleTracker[listCount].manuID = strtol(value, NULL, 16);
171 value = list_get_at(productIDs, alias);
172 bundleTracker[listCount].productID = strtol(value, NULL, 16);
174 bundleTracker[listCount].readerName = strdup(list_get_at(readerNames, alias));
177 bundleTracker[listCount].bundleName = strdup(currFP->d_name);
178 bundleTracker[listCount].libraryPath = strdup(fullLibPath);
181 Log2(PCSC_LOG_INFO,
"Found driver for: %s",
182 bundleTracker[listCount].readerName);
186 if (listCount >=
sizeof(bundleTracker)/
sizeof(bundleTracker[0]))
188 Log2(PCSC_LOG_CRITICAL,
"Too many readers declared. Maximum is %zd",
sizeof(bundleTracker)/
sizeof(bundleTracker[0]));
197 bundleSize = listCount;
202 "No bundle files in pcsc drivers directory: " PCSCLITE_HP_DROPDIR);
203 Log1(PCSC_LOG_INFO,
"Disabling USB support for pcscd");
210 static void HPEstablishUSBNotifications(
void)
213 int i, j, usbDeviceStatus;
215 struct dirent *entry, *entryB;
217 int suspectDeviceNumber;
218 char dirpath[FILENAME_MAX];
219 char filename[FILENAME_MAX];
221 struct usb_device_descriptor usbDescriptor;
224 suspectDeviceNumber = 0;
228 for (i = 0; i < bundleSize; i++)
231 suspectDeviceNumber = 0;
235 bundleTracker[i].deviceNumber[j].status = 0;
238 dir = opendir(PCSCLITE_USB_PATH);
242 "Cannot open USB path directory: " PCSCLITE_USB_PATH);
247 while ((entry = readdir(dir)) != 0)
253 if (entry->d_name[0] ==
'.')
255 if (!strchr(
"0123456789",
256 entry->d_name[strlen(entry->d_name) - 1]))
261 snprintf(dirpath,
sizeof dirpath,
"%s/%s",
262 PCSCLITE_USB_PATH, entry->d_name);
264 dirB = opendir(dirpath);
269 "USB path seems to have disappeared %s", dirpath);
274 while ((entryB = readdir(dirB)) != NULL)
279 if (entryB->d_name[0] ==
'.')
284 snprintf(filename,
sizeof filename,
"%s/%s",
285 dirpath, entryB->d_name);
286 deviceNumber = atoi(entryB->d_name);
288 fd = open(filename, O_RDONLY);
292 ret = read(fd, (
void *) &usbDescriptor,
293 sizeof(usbDescriptor));
304 if (usbDescriptor.idVendor == bundleTracker[i].manuID &&
305 usbDescriptor.idProduct == bundleTracker[i].productID &&
306 usbDescriptor.idVendor !=0 &&
307 usbDescriptor.idProduct != 0)
311 if (bundleTracker[i].deviceNumber[j].
id == deviceNumber &&
312 bundleTracker[i].deviceNumber[j].
id != 0)
314 bundleTracker[i].deviceNumber[j].status = 1;
319 if (j == PCSCLITE_MAX_READERS_CONTEXTS)
322 suspectDeviceNumber = deviceNumber;
333 if (usbDeviceStatus == 1)
335 pthread_mutex_lock(&usbNotifierMutex);
339 if (bundleTracker[i].deviceNumber[j].
id == 0)
343 if (j == PCSCLITE_MAX_READERS_CONTEXTS)
345 "Too many identical readers plugged in");
348 HPAddHotPluggable(i, j+1);
349 bundleTracker[i].deviceNumber[j].id = suspectDeviceNumber;
352 pthread_mutex_unlock(&usbNotifierMutex);
355 if (usbDeviceStatus == 0)
360 if (bundleTracker[i].deviceNumber[j].
id != 0 &&
361 bundleTracker[i].deviceNumber[j].status == 0)
363 pthread_mutex_lock(&usbNotifierMutex);
364 HPRemoveHotPluggable(i, j+1);
365 bundleTracker[i].deviceNumber[j].id = 0;
366 pthread_mutex_unlock(&usbNotifierMutex);
387 Log1(PCSC_LOG_INFO,
"Hotplug stopped");
388 pthread_exit(&retval);
394 LONG HPSearchHotPluggables(
void)
400 bundleTracker[i].productID = 0;
401 bundleTracker[i].manuID = 0;
404 bundleTracker[i].deviceNumber[j].
id = 0;
407 HPReadBundleValues();
409 ThreadCreate(&usbNotifyThread, THREAD_ATTR_DETACHED,
410 (PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, 0);
415 LONG HPStopHotPluggables(
void)
417 AraKiriHotPlug = TRUE;
422 static LONG HPAddHotPluggable(
int i,
unsigned long usbAddr)
426 RFAddReader(bundleTracker[i].readerName, PCSCLITE_HP_BASE_PORT + usbAddr,
427 bundleTracker[i].libraryPath,
"");
432 static LONG HPRemoveHotPluggable(
int i,
unsigned long usbAddr)
434 RFRemoveReader(bundleTracker[i].readerName, PCSCLITE_HP_BASE_PORT + usbAddr);
442 ULONG HPRegisterForHotplugEvents(
void)
444 (void)pthread_mutex_init(&usbNotifierMutex, NULL);
448 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()