Beispiel #1
0
static void cb_parse_object(struct libusb_transfer *transfer)
{
	struct aura_node *node = transfer->user_data;
	struct usb_dev_info *inf = aura_get_transportdata(node);
	char is_method;
	char *name, *afmt, *rfmt;

	check_control(transfer);
	name = (char *) libusb_control_transfer_get_data(transfer);

	is_method = *name++;
	afmt = next(name);
	rfmt = next(afmt);

	slog(4, SLOG_DEBUG, "usb: got %s %s / '%s' '%s'", 
	     is_method ? "method" : "event",
	     name, afmt, rfmt);

	aura_etable_add(inf->etbl, name, 
			is_method ? afmt : NULL, 
			rfmt);

	if (inf->current_object == inf->num_objects) { 
		slog(4, SLOG_DEBUG, "etable becomes active");
		aura_etable_activate(inf->etbl);
		aura_set_status(node, AURA_STATUS_ONLINE);
		inf->state = AUSB_DEVICE_OPERATIONAL;
		itransfer_enable(node, true);
		return;
	}

	slog(4, SLOG_DEBUG, "Requesting info about obj %d", inf->current_object);
	/* Resubmit the transfer for the next round */
	request_object(node, inf->current_object++);
}
Beispiel #2
0
static void susb_offline_transport(struct usb_dev_info *inf)
{
	aura_set_status(inf->node, AURA_STATUS_OFFLINE);
	libusb_close(inf->handle);
	inf->handle = NULL;
	inf->state = SUSB_DEVICE_SEARCHING;
	slog(4, SLOG_DEBUG, "susb: transport offlined");
}
Beispiel #3
0
static void usb_start_ops(struct libusb_device_handle *hndl, void *arg)
{
	/* FixMe: Reading descriptors is synchronos. This is not needed
	 * often, but leaves a possibility of a flaky usb device to
	 * screw up the event processing.
	 * A proper workaround would be manually reading out string descriptors
	 * from a device in an async fasion in the background.
	 */
	struct usb_dev_info *inf = arg;

	inf->handle = hndl;
	inf->state = SUSB_DEVICE_OPERATIONAL;
	aura_set_status(inf->node, AURA_STATUS_ONLINE);
	slog(2, SLOG_INFO, "susb: Device opened and ready to accept calls");
	return;
};
Beispiel #4
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);
Beispiel #5
0
static int gpio_open(struct aura_node *node, const char *opts)
{
	slog(0, SLOG_INFO, "Opening sysfs/gpio transport");
	struct aura_export_table *etbl = aura_etable_create(node, 16);
	if (!etbl)
		BUG(node, "Failed to create etable");
	aura_etable_add(etbl, "write", "33", "");
	aura_etable_add(etbl, "read", "3", "3");
	aura_etable_add(etbl, "out", "3", "");
	aura_etable_add(etbl, "in", "3", "");
	aura_etable_add(etbl, "export", "3", "3");
	aura_etable_add(etbl, "watch", "3", "");
	//Change notification
	aura_etable_add(etbl, "gpio_changed", NULL, "333");
	aura_etable_activate(etbl);
	aura_set_status(node, AURA_STATUS_ONLINE);
	slog(0, SLOG_INFO, "Opened sysfs/gpio transport");
	return 0;
}