/* Look for a descriptor in the active configuration * Will also find extra descriptors which are normally * not returned by the standard libusb_get_descriptor() */ int usb_get_any_descriptor(struct libusb_device_handle *dev_handle, uint8_t desc_type, uint8_t desc_index, unsigned char *resbuf, int res_len) { struct libusb_device *dev; struct libusb_config_descriptor *config; int ret; uint16_t conflen; unsigned char *cbuf; dev = libusb_get_device(dev_handle); if (!dev) { fprintf(stderr, "Error: Broken device handle\n"); return -1; } /* Get the total length of the configuration descriptors */ ret = libusb_get_active_config_descriptor(dev, &config); if (ret == LIBUSB_ERROR_NOT_FOUND) { fprintf(stderr, "Error: Device is unconfigured\n"); return -1; } else if (ret) { fprintf(stderr, "Error: failed " "libusb_get_active_config_descriptor()\n"); exit(1); } conflen = config->wTotalLength; libusb_free_config_descriptor(config); /* Suck in the configuration descriptor list from device */ cbuf = malloc(conflen); ret = libusb_get_descriptor(dev_handle, LIBUSB_DT_CONFIG, desc_index, cbuf, conflen); if (ret < conflen) { fprintf(stderr, "Warning: failed to retrieve complete " "configuration descriptor, got %i/%i\n", ret, conflen); conflen = ret; } /* Search through the configuration descriptor list */ ret = find_descriptor(cbuf, conflen, desc_type, desc_index, resbuf, res_len); free(cbuf); /* A descriptor must be at least 2 bytes long */ if (ret > 1) { if (verbose) printf("Found descriptor in complete configuration " "descriptor list\n"); return ret; } /* Finally try to retrieve it requesting the device directly * This is not supported on all devices for non-standard types */ return libusb_get_descriptor(dev_handle, desc_type, desc_index, resbuf, res_len); }
API_EXPORTED int usb_get_descriptor(usb_dev_handle *dev, unsigned char type, unsigned char desc_index, void *buf, int size) { int r; r = libusb_get_descriptor(dev->handle, type, desc_index, buf, size); if (r >= 0) return r; return compat_err(r); }
/* Look for a descriptor in the active configuration * Will also find extra descriptors which are normally * not returned by the standard libusb_get_descriptor() */ static int usb_get_any_descriptor(struct libusb_device_handle *dev_handle, uint8_t desc_type, uint8_t desc_index, unsigned char *resbuf, int res_len) { struct libusb_device *dev; struct libusb_config_descriptor *config; int ret; uint16_t conflen; unsigned char *cbuf; dev = libusb_get_device(dev_handle); if (!dev) { return -1; } /* Get the total length of the configuration descriptors */ ret = libusb_get_active_config_descriptor(dev, &config); if (ret) return -1; conflen = config->wTotalLength; libusb_free_config_descriptor(config); /* Suck in the configuration descriptor list from device */ cbuf = (unsigned char *)malloc(conflen); ret = libusb_get_descriptor(dev_handle, LIBUSB_DT_CONFIG, desc_index, cbuf, conflen); if (ret < conflen) { conflen = ret; } /* Search through the configuration descriptor list */ ret = find_descriptor(cbuf, conflen, desc_type, desc_index, resbuf, res_len); free(cbuf); /* A descriptor must be at least 2 bytes long */ if (ret > 1) { return ret; } /* Finally try to retrieve it requesting the device directly * This is not supported on all devices for non-standard types */ return libusb_get_descriptor(dev_handle, desc_type, desc_index, resbuf, res_len); }
/** \ingroup desc * Get a Binary Object Store (BOS) descriptor * This is a BLOCKING function, which will send requests to the device. * * \param handle the handle of an open libusb device * \param bos output location for the BOS descriptor. Only valid if 0 was returned. * Must be freed with \ref libusb_free_bos_descriptor() after use. * \returns 0 on success * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor * \returns another LIBUSB_ERROR code on error */ int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *handle, struct libusb_bos_descriptor **bos) { struct libusb_bos_descriptor _bos; uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0}; unsigned char *bos_data = NULL; const int host_endian = 0; int r; /* Read the BOS. This generates 2 requests on the bus, * one for the header, and one for the full BOS */ r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_header, LIBUSB_DT_BOS_SIZE); if (r < 0) { if (r != LIBUSB_ERROR_PIPE) usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r); return r; } if (r < LIBUSB_DT_BOS_SIZE) { usbi_err(handle->dev->ctx, "short BOS read %d/%d", r, LIBUSB_DT_BOS_SIZE); return LIBUSB_ERROR_IO; } usbi_parse_descriptor(bos_header, "bbwb", &_bos, host_endian); usbi_dbg("found BOS descriptor: size %d bytes, %d capabilities", _bos.wTotalLength, _bos.bNumDeviceCaps); bos_data = calloc(_bos.wTotalLength, 1); if (bos_data == NULL) return LIBUSB_ERROR_NO_MEM; r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_data, _bos.wTotalLength); if (r >= 0) r = parse_bos(handle->dev->ctx, bos, bos_data, r, host_endian); else usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r); free(bos_data); return r; }
static int mainPhase(){ int response = 0; static int transferred; int i; struct libusb_config_descriptor* config_desc; const struct libusb_interface_descriptor* interface_desc; response = libusb_get_descriptor(handle, LIBUSB_DT_CONFIG, 0, buffer, LIBUSB_DT_CONFIG_SIZE); //response = libusb_get_descriptor(handle, LIBUSB_DT_INTERFACE, 0, buffer, LIBUSB_DT_INTERFACE_SIZE); if(response < 0){error(response);return -1;} config_desc = (struct libusb_config_descriptor*)buffer; printf("bLength %i\n", config_desc->bLength); printf("bNumInterfaces %i\n", config_desc->bNumInterfaces); printf("MaxPower %i\n", config_desc->MaxPower); /* Send our host name to device */ memset(buffer, 0x0, sizeof(buffer)); gethostname((char*)buffer, sizeof(buffer)); response = libusb_bulk_transfer(handle, OUT, buffer, sizeof(buffer), &transferred, 5000); if(response < 0){ error(response); return -1; } else{ printf("Done, transferred %i bytes\n", transferred); status(response); } /* Receive back device response */ memset(buffer, 0x0, sizeof(buffer)); response = libusb_bulk_transfer(handle, IN, buffer, sizeof(buffer), &transferred, 5000); if(response < 0){ error(response); return -1; } else{ printf("Done, received %i bytes\n", transferred); status(response); } printf("Received: %s\n", buffer); for(i=0; i<sizeof(buffer); i++) printf("%i ", buffer[i]); printf("\n"); return 0; }
bool CH341DeviceInit(void) { int ret; unsigned char desc[0x12]; if (CH341DeviceHanlde) return true; if ((ret = libusb_init(NULL))) { fprintf(stderr, "Error: libusb_init failed: %d (%s)\n", ret, libusb_error_name(ret)); return false; } if (!(CH341DeviceHanlde = libusb_open_device_with_vid_pid(NULL, CH341_USB_VID, CH341_USB_PID))) { fprintf(stderr, "Error: CH341 device (%04x/%04x) not found\n", CH341_USB_VID, CH341_USB_PID); return false; } #if !defined(_MSC_VER) && !defined(MSYS) && !defined(CYGWIN) && !defined(WIN32) && !defined(MINGW) && !defined(MINGW32) if (libusb_kernel_driver_active(CH341DeviceHanlde, 0)) { if ((ret = libusb_detach_kernel_driver(CH341DeviceHanlde, 0))) { fprintf(stderr, "Error: libusb_detach_kernel_driver failed: %d (%s)\n", ret, libusb_error_name(ret)); goto cleanup; } } #endif if ((ret = libusb_claim_interface(CH341DeviceHanlde, 0))) { fprintf(stderr, "Error: libusb_claim_interface failed: %d (%s)\n", ret, libusb_error_name(ret)); goto cleanup; } if (!(ret = libusb_get_descriptor(CH341DeviceHanlde, LIBUSB_DT_DEVICE, 0x00, desc, 0x12))) { fprintf(stderr, "Warning: libusb_get_descriptor failed: %d (%s)\n", ret, libusb_error_name(ret)); } printf("CH341 %d.%02d found.\n\n", desc[12], desc[13]); return true; cleanup: libusb_close(CH341DeviceHanlde); CH341DeviceHanlde = NULL; return false; }
int musb_get_device(MUSB_INTERFACE *usb_interface) { #ifdef HAVE_LIBUSB struct usb_device_descriptor d; usb_get_descriptor(usb_interface->dev, USB_DT_DEVICE, 0, &d, sizeof(d)); return d.bcdDevice; #elif HAVE_LIBUSB10 struct libusb_device_descriptor d; libusb_get_descriptor(usb_interface->dev, LIBUSB_DT_DEVICE, 0, (unsigned char *)&d, sizeof(d)); return d.bcdDevice; #else return 0; #endif }
static void probe_configuration(libusb_device *dev, struct libusb_device_descriptor *desc) { struct usb_dfu_func_descriptor func_dfu; libusb_device_handle *devh; struct dfu_if *pdfu; struct libusb_config_descriptor *cfg; const struct libusb_interface_descriptor *intf; const struct libusb_interface *uif; char alt_name[MAX_DESC_STR_LEN + 1]; char serial_name[MAX_DESC_STR_LEN + 1]; int cfg_idx; int intf_idx; int alt_idx; int ret; int has_dfu; for (cfg_idx = 0; cfg_idx != desc->bNumConfigurations; cfg_idx++) { memset(&func_dfu, 0, sizeof(func_dfu)); has_dfu = 0; ret = libusb_get_config_descriptor(dev, cfg_idx, &cfg); if (ret != 0) return; if (match_config_index > -1 && match_config_index != cfg->bConfigurationValue) { libusb_free_config_descriptor(cfg); continue; } /* * In some cases, noticably FreeBSD if uid != 0, * the configuration descriptors are empty */ if (!cfg) return; ret = find_descriptor(cfg->extra, cfg->extra_length, USB_DT_DFU, &func_dfu, sizeof(func_dfu)); if (ret > -1) goto found_dfu; for (intf_idx = 0; intf_idx < cfg->bNumInterfaces; intf_idx++) { uif = &cfg->interface[intf_idx]; if (!uif) break; for (alt_idx = 0; alt_idx < cfg->interface[intf_idx].num_altsetting; alt_idx++) { intf = &uif->altsetting[alt_idx]; if (intf->bInterfaceClass != 0xfe || intf->bInterfaceSubClass != 1) continue; ret = find_descriptor(intf->extra, intf->extra_length, USB_DT_DFU, &func_dfu, sizeof(func_dfu)); if (ret > -1) goto found_dfu; has_dfu = 1; } } if (has_dfu) { /* * Finally try to retrieve it requesting the * device directly This is not supported on * all devices for non-standard types */ if (libusb_open(dev, &devh) == 0) { ret = libusb_get_descriptor(devh, USB_DT_DFU, 0, (void *)&func_dfu, sizeof(func_dfu)); libusb_close(devh); if (ret > -1) goto found_dfu; } warnx("Device has DFU interface, " "but has no DFU functional descriptor"); /* fake version 1.0 */ func_dfu.bLength = 7; func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); goto found_dfu; } libusb_free_config_descriptor(cfg); continue; found_dfu: if (func_dfu.bLength == 7) { printf("Deducing device DFU version from functional descriptor " "length\n"); func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); } else if (func_dfu.bLength < 9) { printf("Error obtaining DFU functional descriptor\n"); printf("Please report this as a bug!\n"); printf("Warning: Assuming DFU version 1.0\n"); func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); printf("Warning: Transfer size can not be detected\n"); func_dfu.wTransferSize = 0; } for (intf_idx = 0; intf_idx < cfg->bNumInterfaces; intf_idx++) { if (match_iface_index > -1 && match_iface_index != intf_idx) continue; uif = &cfg->interface[intf_idx]; if (!uif) break; for (alt_idx = 0; alt_idx < uif->num_altsetting; alt_idx++) { int dfu_mode; intf = &uif->altsetting[alt_idx]; if (intf->bInterfaceClass != 0xfe || intf->bInterfaceSubClass != 1) continue; dfu_mode = (intf->bInterfaceProtocol == 2); /* e.g. DSO Nano has bInterfaceProtocol 0 instead of 2 */ if (func_dfu.bcdDFUVersion == 0x011a && intf->bInterfaceProtocol == 0) dfu_mode = 1; /* LPC DFU bootloader has bInterfaceProtocol 1 (Runtime) instead of 2 */ if (desc->idVendor == 0x1fc9 && desc->idProduct == 0x000c && intf->bInterfaceProtocol == 1) dfu_mode = 1; if (dfu_mode && match_iface_alt_index > -1 && match_iface_alt_index != alt_idx) continue; if (dfu_mode) { if ((match_vendor_dfu >= 0 && match_vendor_dfu != desc->idVendor) || (match_product_dfu >= 0 && match_product_dfu != desc->idProduct)) { continue; } } else { if ((match_vendor >= 0 && match_vendor != desc->idVendor) || (match_product >= 0 && match_product != desc->idProduct)) { continue; } } if (libusb_open(dev, &devh)) { warnx("Cannot open DFU device %04x:%04x", desc->idVendor, desc->idProduct); break; } if (intf->iInterface != 0) ret = libusb_get_string_descriptor_ascii(devh, intf->iInterface, (void *)alt_name, MAX_DESC_STR_LEN); else ret = -1; if (ret < 1) strcpy(alt_name, "UNKNOWN"); if (desc->iSerialNumber != 0) ret = libusb_get_string_descriptor_ascii(devh, desc->iSerialNumber, (void *)serial_name, MAX_DESC_STR_LEN); else ret = -1; if (ret < 1) strcpy(serial_name, "UNKNOWN"); libusb_close(devh); if (dfu_mode && match_iface_alt_name != NULL && strcmp(alt_name, match_iface_alt_name)) continue; if (dfu_mode) { if (match_serial_dfu != NULL && strcmp(match_serial_dfu, serial_name)) continue; } else { if (match_serial != NULL && strcmp(match_serial, serial_name)) continue; } pdfu = dfu_malloc(sizeof(*pdfu)); memset(pdfu, 0, sizeof(*pdfu)); pdfu->func_dfu = func_dfu; pdfu->dev = libusb_ref_device(dev); pdfu->quirks = get_quirks(desc->idVendor, desc->idProduct, desc->bcdDevice); pdfu->vendor = desc->idVendor; pdfu->product = desc->idProduct; pdfu->bcdDevice = desc->bcdDevice; pdfu->configuration = cfg->bConfigurationValue; pdfu->interface = intf->bInterfaceNumber; pdfu->altsetting = intf->bAlternateSetting; pdfu->devnum = libusb_get_device_address(dev); pdfu->busnum = libusb_get_bus_number(dev); pdfu->alt_name = strdup(alt_name); if (pdfu->alt_name == NULL) errx(EX_SOFTWARE, "Out of memory"); pdfu->serial_name = strdup(serial_name); if (pdfu->serial_name == NULL) errx(EX_SOFTWARE, "Out of memory"); if (dfu_mode) pdfu->flags |= DFU_IFF_DFU; if (pdfu->quirks & QUIRK_FORCE_DFU11) { pdfu->func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0110); } pdfu->bMaxPacketSize0 = desc->bMaxPacketSize0; /* queue into list */ pdfu->next = dfu_root; dfu_root = pdfu; } } libusb_free_config_descriptor(cfg); } }
int cyusb_get_descriptor(cyusb_handle *h, unsigned char desc_type, unsigned char desc_index, unsigned char *data, int len) { return ( libusb_get_descriptor(h, desc_type, desc_index, data, len) ); }
/* Configure CH341A, find the device and set the default interface. */ int32_t ch341Configure(uint16_t vid, uint16_t pid) { struct libusb_device *dev; int32_t ret; struct sigaction sa; uint8_t desc[0x12]; if (devHandle != NULL) { fprintf(stderr, "Call ch341Release before re-configure\n"); return -1; } ret = libusb_init(NULL); if(ret < 0) { fprintf(stderr, "Couldn't initialise libusb\n"); return -1; } libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO); if(!(devHandle = libusb_open_device_with_vid_pid(NULL, vid, pid))) { fprintf(stderr, "Couldn't open device [%04x:%04x].\n", vid, pid); return -1; } if(!(dev = libusb_get_device(devHandle))) { fprintf(stderr, "Couldn't get bus number and address.\n"); goto close_handle; } if(libusb_kernel_driver_active(devHandle, 0)) { ret = libusb_detach_kernel_driver(devHandle, 0); if(ret) { fprintf(stderr, "Failed to detach kernel driver: '%s'\n", strerror(-ret)); goto close_handle; } } ret = libusb_claim_interface(devHandle, 0); if(ret) { fprintf(stderr, "Failed to claim interface 0: '%s'\n", strerror(-ret)); goto close_handle; } ret = libusb_get_descriptor(devHandle, LIBUSB_DT_DEVICE, 0x00, desc, 0x12); if(ret < 0) { fprintf(stderr, "Failed to get device descriptor: '%s'\n", strerror(-ret)); goto release_interface; } printf("Device reported its revision [%d.%02d]\n", desc[12], desc[13]); sa.sa_handler = &sig_int; sa.sa_flags = SA_RESTART; sigfillset(&sa.sa_mask); if (sigaction(SIGINT, &sa, &saold) == -1) { perror("Error: cannot handle SIGINT"); // Should not happen } return 0; release_interface: libusb_release_interface(devHandle, 0); close_handle: libusb_close(devHandle); devHandle = NULL; return -1; }
// Tests based on USB descriptors. // This primarily tests the "Get Descriptor" request. static void descriptor_tests(void) { uint8_t buffer[1024]; char string_buffer[1024]; unsigned int i; int r; // Check that device descriptor is exactly 18 bytes long. r = libusb_get_descriptor(device_handle, LIBUSB_DT_DEVICE, 0, buffer, sizeof(buffer)); if (r != 18) { printf("Could not get valid device descriptor\n"); tests_failed++; } else { tests_succeeded++; } // Check that a truncated device descriptor can be obtained. r = libusb_get_descriptor(device_handle, LIBUSB_DT_DEVICE, 0, buffer, 7); if (r != 7) { printf("Could not get truncated (length = 7) device descriptor\n"); tests_failed++; } else { tests_succeeded++; } // index != 0 is invalid for device descriptors. r = libusb_get_descriptor(device_handle, LIBUSB_DT_DEVICE, 0xff, buffer, sizeof(buffer)); if (r >= 0) { printf("Get device descriptor succeeds for index != 0\n"); tests_failed++; } else { tests_succeeded++; } // Get first configuration descriptor. r = libusb_get_descriptor(device_handle, LIBUSB_DT_CONFIG, 0, buffer, sizeof(buffer)); if (r < 0) { printf("Could not get first configuration descriptor\n"); tests_failed++; } else { tests_succeeded++; } // Get all string descriptors. for (i = 0; i <= 0xff; i++) { r = libusb_get_string_descriptor_ascii(device_handle, i, string_buffer, sizeof(string_buffer)); if (r >= 0) { printf("String descriptor %u: \"%s\"\n", i, string_buffer); } } // Attempt to get interface and endpoint descriptors. This should fail // (those descriptors as supposed to be included only as part of the // configuration descriptor). r = libusb_get_descriptor(device_handle, LIBUSB_DT_INTERFACE, 0, buffer, sizeof(buffer)); if (r >= 0) { printf("Was able to get interface descriptor directly\n"); tests_failed++; } else { tests_succeeded++; } r = libusb_get_descriptor(device_handle, LIBUSB_DT_ENDPOINT, 0, buffer, sizeof(buffer)); if (r >= 0) { printf("Was able to get endpoint descriptor directly\n"); tests_failed++; } else { tests_succeeded++; } }
void poke(libusb_device_handle *dev) { unsigned char buffer[256]; (void)libusb_get_descriptor(dev, 0, 0, buffer, sizeof buffer); }
API_EXPORTED int usb_get_descriptor(usb_dev_handle *dev, unsigned char type, unsigned char desc_index, void *buf, int size) { return libusb_get_descriptor(dev->handle, type, desc_index, buf, size); }