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; }
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); } }