#include #include static libusb_context *usb = NULL; static struct libusb_device_handle *device = NULL; static uint8_t endpoint_d2h = 0, endpoint_h2d = 0; static uint16_t payload_d2h = 0, payload_h2d = 0; #define LIBUSB_CHECK(action) \ do { \ int ret = (action); \ if (ret != LIBUSB_SUCCESS) \ { \ fprintf(stderr, "%s\n", libusb_strerror(ret)); \ return -1; \ } \ } while(0) int usb_device_open(uint16_t vid, uint16_t pid) { LIBUSB_CHECK(libusb_init(&usb)); //libusb_set_debug(usb, LIBUSB_LOG_LEVEL_WARNING); libusb_device **device_list = NULL; ssize_t device_num = libusb_get_device_list(usb, &device_list); if (device_num <= 0) { fprintf(stderr, "No device found on the bus.\n"); return -1; } for (ssize_t i = 0; i < device_num; i++) { struct libusb_device_descriptor desc; LIBUSB_CHECK(libusb_get_device_descriptor(device_list[i], &desc)); printf("%d: %04X:%04X\n", i + 1, desc.idVendor, desc.idProduct); struct libusb_config_descriptor *conf_desc; LIBUSB_CHECK(libusb_get_active_config_descriptor(device_list[i], &conf_desc)); for (unsigned int j = 0; j < conf_desc->bNumInterfaces; j++) { const struct libusb_interface *interface = &conf_desc->interface[j]; if (interface->num_altsetting >= 1) { const struct libusb_interface_descriptor *if_desc = &interface->altsetting[0]; if (if_desc->bInterfaceClass == LIBUSB_CLASS_MASS_STORAGE && if_desc->bInterfaceSubClass == 0x06 && if_desc->bInterfaceProtocol == 0x50) { printf("\tInterface #%d: Mass storage, SCSI transparent command set, Bulk-only transport\n", j); for (unsigned int k = 0; k < if_desc->bNumEndpoints; k++) { const struct libusb_endpoint_descriptor *ep_desc = &if_desc->endpoint[k]; if ((ep_desc->bmAttributes & 0x03) == LIBUSB_TRANSFER_TYPE_BULK) { if (ep_desc->bEndpointAddress & 0x80) { printf("\tEndpoint 0x%02X: Bulk D2H (Payload = %u bytes)\n", ep_desc->bEndpointAddress, ep_desc->wMaxPacketSize); endpoint_d2h = ep_desc->bEndpointAddress; payload_d2h = ep_desc->wMaxPacketSize; } else { printf("\tEndpoint 0x%02X: Bulk H2D (Payload = %u bytes)\n", ep_desc->bEndpointAddress, ep_desc->wMaxPacketSize); endpoint_h2d = ep_desc->bEndpointAddress; payload_h2d = ep_desc->wMaxPacketSize; } } } if (endpoint_d2h == 0 || endpoint_h2d == 0) { fprintf(stderr, "Interface is not complete.\n"); return -1; } LIBUSB_CHECK(libusb_open(device_list[i], &device)); libusb_set_auto_detach_kernel_driver(device, 1); LIBUSB_CHECK(libusb_claim_interface(device, 0)); libusb_free_device_list(device_list, 1); return 0; } } else { printf("no conf.\n"); } } libusb_free_config_descriptor(conf_desc); } libusb_free_device_list(device_list, 1); fprintf(stderr, "No target device found.\n"); return -1; } void usb_device_close(void) { if (device != NULL) libusb_close(device); if (usb != NULL) libusb_exit(usb); } ssize_t usb_bulk_read(void *data, size_t length) { int transferred; LIBUSB_CHECK(libusb_bulk_transfer(device, endpoint_d2h, (unsigned char *)data, length, &transferred, 0)); return transferred; } ssize_t usb_bulk_write(const void *data, size_t length) { int transferred; LIBUSB_CHECK(libusb_bulk_transfer(device, endpoint_h2d, (unsigned char *)data, length, &transferred, 0)); return transferred; }