int usb_close(usb_dev_handle * udev) { struct usb_device *dev; int err; err = libusb20_dev_close((void *)udev); if (err) return (-1); if (usb_backend != NULL) { /* * Enqueue USB device to backend queue so that it gets freed * when the backend is re-scanned: */ libusb20_be_enqueue_device(usb_backend, (void *)udev); } else { /* * The backend is gone. Free device data so that we * don't start leaking memory! */ dev = usb_device(udev); libusb20_dev_free((void *)udev); LIST_DEL(usb_global_bus.devices, dev); free(dev); } return (0); }
int usb_find_devices(void) { struct libusb20_device *pdev; struct usb_device *udev; struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; int devnum; int err; /* cleanup after last device search */ /* close all opened devices, if any */ while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) { udev = pdev->privLuData; libusb20_be_dequeue_device(usb_backend, pdev); libusb20_dev_free(pdev); if (udev != NULL) { LIST_DEL(usb_global_bus.devices, udev); free(udev); } } /* free old USB backend, if any */ libusb20_be_free(usb_backend); /* do a new backend device search */ usb_backend = libusb20_be_alloc_default(); if (usb_backend == NULL) { return (-1); } /* iterate all devices */ devnum = 1; pdev = NULL; while ((pdev = libusb20_be_device_foreach(usb_backend, pdev))) { udev = malloc(sizeof(*udev)); if (udev == NULL) break; memset(udev, 0, sizeof(*udev)); udev->bus = &usb_global_bus; snprintf(udev->filename, sizeof(udev->filename), "/dev/ugen%u.%u", libusb20_dev_get_bus_number(pdev), libusb20_dev_get_address(pdev)); ddesc = libusb20_dev_get_device_desc(pdev); udev->descriptor.bLength = sizeof(udev->descriptor); udev->descriptor.bDescriptorType = ddesc->bDescriptorType; udev->descriptor.bcdUSB = ddesc->bcdUSB; udev->descriptor.bDeviceClass = ddesc->bDeviceClass; udev->descriptor.bDeviceSubClass = ddesc->bDeviceSubClass; udev->descriptor.bDeviceProtocol = ddesc->bDeviceProtocol; udev->descriptor.bMaxPacketSize0 = ddesc->bMaxPacketSize0; udev->descriptor.idVendor = ddesc->idVendor; udev->descriptor.idProduct = ddesc->idProduct; udev->descriptor.bcdDevice = ddesc->bcdDevice; udev->descriptor.iManufacturer = ddesc->iManufacturer; udev->descriptor.iProduct = ddesc->iProduct; udev->descriptor.iSerialNumber = ddesc->iSerialNumber; udev->descriptor.bNumConfigurations = ddesc->bNumConfigurations; if (udev->descriptor.bNumConfigurations > USB_MAXCONFIG) { /* truncate number of configurations */ udev->descriptor.bNumConfigurations = USB_MAXCONFIG; } udev->devnum = devnum++; /* link together the two structures */ udev->dev = pdev; pdev->privLuData = udev; err = libusb20_dev_open(pdev, 0); if (err == 0) { /* XXX get all config descriptors by default */ usb_fetch_and_parse_descriptors((void *)pdev); libusb20_dev_close(pdev); } LIST_ADD(usb_global_bus.devices, udev); } return (devnum - 1); /* success */ }
static void doit(struct libusb20_device *dev) { int rv; if (do_request) printf("doit(): bmRequestType 0x%02x, bRequest 0x%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\n", setup.bmRequestType, setup.bRequest, setup.wValue, setup.wIndex, setup.wLength); /* * Open the device, allocating memory for two possible (bulk or * interrupt) transfers. * * If only control transfers are intended (via * libusb20_dev_request_sync()), transfer_max can be given as 0. */ if ((rv = libusb20_dev_open(dev, 1)) != 0) { fprintf(stderr, "libusb20_dev_open: %s\n", libusb20_strerror(rv)); return; } /* * If the device has more than one configuration, select the desired * one here. */ if ((rv = libusb20_dev_set_config_index(dev, 0)) != 0) { fprintf(stderr, "libusb20_dev_set_config_index: %s\n", libusb20_strerror(rv)); return; } uint8_t *data = 0; uint16_t actlen; if ((setup.bmRequestType & 0x80) != 0) { /* this is an IN request, allocate a buffer */ data = malloc(setup.wLength); if (data == 0) { fprintf(stderr, "Out of memory allocating %u bytes of reply buffer\n", setup.wLength); return; } } else data = out_buf; if (do_request) { if ((rv = libusb20_dev_request_sync(dev, &setup, data, &actlen, TIMEOUT, 0 /* flags */)) != 0) { fprintf(stderr, "libusb20_dev_request_sync: %s\n", libusb20_strerror(rv)); } printf("sent %d bytes\n", actlen); if ((setup.bmRequestType & 0x80) != 0) { print_formatted(data, (uint32_t)setup.wLength); free(data); } } if (intr_ep != 0) { /* * One transfer has been requested in libusb20_dev_open() above; * obtain the corresponding transfer struct pointer. */ struct libusb20_transfer *xfr_intr = libusb20_tr_get_pointer(dev, 0); if (xfr_intr == NULL) { fprintf(stderr, "libusb20_tr_get_pointer: %s\n", libusb20_strerror(rv)); return; } /* * Open the interrupt transfer. */ if ((rv = libusb20_tr_open(xfr_intr, 0, 1, intr_ep)) != 0) { fprintf(stderr, "libusb20_tr_open: %s\n", libusb20_strerror(rv)); return; } uint8_t in_buf[BUFLEN]; uint32_t rlen; if ((rv = libusb20_tr_bulk_intr_sync(xfr_intr, in_buf, BUFLEN, &rlen, TIMEOUT)) != 0) { fprintf(stderr, "libusb20_tr_bulk_intr_sync: %s\n", libusb20_strerror(rv)); } printf("received %d bytes\n", rlen); if (rlen > 0) print_formatted(in_buf, rlen); libusb20_tr_close(xfr_intr); } libusb20_dev_close(dev); }
static void doit(struct libusb20_device *dev) { int rv; /* * Open the device, allocating memory for two possible (bulk or * interrupt) transfers. * * If only control transfers are intended (via * libusb20_dev_request_sync()), transfer_max can be given as 0. */ if ((rv = libusb20_dev_open(dev, 2)) != 0) { fprintf(stderr, "libusb20_dev_open: %s\n", libusb20_strerror(rv)); return; } /* * If the device has more than one configuration, select the desired * one here. */ if ((rv = libusb20_dev_set_config_index(dev, 0)) != 0) { fprintf(stderr, "libusb20_dev_set_config_index: %s\n", libusb20_strerror(rv)); return; } /* * Two transfers have been requested in libusb20_dev_open() above; * obtain the corresponding transfer struct pointers. */ struct libusb20_transfer *xfr_out = libusb20_tr_get_pointer(dev, 0); struct libusb20_transfer *xfr_in = libusb20_tr_get_pointer(dev, 1); if (xfr_in == NULL || xfr_out == NULL) { fprintf(stderr, "libusb20_tr_get_pointer: %s\n", libusb20_strerror(rv)); return; } /* * Open both transfers, the "out" one for the write endpoint, the * "in" one for the read endpoint (ep | 0x80). */ if ((rv = libusb20_tr_open(xfr_out, 0, 1, out_ep)) != 0) { fprintf(stderr, "libusb20_tr_open: %s\n", libusb20_strerror(rv)); return; } if ((rv = libusb20_tr_open(xfr_in, 0, 1, in_ep)) != 0) { fprintf(stderr, "libusb20_tr_open: %s\n", libusb20_strerror(rv)); return; } uint8_t in_buf[BUFLEN]; uint32_t rlen; if (out_len > 0) { if ((rv = libusb20_tr_bulk_intr_sync(xfr_out, out_buf, out_len, &rlen, TIMEOUT)) != 0) { fprintf(stderr, "libusb20_tr_bulk_intr_sync (OUT): %s\n", libusb20_strerror(rv)); } printf("sent %d bytes\n", rlen); } if ((rv = libusb20_tr_bulk_intr_sync(xfr_in, in_buf, BUFLEN, &rlen, TIMEOUT)) != 0) { fprintf(stderr, "libusb20_tr_bulk_intr_sync: %s\n", libusb20_strerror(rv)); } printf("received %d bytes\n", rlen); if (rlen > 0) print_formatted(in_buf, rlen); libusb20_tr_close(xfr_out); libusb20_tr_close(xfr_in); libusb20_dev_close(dev); }
void usb_control_ep_error_test(uint16_t vid, uint16_t pid) { struct LIBUSB20_CONTROL_SETUP_DECODED req; struct libusb20_device *pdev; uint8_t buffer[256]; int error; int fail = 0; int bus; int dev; int cfg; pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } error = libusb20_dev_open(pdev, 0); if (error) { printf("Could not open USB device\n"); libusb20_dev_free(pdev); return; } bus = libusb20_dev_get_bus_number(pdev); dev = libusb20_dev_get_address(pdev); for (cfg = 0; cfg != 255; cfg++) { LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req); req.bmRequestType = 0x80; /* read */ req.bRequest = 0x06; /* descriptor */ req.wValue = 0x0200 | cfg; /* config descriptor */ req.wIndex = 0; req.wLength = 255; printf("Test #%d.1/3 ...\n", cfg); set_ctrl_ep_fail(-1,-1,0,0); error = libusb20_dev_request_sync(pdev, &req, buffer, NULL, 1000, 0); if (error != 0) { printf("Last configuration index is: %d\n", cfg - 1); break; } printf("Test #%d.2/3 ...\n", cfg); set_ctrl_ep_fail(bus,dev,1,1); error = libusb20_dev_request_sync(pdev, &req, buffer, NULL, 1000, 0); set_ctrl_ep_fail(-1,-1,0,0); error = libusb20_dev_request_sync(pdev, &req, buffer, NULL, 1000, 0); if (error != 0) { printf("Cannot fetch descriptor (unexpected)\n"); fail++; } printf("Test #%d.3/3 ...\n", cfg); set_ctrl_ep_fail(bus,dev,0,1); error = libusb20_dev_request_sync(pdev, &req, buffer, NULL, 1000, 0); set_ctrl_ep_fail(-1,-1,0,0); error = libusb20_dev_request_sync(pdev, &req, buffer, NULL, 1000, 0); if (error != 0) { printf("Cannot fetch descriptor (unexpected)\n"); fail++; } } libusb20_dev_close(pdev); libusb20_dev_free(pdev); printf("Test completed detecting %d failures\nDone\n\n", fail); }
void usb_set_alt_interface_test(uint16_t vid, uint16_t pid) { struct libusb20_device *pdev; struct libusb20_config *config; int iter; int error; int errcnt; int n; int m; pdev = find_usb_device(vid, pid); if (pdev == NULL) { printf("USB device not found\n"); return; } printf("Starting set alternate setting test " "for VID=0x%04x PID=0x%04x\n", vid, pid); config = libusb20_dev_alloc_config(pdev, libusb20_dev_get_config_index(pdev)); if (config == NULL) { printf("Could not get configuration descriptor\n"); libusb20_dev_free(pdev); return; } iter = 0; errcnt = 0; for (n = 0; n != config->num_interface; n++) { /* detach kernel driver */ libusb20_dev_detach_kernel_driver(pdev, n); error = libusb20_dev_open(pdev, 0); if (error) printf("ERROR could not open device\n"); /* Try the alternate settings */ for (m = 0; m != config->interface[n].num_altsetting; m++) { iter++; if (libusb20_dev_set_alt_index(pdev, n, m + 1)) { printf("ERROR on interface %d alt %d\n", n, m + 1); errcnt++; } } /* Restore to default */ iter++; if (libusb20_dev_set_alt_index(pdev, n, 0)) { printf("ERROR on interface %d alt %d\n", n, 0); errcnt++; } libusb20_dev_close(pdev); } libusb20_dev_free(pdev); printf("\n" "Test summary\n" "============\n" "Interfaces tested: %d\n" "Errors: %d\n", iter, errcnt); }