Ejemplo n.º 1
0
static void udev_hotplug_event(struct udev_device* udev_dev)
{
	const char* udev_action;
	const char* sys_name = NULL;
	uint8_t busnum = 0, devaddr = 0;
	int detached;
	int r;

	do {
		udev_action = udev_device_get_action(udev_dev);
		if (!udev_action) {
			break;
		}

		detached = !strncmp(udev_action, "remove", 6);

		r = udev_device_info(NULL, detached, udev_dev, &busnum, &devaddr, &sys_name);
		if (LIBUSB_SUCCESS != r) {
			break;
		}

		usbi_dbg("udev hotplug event. action: %s.", udev_action);

		if (strncmp(udev_action, "add", 3) == 0) {
			linux_hotplug_enumerate(busnum, devaddr, sys_name);
		} else if (detached) {
			linux_hotplug_disconnected(busnum, devaddr, sys_name);
		} else {
			usbi_err(NULL, "ignoring udev action %s", udev_action);
		}
	} while (0);

	udev_device_unref(udev_dev);
}
Ejemplo n.º 2
0
static int linux_netlink_read_message(void)
{
	unsigned char buffer[1024];
	struct iovec iov = {.iov_base = buffer, .iov_len = sizeof(buffer)};
	struct msghdr meh = { .msg_iov=&iov, .msg_iovlen=1,
			     .msg_name=&snl, .msg_namelen=sizeof(snl) };
	const char *sys_name = NULL;
	uint8_t busnum, devaddr;
	int detached, r;
	size_t len;

	/* read netlink message */
	memset(buffer, 0, sizeof(buffer));
	len = recvmsg(linux_netlink_socket, &meh, 0);
	if (len < 32) {
		if (errno != EAGAIN)
			usbi_dbg("error recieving message from netlink");
		return -1;
	}

	/* TODO -- authenticate this message is from the kernel or udevd */

	r = linux_netlink_parse(buffer, len, &detached, &sys_name,
				&busnum, &devaddr);
	if (r)
		return r;

	usbi_dbg("netlink hotplug found device busnum: %hhu, devaddr: %hhu, sys_name: %s, removed: %s",
		 busnum, devaddr, sys_name, detached ? "yes" : "no");

	/* signal device is available (or not) to all contexts */
	if (detached)
		linux_hotplug_disconnected(busnum, devaddr, sys_name);
	else
		linux_hotplug_enumerate(busnum, devaddr, sys_name);

	return 0;
}

static void *linux_netlink_event_thread_main(void *arg)
{
	char dummy;
	int r;
	struct pollfd fds[] = {
		{ .fd = netlink_control_pipe[0],
		  .events = POLLIN },
		{ .fd = linux_netlink_socket,
		  .events = POLLIN },
	};
Ejemplo n.º 3
0
static int linux_netlink_read_message(void)
{
	unsigned char buffer[1024];
	struct iovec iov = {.iov_base = buffer, .iov_len = sizeof(buffer)};
	struct msghdr meh = { .msg_iov=&iov, .msg_iovlen=1,
			     .msg_name=&snl, .msg_namelen=sizeof(snl) };
	const char *sys_name = NULL;
	uint8_t busnum, devaddr;
	int detached, r;
	size_t len;

	/* read netlink message */
	memset(buffer, 0, sizeof(buffer));
	len = recvmsg(linux_netlink_socket, &meh, 0);
	if (len < 32) {
		if (errno != EAGAIN)
			usbi_dbg("error recieving message from netlink");
		return -1;
	}

	/* TODO -- authenticate this message is from the kernel or udevd */

	r = linux_netlink_parse(buffer, len, &detached, &sys_name,
				&busnum, &devaddr);
	if (r)
		return r;

	usbi_dbg("netlink hotplug found device busnum: %hhu, devaddr: %hhu, sys_name: %s, removed: %s",
		 busnum, devaddr, sys_name, detached ? "yes" : "no");

	/* signal device is available (or not) to all contexts */
	if (detached)
		linux_hotplug_disconnected(busnum, devaddr, sys_name);
	else
		linux_hotplug_enumerate(busnum, devaddr, sys_name);

	return 0;
}

static void *linux_netlink_event_thread_main(void *arg)
{
	struct pollfd fds = {.fd = linux_netlink_socket,
			     .events = POLLIN};

	/* silence compiler warning */
	(void) arg;

	while (1 == poll(&fds, 1, -1)) {
		if (POLLIN != fds.revents) {
			break;
		}

		usbi_mutex_static_lock(&linux_hotplug_lock);
		linux_netlink_read_message();
		usbi_mutex_static_unlock(&linux_hotplug_lock);
	}

	return NULL;
}

void linux_netlink_hotplug_poll(void)
{
	int r;

	usbi_mutex_static_lock(&linux_hotplug_lock);
	do {
		r = linux_netlink_read_message();
	} while (r == 0);
	usbi_mutex_static_unlock(&linux_hotplug_lock);
}