Пример #1
0
static int usb_open(struct aura_node *node, const char *opts)
{
	int ret; 
	struct usb_dev_info *inf = calloc(1, sizeof(*inf));

	if (!inf)
		return -ENOMEM;

	ret = libusb_init(&inf->ctx);
	if (ret != 0) 
		return -EIO;

	inf->io_buf_size = 256;
	inf->optbuf = strdup(opts);
	inf->dev_descr.device_found_func = usb_start_ops;
	inf->dev_descr.arg = inf;
	inf->node = node;
	parse_params(inf);
	
	ncusb_start_descriptor_watching(node, inf->ctx);
	aura_set_transportdata(node, inf);	

	slog(4, SLOG_INFO, "usb: vid 0x%x pid 0x%x vendor %s product %s serial %s", 
	     inf->dev_descr.vid, inf->dev_descr.pid, inf->dev_descr.vendor, 
	     inf->dev_descr.product, inf->dev_descr.serial);

	inf->ctrlbuf   = malloc(inf->io_buf_size);
	if (!inf->ctrlbuf)
		goto err_free_inf;
	inf->itransfer = libusb_alloc_transfer(0);
	if (!inf->itransfer)
		goto err_free_cbuf;

 	inf->ctransfer = libusb_alloc_transfer(0);
	if (!inf->ctransfer)
		goto err_free_int;
	
	slog(1, SLOG_INFO, "usb: Now looking for a matching device");

	ncusb_watch_for_device(inf->ctx, &inf->dev_descr);

	return 0;
	
err_free_int:
	libusb_free_transfer(inf->itransfer);
err_free_cbuf:
	free(inf->ctrlbuf);
err_free_inf:
	libusb_exit(inf->ctx);
	free(inf);
	return -ENOMEM;
}
Пример #2
0
static void usb_loop(struct aura_node *node, const struct aura_pollfds *fd)
{
	struct aura_buffer *buf;
	struct usb_dev_info *inf = aura_get_transportdata(node);
	struct timeval tv = { 
		.tv_sec  = 0,
		.tv_usec = 0
	};

	libusb_handle_events_timeout(inf->ctx, &tv);

	if (inf->cbusy)
		return; 

	if (inf->state == AUSB_DEVICE_RESTART) { 
		slog(4, SLOG_DEBUG, "usb: transport offlined, starting to look for a device");
		aura_set_status(node, AURA_STATUS_OFFLINE);
		libusb_close(inf->handle);
		inf->handle = NULL;
		inf->state = AUSB_DEVICE_SEARCHING;
		ncusb_watch_for_device(inf->ctx, &inf->dev_descr);
		return;
	}

	if (inf->state == AUSB_DEVICE_OPERATIONAL) {
		if (inf->pending) 
			submit_event_readout(node);
		else if ( (buf = aura_dequeue_buffer(&node->outbound_buffers)) ) { 
			submit_call_write(node, buf);
		}
	}
}

static struct aura_transport usb = { 
	.name = "usb",
	.open = usb_open,
	.close = usb_close,
	.loop  = usb_loop,
	.buffer_overhead = LIBUSB_CONTROL_SETUP_SIZE, /* Offset for usb SETUP structure */  
	.buffer_offset = LIBUSB_CONTROL_SETUP_SIZE
};

AURA_TRANSPORT(usb);
Пример #3
0
static void susb_handle_event(struct aura_node *node, enum node_event evt, const struct aura_pollfds *fd)
{
	struct aura_buffer *buf;
	struct usb_dev_info *inf = aura_get_transportdata(node);

	ncusb_handle_events_nonblock_once(node, inf->ctx, inf->timer);

	if (inf->cbusy)
		return;

	if (evt == NODE_EVENT_STARTED) {
		aura_etable_activate(inf->etbl);
		/* Activate our export table
		 * Hack: Since libusb tends to send and receive data in one buffer,
		 * we need to adjust argument buffer to fit in return values as well.
		 * It helps us to avoid needless copying.
		 */
		int i;
		for (i = 0; i < inf->etbl->next; i++) {
			struct aura_object *tmp;
			tmp = &inf->etbl->objects[i];
			tmp->arglen += tmp->retlen;
		}
		inf->etbl = NULL;
		ncusb_watch_for_device(inf->ctx, &inf->dev_descr);
		ncusb_start_descriptor_watching(node, inf->ctx);
		slog(1, SLOG_INFO, "usb: Now looking for a device %x:%x %s/%s/%s",
		     inf->dev_descr.vid, inf->dev_descr.pid,
		     inf->dev_descr.vendor, inf->dev_descr.product, inf->dev_descr.serial);
	} else if (inf->state == SUSB_DEVICE_RESTART) {
		susb_offline_transport(inf);
	} else if (inf->state == SUSB_DEVICE_OPERATIONAL) {
		buf = aura_peek_buffer(&node->outbound_buffers);
		if (buf)
			susb_issue_call(node, buf);
	}
}