예제 #1
0
파일: usbwait.c 프로젝트: cfriedt/ben-wpan
static void wait_for_usb(void)
{
	struct timeval to, now;
	usb_dev_handle *dev;

	gettimeofday(&to, NULL);
	to.tv_sec += timeout;

	while (1) {
		usb_rescan();
		dev = open_usb(0, 0);
		if (dev) {
			if (!need_removal)
				return;
			usb_close(dev);
		} else {
			need_removal = 0;
		}
		if (timeout) {
			gettimeofday(&now, NULL);
			if (now.tv_sec > to.tv_sec)
				break;
			if (now.tv_sec == to.tv_sec &&
			    now.tv_usec > to.tv_usec)
				break;
		}
		if (usleep(interval_us) < 0) {
			perror("usleep");
			exit(1);
		}
	}

	fprintf(stderr, "timeout\n");
	exit(1);
}
예제 #2
0
static void handle_sigusr1(void) {
#ifdef BRICKD_WITH_USB_REOPEN_ON_SIGUSR1
	usb_reopen();
#else
	usb_rescan();
#endif
}
예제 #3
0
static void forward_notifications(void *opaque) {
	uint8_t byte;

	(void)opaque;

	if (pipe_read(&_notification_pipe, &byte, sizeof(byte)) < 0) {
		log_error("Could not read from notification pipe: %s (%d)",
		          get_errno_name(errno), errno);

		return;
	}

	usb_rescan();
}
예제 #4
0
파일: udev.c 프로젝트: vszurma/brickd
static void udev_handle_event(void *opaque) {
	struct udev_device* device;
	const char *action;
	const char *dev_node;
	const char *sys_name;

	(void)opaque;

	device = udev_monitor_receive_device(_udev_monitor);

	if (device == NULL) {
		log_error("Could not read data from udev monitor socket");

		return;
	}

	action = udev_device_get_action(device);

	if (action == NULL) {
		goto cleanup;
	}

	dev_node = udev_device_get_devnode(device);

	if (dev_node == NULL) {
		goto cleanup;
	}

	sys_name = udev_device_get_sysname(device);

	if (sys_name == NULL) {
		goto cleanup;
	}

	if (strncmp(action, "add", 3) == 0 || strncmp(action, "remove", 6) == 0) {
		log_debug("Received udev event (action: %s, dev node: %s, sys name: %s)",
		          action, dev_node, sys_name);

		usb_rescan();
	} else {
		log_debug("Ignoring udev event (action: %s, dev node: %s, sys name: %s)",
		          action, dev_node, sys_name);
	}

cleanup:
	udev_device_unref(device);
}
예제 #5
0
int usb_reopen(void) {
	int i;
	USBStack *usb_stack;

	log_debug("Reopening all USB devices");

	// iterate backwards for simpler index handling and to avoid memmove in
	// array_remove call
	for (i = _usb_stacks.count - 1; i >= 0; --i) {
		usb_stack = array_get(&_usb_stacks, i);

		log_info("Temporarily removing USB device (bus: %u, device: %u) at index %d: %s",
		         usb_stack->bus_number, usb_stack->device_address, i,
		         usb_stack->base.name);

		stack_announce_disconnect(&usb_stack->base);

		array_remove(&_usb_stacks, i, (ItemDestroyFunction)usb_stack_destroy);
	}

	return usb_rescan();
}
예제 #6
0
int usb_init(void) {
	int phase = 0;

	log_debug("Initializing USB subsystem");

	_libusb_log_source.file = "libusb";
	_libusb_log_source.name = "libusb";

#if defined(_WIN32) || defined(__APPLE__)
	libusb_set_log_function(usb_forward_message);
#endif

	switch (log_get_effective_level()) {
	case LOG_LEVEL_ERROR:
		putenv("LIBUSB_DEBUG=1");
		break;

	case LOG_LEVEL_WARN:
		putenv("LIBUSB_DEBUG=2");
		break;

	case LOG_LEVEL_INFO:
		putenv("LIBUSB_DEBUG=3");
		break;

	case LOG_LEVEL_DEBUG:
		if (log_is_included(LOG_LEVEL_DEBUG, &_libusb_log_source,
		                    LOG_DEBUG_GROUP_LIBUSB)) {
			putenv("LIBUSB_DEBUG=4");
		} else {
			putenv("LIBUSB_DEBUG=3");
		}

		break;

	default:
		break;
	}

	if (usb_init_platform() < 0) {
		goto cleanup;
	}

	phase = 1;

	// initialize main libusb context
	if (usb_create_context(&_context)) {
		goto cleanup;
	}

	phase = 2;

	if (!libusb_pollfds_handle_timeouts(_context)) {
		log_debug("libusb requires special timeout handling"); // FIXME
	} else {
		log_debug("libusb can handle timeouts on its own");
	}

	// create USB stack array. the USBStack struct is not relocatable, because
	// its USB transfers keep a pointer to it
	if (array_create(&_usb_stacks, 32, sizeof(USBStack), false) < 0) {
		log_error("Could not create USB stack array: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 3;

	if (usb_has_hotplug()) {
		log_debug("libusb supports hotplug");

		if (usb_init_hotplug(_context) < 0) {
			goto cleanup;
		}

		_initialized_hotplug = true;
	} else {
		log_debug("libusb does not support hotplug");
	}

	if (usb_rescan() < 0) {
		goto cleanup;
	}

	phase = 4;

cleanup:
	switch (phase) { // no breaks, all cases fall through intentionally
	case 3:
		array_destroy(&_usb_stacks, (ItemDestroyFunction)usb_stack_destroy);

	case 2:
		usb_destroy_context(_context);

	case 1:
		usb_exit_platform();

	default:
		break;
	}

	return phase == 4 ? 0 : -1;
}