[Pcsclite-cvs-commit] PCSC/src hotplug_libusb.c,1.5,1.6
rousseau@quantz.debian.org
rousseau@quantz.debian.org
Tue, 26 Aug 2003 15:12:49 +0200
Update of /cvsroot/pcsclite/PCSC/src
In directory quantz:/tmp/cvs-serv10580/src
Modified Files:
hotplug_libusb.c
Log Message:
complete redesign to support up to PCSCLITE_MAX_READERS readers whatever
the driver they use (correct bug [ #300067 ] More than 4 Hotplug Readers in
the same time on Linux)
Index: hotplug_libusb.c
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/hotplug_libusb.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** hotplug_libusb.c 21 Aug 2003 17:27:53 -0000 1.5
--- hotplug_libusb.c 26 Aug 2003 13:12:46 -0000 1.6
***************
*** 37,89 ****
// PCSCLITE_HP_DROPDIR is defined using ./configure --enable-usbdropdir=foobar
! #define PCSCLITE_MANUKEY_NAME "ifdVendorID"
! #define PCSCLITE_PRODKEY_NAME "ifdProductID"
! #define PCSCLITE_NAMEKEY_NAME "ifdFriendlyName"
! #define PCSCLITE_LIBRKEY_NAME "CFBundleExecutable"
! #define PCSCLITE_HP_MAX_IDENTICAL_READERS 16
! #define PCSCLITE_HP_MAX_SIMUL_READERS 04
! #define PCSCLITE_HP_MAX_DRIVERS 20
! #define BUS_DEVICE_STRSIZE 256
/* set to 1 if you want to see USB hotplug debug messages */
! #define DEBUG_USB_HOTPLUG 0
extern int LTPBundleFindValueWithKey(char *, char *, char *, int);
extern PCSCLITE_MUTEX usbNotifierMutex;
- LONG HPAddHotPluggable(int, unsigned long);
- LONG HPRemoveHotPluggable(int, unsigned long);
- LONG HPReadBundleValues();
-
static PCSCLITE_THREAD_T usbNotifyThread;
! static int bundleSize = 0;
/*
! * A list to keep track of 20 simultaneous readers
*/
!
! static struct _bundleTracker
{
! long manuID;
! long productID;
!
! struct _deviceNumber {
! short plugged;
! char status;
! char bus_device[BUS_DEVICE_STRSIZE];
! } deviceNumber[PCSCLITE_HP_MAX_SIMUL_READERS];
char *bundleName;
char *libraryPath;
char *readerName;
! }
! bundleTracker[PCSCLITE_HP_MAX_DRIVERS];
!
! // static LONG hpManu_id, hpProd_id;
! // static int bundleArraySize;
! LONG HPReadBundleValues()
{
LONG rv;
DIR *hpDir;
--- 37,96 ----
// PCSCLITE_HP_DROPDIR is defined using ./configure --enable-usbdropdir=foobar
! #define PCSCLITE_MANUKEY_NAME "ifdVendorID"
! #define PCSCLITE_PRODKEY_NAME "ifdProductID"
! #define PCSCLITE_NAMEKEY_NAME "ifdFriendlyName"
! #define PCSCLITE_LIBRKEY_NAME "CFBundleExecutable"
! // PCSCLITE_MAX_READERS is defined in pcsclite.h
! #define PCSCLITE_MAX_DRIVERS 16
! #define BUS_DEVICE_STRSIZE 256
! #define PCSCLITE_HP_BASE_PORT 0x200000
!
! #define READER_ABSENT 0
! #define READER_PRESENT 1
!
! #define FALSE 0
! #define TRUE 1
/* set to 1 if you want to see USB hotplug debug messages */
! #define DEBUG_USB_HOTPLUG 1
extern int LTPBundleFindValueWithKey(char *, char *, char *, int);
extern PCSCLITE_MUTEX usbNotifierMutex;
static PCSCLITE_THREAD_T usbNotifyThread;
! static int driverSize = -1;
/*
! * keep track of PCSCLITE_MAX_DRIVERS simultaneous drivers
*/
! static struct _driverTracker
{
! long manuID;
! long productID;
char *bundleName;
char *libraryPath;
char *readerName;
! } driverTracker[PCSCLITE_MAX_DRIVERS];
! /*
! * keep track of PCSCLITE_MAX_READERS simultaneous readers
! */
! static struct _readerTracker
{
+ // short plugged;
+ char status;
+ char bus_device[BUS_DEVICE_STRSIZE]; /* device name */
+
+ struct _driverTracker *driver; /* driver for this reader */
+ } readerTracker[PCSCLITE_MAX_READERS];
+
+ LONG HPReadBundleValues(void);
+ LONG HPAddHotPluggable(struct usb_device *dev, const char bus_device[],
+ struct _driverTracker *driver);
+ LONG HPRemoveHotPluggable(int index);
+ LONG HPReadBundleValues(void)
+ {
LONG rv;
DIR *hpDir;
***************
*** 121,125 ****
keyValue, alias) == 0)
{
! bundleTracker[listCount].bundleName = strdup(currFP->d_name);
// Get ifdVendorID
--- 128,132 ----
keyValue, alias) == 0)
{
! driverTracker[listCount].bundleName = strdup(currFP->d_name);
// Get ifdVendorID
***************
*** 127,131 ****
keyValue, alias);
if (rv == 0)
! bundleTracker[listCount].manuID = strtol(keyValue, 0, 16);
// get ifdProductID
--- 134,138 ----
keyValue, alias);
if (rv == 0)
! driverTracker[listCount].manuID = strtol(keyValue, 0, 16);
// get ifdProductID
***************
*** 133,137 ****
keyValue, alias);
if (rv == 0)
! bundleTracker[listCount].productID =
strtol(keyValue, 0, 16);
--- 140,144 ----
keyValue, alias);
if (rv == 0)
! driverTracker[listCount].productID =
strtol(keyValue, 0, 16);
***************
*** 140,144 ****
keyValue, alias);
if (rv == 0)
! bundleTracker[listCount].readerName = strdup(keyValue);
// get CFBundleExecutable
--- 147,151 ----
keyValue, alias);
if (rv == 0)
! driverTracker[listCount].readerName = strdup(keyValue);
// get CFBundleExecutable
***************
*** 150,156 ****
currFP->d_name, "/Contents/Linux/", keyValue);
fullLibPath[FILENAME_MAX - 1] = '\0';
! bundleTracker[listCount].libraryPath = strdup(fullLibPath);
}
listCount++;
alias++;
--- 157,168 ----
currFP->d_name, "/Contents/Linux/", keyValue);
fullLibPath[FILENAME_MAX - 1] = '\0';
! driverTracker[listCount].libraryPath = strdup(fullLibPath);
}
+ #if DEBUG_USB_HOTPLUG
+ DebugLogB("Found driver for: %s",
+ driverTracker[listCount].readerName);
+ #endif
+
listCount++;
alias++;
***************
*** 159,165 ****
}
! bundleSize = listCount;
! if (bundleSize == 0)
{
DebugLogA("No bundle files in pcsc drivers directory: " PCSCLITE_HP_DROPDIR);
--- 171,178 ----
}
! driverSize = listCount;
! closedir(hpDir);
! if (driverSize == 0)
{
DebugLogA("No bundle files in pcsc drivers directory: " PCSCLITE_HP_DROPDIR);
***************
*** 167,171 ****
}
- closedir(hpDir);
return 0;
}
--- 180,183 ----
***************
*** 173,188 ****
void HPEstablishUSBNotifications()
{
!
! int i, j, usbDeviceStatus;
! #ifdef MSC_TARGET_BSD
! int fd;
! char filename[BUS_DEVICE_STRSIZE];
! #endif
struct usb_bus *bus;
struct usb_device *dev;
char bus_device[BUS_DEVICE_STRSIZE];
- usbDeviceStatus = 0;
-
usb_init();
while (1)
--- 185,193 ----
void HPEstablishUSBNotifications()
{
! int i, j;
struct usb_bus *bus;
struct usb_device *dev;
char bus_device[BUS_DEVICE_STRSIZE];
usb_init();
while (1)
***************
*** 190,210 ****
usb_find_busses();
usb_find_devices();
- for (i = 0; i < bundleSize; i++)
- {
- usbDeviceStatus = 0;
! for (j=0; j < PCSCLITE_HP_MAX_SIMUL_READERS; j++)
! /* clear rollcall */
! bundleTracker[i].deviceNumber[j].status = 0;
! for (bus = usb_get_busses(); bus; bus = bus->next)
{
! for (dev = bus->devices; dev; dev = dev->next)
{
! if (dev->descriptor.idVendor == bundleTracker[i].manuID &&
! dev->descriptor.idProduct == bundleTracker[i].productID &&
! dev->descriptor.idVendor !=0 &&
! dev->descriptor.idProduct != 0)
{
/* A known device has been found */
snprintf(bus_device, BUS_DEVICE_STRSIZE, "%s:%s",
--- 195,218 ----
usb_find_busses();
usb_find_devices();
! for (i=0; i < PCSCLITE_MAX_READERS; i++)
! /* clear rollcall */
! readerTracker[i].status = READER_ABSENT;
! /* For each USB bus */
! for (bus = usb_get_busses(); bus; bus = bus->next)
! {
! /* For each USB device */
! for (dev = bus->devices; dev; dev = dev->next)
{
! /* check if the device is supported by one driver */
! for (i=0; i<PCSCLITE_MAX_DRIVERS; i++)
{
! if (driverTracker[i].libraryPath != NULL &&
! dev->descriptor.idVendor == driverTracker[i].manuID &&
! dev->descriptor.idProduct == driverTracker[i].productID)
{
+ int newreader;
+
/* A known device has been found */
snprintf(bus_device, BUS_DEVICE_STRSIZE, "%s:%s",
***************
*** 212,228 ****
bus_device[BUS_DEVICE_STRSIZE - 1] = '\0';
#if DEBUG_USB_HOTPLUG
! DebugLogB("Found matching USB device %s", bus_device);
#endif
! for (j=0; j < PCSCLITE_HP_MAX_SIMUL_READERS; j++)
{
! if (strncmp(bundleTracker[i].deviceNumber[j].bus_device,
! bus_device, BUS_DEVICE_STRSIZE) == 0 &&
! bundleTracker[i].deviceNumber[j].plugged)
{
! /* I'm here */
! bundleTracker[i].deviceNumber[j].status = 1;
#if DEBUG_USB_HOTPLUG
! DebugLogB("Refresh USB device %s status",
! bus_device);
#endif
break;
--- 220,238 ----
bus_device[BUS_DEVICE_STRSIZE - 1] = '\0';
#if DEBUG_USB_HOTPLUG
! DebugLogB("Found matching USB device: %s", bus_device);
#endif
! newreader = TRUE;
!
! /* Check if the reader is a new one */
! for (j=0; j<PCSCLITE_MAX_READERS; j++)
{
! if (strncmp(readerTracker[j].bus_device,
! bus_device, BUS_DEVICE_STRSIZE) == 0)
{
! /* The reader is already known */
! readerTracker[j].status = READER_PRESENT;
! newreader = FALSE;
#if DEBUG_USB_HOTPLUG
! DebugLogB("Refresh USB device: %s", bus_device);
#endif
break;
***************
*** 230,331 ****
}
! if (j == PCSCLITE_HP_MAX_SIMUL_READERS)
! usbDeviceStatus = 1;
}
! } /* End of for..loop */
! } /* End of for..loop */
! if (usbDeviceStatus == 1)
{
! SYS_MutexLock(&usbNotifierMutex);
!
! for (j=0; j < PCSCLITE_HP_MAX_SIMUL_READERS; j++)
! {
! if (!bundleTracker[i].deviceNumber[j].plugged)
! break;
! }
!
! if (j == PCSCLITE_HP_MAX_SIMUL_READERS)
! DebugLogA("Too many identical readers plugged in");
! else
! {
! DebugLogB("Adding USB device %s", bus_device);
! HPAddHotPluggable(i, j+1);
! strncpy(bundleTracker[i].deviceNumber[j].bus_device,
! bus_device, BUS_DEVICE_STRSIZE);
! bundleTracker[i].deviceNumber[j].bus_device[BUS_DEVICE_STRSIZE - 1] = '\0';
! bundleTracker[i].deviceNumber[j].plugged = 1;
! }
!
! SYS_MutexUnLock(&usbNotifierMutex);
! }
! else
! if (usbDeviceStatus == 0)
{
!
! for (j=0; j < PCSCLITE_HP_MAX_SIMUL_READERS; j++)
! {
! #ifdef MSC_TARGET_BSD
! /* BSD workaround:
! * ugenopen() in sys/dev/usb/ugen.c returns EBUSY
! * when the character device file is already open.
! * Because of this, open usb devices will not be
! * detected by usb_find_devices(), so we have to
! * check for this explicitly.
! */
! if (bundleTracker[i].deviceNumber[j].plugged)
! {
! sscanf(bundleTracker[i].deviceNumber[j].bus_device,
! "%*[^:]%*[:]%s", filename);
! fd = open(filename, O_RDONLY);
! if (fd == -1)
! {
! if (errno == EBUSY)
! {
! /* The device is present */
#ifdef DEBUG_USB_HOTPLUG
! DebugLogB("BSD: EBUSY on %s", filename);
#endif
! bundleTracker[i].deviceNumber[j].status = 1;
! }
#ifdef DEBUG_USB_HOTPLUG
! else
! DebugLogC("BSD: %s error: %s", filename,
! strerror(errno));
#endif
! }
! else
! {
#ifdef DEBUG_USB_HOTPLUG
! DebugLogB("BSD: OK %s", filename);
#endif
! bundleTracker[i].deviceNumber[j].status = 1;
! close(fd);
! }
! }
#endif
! if (bundleTracker[i].deviceNumber[j].plugged &&
! bundleTracker[i].deviceNumber[j].status == 0)
! {
! DebugLogB("Removing USB device %s", bus_device);
! SYS_MutexLock(&usbNotifierMutex);
! HPRemoveHotPluggable(i, j+1);
! bundleTracker[i].deviceNumber[j].plugged = 0;
! bundleTracker[i].deviceNumber[j].bus_device[0] = '\0';
! SYS_MutexUnLock(&usbNotifierMutex);
! }
! }
! }
! else
! {
! /*
! * Do nothing - no USB devices found
! */
! }
!
! } /* End of for..loop */
SYS_Sleep(1);
--- 240,303 ----
}
! /* New reader found */
! if (newreader)
! HPAddHotPluggable(dev, bus_device, &driverTracker[i]);
}
+ }
+ } /* End of USB device for..loop */
! } /* End of USB bus for..loop */
! /*
! * check if all the previously found readers are still present
! */
! for (i=0; i<PCSCLITE_MAX_READERS; i++)
! {
! #ifdef MSC_TARGET_BSD
! int fd;
! char filename[BUS_DEVICE_STRSIZE];
+ /* BSD workaround:
+ * ugenopen() in sys/dev/usb/ugen.c returns EBUSY
+ * when the character device file is already open.
+ * Because of this, open usb devices will not be
+ * detected by usb_find_devices(), so we have to
+ * check for this explicitly.
+ */
+ if (readerTracker[i].status == READER_PRESENT ||
+ readerTracker[i].driver == NULL)
+ continue;
! sscanf(readerTracker[i].bus_device, "%*[^:]%*[:]%s", filename);
! fd = open(filename, O_RDONLY);
! if (fd == -1)
{
! if (errno == EBUSY)
{
! /* The device is present */
#ifdef DEBUG_USB_HOTPLUG
! DebugLogB("BSD: EBUSY on %s", filename);
#endif
! readerTracker[i].status = READER_PRESENT;
! }
#ifdef DEBUG_USB_HOTPLUG
! else
! DebugLogC("BSD: %s error: %s", filename,
! strerror(errno));
#endif
! }
! else
! {
#ifdef DEBUG_USB_HOTPLUG
! DebugLogB("BSD: %s still present", filename);
#endif
! readerTracker[i].status = READER_PRESENT;
! close(fd);
! }
#endif
! if (readerTracker[i].status == READER_ABSENT &&
! readerTracker[i].driver != NULL)
! HPRemoveHotPluggable(i);
! }
SYS_Sleep(1);
***************
*** 334,352 ****
}
! LONG HPSearchHotPluggables()
{
! int i, j;
! for (i = 0; i < PCSCLITE_HP_MAX_DRIVERS; i++)
{
! bundleTracker[i].productID = 0;
! bundleTracker[i].manuID = 0;
! for (j=0; j < PCSCLITE_HP_MAX_SIMUL_READERS; j++)
! {
! bundleTracker[i].deviceNumber[j].plugged = 0;
! bundleTracker[i].deviceNumber[j].status = 0;
! bundleTracker[i].deviceNumber[j].bus_device[0] = '\0';
! }
}
--- 306,327 ----
}
! LONG HPSearchHotPluggables(void)
{
! int i;
! for (i=0; i < PCSCLITE_MAX_DRIVERS; i++)
{
! driverTracker[i].productID = 0;
! driverTracker[i].manuID = 0;
! driverTracker[i].bundleName = NULL;
! driverTracker[i].libraryPath = NULL;
! driverTracker[i].readerName = NULL;
! }
! for (i=0; i<PCSCLITE_MAX_READERS; i++)
! {
! readerTracker[i].driver = NULL;
! readerTracker[i].status = READER_ABSENT;
! readerTracker[i].bus_device[0] = '\0';
}
***************
*** 359,373 ****
}
! LONG HPAddHotPluggable(int i, unsigned long usbAddr)
{
! RFAddReader(bundleTracker[i].readerName, 0x200000 + usbAddr,
! bundleTracker[i].libraryPath);
return 1;
} /* End of function */
! LONG HPRemoveHotPluggable(int i, unsigned long usbAddr)
{
! RFRemoveReader(bundleTracker[i].readerName, 0x200000 + usbAddr);
return 1;
--- 334,387 ----
}
! LONG HPAddHotPluggable(struct usb_device *dev, const char bus_device[],
! struct _driverTracker *driver)
{
! int i;
!
! SYS_MutexLock(&usbNotifierMutex);
!
! DebugLogB("Adding USB device: %s", bus_device);
!
! /* find a free entry */
! for (i=0; i<PCSCLITE_MAX_READERS; i++)
! {
! if (readerTracker[i].driver == NULL)
! break;
! }
!
! if (i==PCSCLITE_MAX_READERS)
! {
! DebugLogB("Not enough reader entries. Already found %d readers", i);
! return 0;
! }
!
! if (RFAddReader(driver->readerName, PCSCLITE_HP_BASE_PORT + i,
! driver->libraryPath) == SCARD_S_SUCCESS)
! {
! strncpy(readerTracker[i].bus_device, bus_device, BUS_DEVICE_STRSIZE);
! readerTracker[i].bus_device[BUS_DEVICE_STRSIZE - 1] = '\0';
!
! readerTracker[i].status = READER_PRESENT;
! readerTracker[i].driver = driver;
! }
!
! SYS_MutexUnLock(&usbNotifierMutex);
return 1;
} /* End of function */
! LONG HPRemoveHotPluggable(int index)
{
! SYS_MutexLock(&usbNotifierMutex);
!
! DebugLogC("Removing USB device[%d]: %s", index, readerTracker[index].bus_device);
!
! RFRemoveReader(readerTracker[index].driver->readerName,
! PCSCLITE_HP_BASE_PORT + index);
! readerTracker[index].status = READER_ABSENT;
! readerTracker[index].bus_device[0] = '\0';
! readerTracker[index].driver = NULL;
!
! SYS_MutexUnLock(&usbNotifierMutex);
return 1;