static void HPEstablishUSBNotifications(void)
{
	int i, do_polling;

	/* libusb default is /dev/bus/usb but the devices are not yet visible there
	 * when a hotplug is requested */
	setenv("USB_DEVFS_PATH", "/proc/bus/usb", 0);

	usb_init();

	/* scan the USB bus for devices at startup */
	HPRescanUsbBus();

	/* if at least one driver do not have IFD_GENERATE_HOTPLUG */
	do_polling = FALSE;
	for (i=0; i<driverSize; i++)
		if (driverTracker[i].libraryPath)
			if ((driverTracker[i].ifdCapabilities & IFD_GENERATE_HOTPLUG) == 0)
			{
				Log2(PCSC_LOG_INFO,
					"Driver %s does not support IFD_GENERATE_HOTPLUG. Using active polling instead.",
					driverTracker[i].bundleName);
				if (HPForceReaderPolling < 1)
					HPForceReaderPolling = 1;
				break;
			}

	if (HPForceReaderPolling)
	{
		Log2(PCSC_LOG_INFO,
				"Polling forced every %d second(s)", HPForceReaderPolling);
		do_polling = TRUE;
	}

	if (do_polling)
	{
		while (!AraKiriHotPlug)
		{
			SYS_Sleep(HPForceReaderPolling);
			HPRescanUsbBus();
		}
	}
	else
	{
		char dummy;

	  	pipe(rescan_pipe);
		while (read(rescan_pipe[0], &dummy, sizeof(dummy)) > 0)
		{
			Log1(PCSC_LOG_INFO, "Reload serial configuration");
			HPRescanUsbBus();
			RFReCheckReaderConf();
			Log1(PCSC_LOG_INFO, "End reload serial configuration");
		}
		close(rescan_pipe[0]);
		rescan_pipe[0] = -1;
	}
}
Example #2
0
/**
 * Sets up callbacks for device hotplug events.
 */
ULONG HPRegisterForHotplugEvents(void)
{
	struct udev *udev;

	(void)pthread_mutex_init(&usbNotifierMutex, NULL);

	if (driverSize <= 0)
	{
		Log1(PCSC_LOG_INFO, "No bundle files in pcsc drivers directory: "
			PCSCLITE_HP_DROPDIR);
		Log1(PCSC_LOG_INFO, "Disabling USB support for pcscd");
		return 0;
	}

	/* Create the udev object */
	udev = udev_new();
	if (!udev)
	{
		Log1(PCSC_LOG_ERROR, "udev_new() failed");
		return 0;
	}

	HPRescanUsbBus(udev);

	(void)ThreadCreate(&usbNotifyThread, THREAD_ATTR_DETACHED,
		(PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, udev);

	return 0;
} /* HPRegisterForHotplugEvents */
Example #3
0
static void HPEstablishUSBNotifications(struct udev *udev)
{
	struct udev_monitor *udev_monitor;
	int r, i;
	int fd;
	fd_set fds;

	udev_monitor = udev_monitor_new_from_netlink(udev, "udev");

	/* filter only the interfaces */
	r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb",
		"usb_interface");
	if (r)
	{
		Log2(PCSC_LOG_ERROR, "udev_monitor_filter_add_match_subsystem_devtype() error: %d\n", r);
		return;
	}

	r = udev_monitor_enable_receiving(udev_monitor);
	if (r)
	{
		Log2(PCSC_LOG_ERROR, "udev_monitor_enable_receiving() error: %d\n", r);
		return;
	}

	/* udev monitor file descriptor */
	fd = udev_monitor_get_fd(udev_monitor);

	while (!AraKiriHotPlug)
	{
		struct udev_device *dev, *parent;
		const char *action, *devpath;

#ifdef DEBUG_HOTPLUG
		Log0(PCSC_LOG_INFO);
#endif

		FD_ZERO(&fds);
		FD_SET(fd, &fds);

		/* wait for a udev event */
		r = select(fd+1, &fds, NULL, NULL, NULL);
		if (r < 0)
		{
			Log2(PCSC_LOG_ERROR, "select(): %s", strerror(errno));
			return;
		}

		dev = udev_monitor_receive_device(udev_monitor);
		if (!dev)
		{
			Log1(PCSC_LOG_ERROR, "udev_monitor_receive_device() error\n");
			return;
		}

		action = udev_device_get_action(dev);
		if (0 == strcmp("remove", action))
		{
			Log1(PCSC_LOG_INFO, "Device removed");
			HPRescanUsbBus(udev);
			continue;
		}

		if (strcmp("add", action))
			continue;

		parent = udev_device_get_parent_with_subsystem_devtype(dev, "usb",
			"usb_device");
		devpath = udev_device_get_devnode(parent);
		if (!devpath)
		{
			/* the device disapeared? */
			Log1(PCSC_LOG_ERROR, "udev_device_get_devnode() failed");
			continue;
		}

		HPAddDevice(dev, parent, devpath);

		/* free device */
		udev_device_unref(dev);

	}

	for (i=0; i<driverSize; i++)
	{
		/* free strings allocated by strdup() */
		free(driverTracker[i].bundleName);
		free(driverTracker[i].libraryPath);
		free(driverTracker[i].readerName);
	}
	free(driverTracker);

	Log1(PCSC_LOG_INFO, "Hotplug stopped");
} /* HPEstablishUSBNotifications */