?? descriptor.c
字號:
for (i = 0; i < config->bNumInterfaces; i++) { int len; unsigned char *begin; /* Skip over the rest of the Class Specific or Vendor */ /* Specific descriptors */ begin = buffer; while (size >= DESC_HEADER_LENGTH) { usbi_parse_descriptor(buffer, "bb", &header, 0); if ((header.bLength > size) || (header.bLength < DESC_HEADER_LENGTH)) { usbi_err(ctx, "invalid descriptor length of %d", header.bLength); r = LIBUSB_ERROR_IO; goto err; } /* If we find another "proper" descriptor then we're done */ if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) || (header.bDescriptorType == LIBUSB_DT_INTERFACE) || (header.bDescriptorType == LIBUSB_DT_CONFIG) || (header.bDescriptorType == LIBUSB_DT_DEVICE)) break; usbi_dbg("skipping descriptor 0x%x\n", header.bDescriptorType); buffer += header.bLength; size -= header.bLength; } /* Copy any unknown descriptors into a storage area for */ /* drivers to later parse */ len = (int)(buffer - begin); if (len) { /* FIXME: We should realloc and append here */ if (!config->extra_length) { config->extra = malloc(len); if (!config->extra) { r = LIBUSB_ERROR_NO_MEM; goto err; } memcpy((unsigned char *) config->extra, begin, len); config->extra_length = len; } } r = parse_interface(ctx, interface + i, buffer, size, host_endian); if (r < 0) goto err; buffer += r; size -= r; } return size;err: clear_configuration(config); return r;}/** \ingroup desc * Get the USB device descriptor for a given device. * * This is a non-blocking function; the device descriptor is cached in memory. * * \param dev the device * \param desc output location for the descriptor data * \returns 0 on success or a LIBUSB_ERROR code on failure */API_EXPORTED int libusb_get_device_descriptor(libusb_device *dev, struct libusb_device_descriptor *desc){ unsigned char raw_desc[DEVICE_DESC_LENGTH]; int host_endian = 0; int r; usbi_dbg(""); r = usbi_backend->get_device_descriptor(dev, raw_desc, &host_endian); if (r < 0) return r; memcpy((unsigned char *) desc, raw_desc, sizeof(raw_desc)); if (host_endian) { desc->bcdUSB = libusb_cpu_to_le16(desc->bcdUSB); desc->idVendor = libusb_cpu_to_le16(desc->idVendor); desc->idProduct = libusb_cpu_to_le16(desc->idProduct); desc->bcdDevice = libusb_cpu_to_le16(desc->bcdDevice); } return 0;}/** \ingroup desc * Get the USB configuration descriptor for the currently active configuration. * This is a non-blocking function which does not involve any requests being * sent to the device. * * \param dev a device * \param config output location for the USB configuration descriptor. Only * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() * after use. * \returns 0 on success * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state * \returns another LIBUSB_ERROR code on error * \see libusb_get_config_descriptor */API_EXPORTED int libusb_get_active_config_descriptor(libusb_device *dev, struct libusb_config_descriptor **config){ struct libusb_config_descriptor *_config = malloc(sizeof(*_config)); unsigned char tmp[8]; unsigned char *buf = NULL; int host_endian = 0; int r; usbi_dbg(""); if (!_config) return LIBUSB_ERROR_NO_MEM; r = usbi_backend->get_active_config_descriptor(dev, tmp, sizeof(tmp), &host_endian); if (r < 0) goto err; usbi_parse_descriptor(tmp, "bbw", _config, host_endian); buf = malloc(_config->wTotalLength); if (!buf) { r = LIBUSB_ERROR_NO_MEM; goto err; } r = usbi_backend->get_active_config_descriptor(dev, buf, _config->wTotalLength, &host_endian); if (r < 0) goto err; r = parse_configuration(dev->ctx, _config, buf, host_endian); if (r < 0) { usbi_err(dev->ctx, "parse_configuration failed with error %d", r); goto err; } else if (r > 0) { usbi_warn(dev->ctx, "descriptor data still left"); } *config = _config; return 0;err: free(_config); if (buf) free(buf); return r;}/** \ingroup desc * Get a USB configuration descriptor based on its index. * This is a non-blocking function which does not involve any requests being * sent to the device. * * \param dev a device * \param config_index the index of the configuration you wish to retrieve * \param config output location for the USB configuration descriptor. Only * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() * after use. * \returns 0 on success * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist * \returns another LIBUSB_ERROR code on error * \see libusb_get_active_config_descriptor() * \see libusb_get_config_descriptor_by_value() */API_EXPORTED int libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, struct libusb_config_descriptor **config){ struct libusb_config_descriptor *_config; unsigned char tmp[8]; unsigned char *buf = NULL; int host_endian = 0; int r; usbi_dbg("index %d", config_index); if (config_index >= dev->num_configurations) return LIBUSB_ERROR_NOT_FOUND; _config = malloc(sizeof(*_config)); if (!_config) return LIBUSB_ERROR_NO_MEM; r = usbi_backend->get_config_descriptor(dev, config_index, tmp, sizeof(tmp), &host_endian); if (r < 0) goto err; usbi_parse_descriptor(tmp, "bbw", _config, host_endian); buf = malloc(_config->wTotalLength); if (!buf) { r = LIBUSB_ERROR_NO_MEM; goto err; } r = usbi_backend->get_config_descriptor(dev, config_index, buf, _config->wTotalLength, &host_endian); if (r < 0) goto err; r = parse_configuration(dev->ctx, _config, buf, host_endian); if (r < 0) { usbi_err(dev->ctx, "parse_configuration failed with error %d", r); goto err; } else if (r > 0) { usbi_warn(dev->ctx, "descriptor data still left"); } *config = _config; return 0;err: free(_config); if (buf) free(buf); return r;}/* iterate through all configurations, returning the index of the configuration * matching a specific bConfigurationValue in the idx output parameter, or -1 * if the config was not found. * returns 0 or a LIBUSB_ERROR code */int usbi_get_config_index_by_value(struct libusb_device *dev, uint8_t bConfigurationValue, int *idx){ int i; usbi_dbg("value %d", bConfigurationValue); for (i = 0; i < dev->num_configurations; i++) { unsigned char tmp[6]; int host_endian; int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp), &host_endian); if (r < 0) return r; if (tmp[5] == bConfigurationValue) { *idx = i; return 0; } } *idx = -1; return 0;}/** \ingroup desc * Get a USB configuration descriptor with a specific bConfigurationValue. * This is a non-blocking function which does not involve any requests being * sent to the device. * * \param dev a device * \param bConfigurationValue the bConfigurationValue of the configuration you * wish to retrieve * \param config output location for the USB configuration descriptor. Only * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() * after use. * \returns 0 on success * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist * \returns another LIBUSB_ERROR code on error * \see libusb_get_active_config_descriptor() * \see libusb_get_config_descriptor() */API_EXPORTED int libusb_get_config_descriptor_by_value(libusb_device *dev, uint8_t bConfigurationValue, struct libusb_config_descriptor **config){ int idx; int r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx); if (r < 0) return r; else if (idx == -1) return LIBUSB_ERROR_NOT_FOUND; else return libusb_get_config_descriptor(dev, idx, config);}/** \ingroup desc * Free a configuration descriptor obtained from * libusb_get_active_config_descriptor() or libusb_get_config_descriptor(). * It is safe to call this function with a NULL config parameter, in which * case the function simply returns. * * \param config the configuration descriptor to free */API_EXPORTED void libusb_free_config_descriptor( struct libusb_config_descriptor *config){ if (!config) return; clear_configuration(config); free(config);}/** \ingroup desc * Retrieve a string descriptor in C style ASCII. * * Wrapper around libusb_get_string_descriptor(). Uses the first language * supported by the device. * * \param dev a device handle * \param desc_index the index of the descriptor to retrieve * \param data output buffer for ASCII string descriptor * \param length size of data buffer * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure */API_EXPORTED int libusb_get_string_descriptor_ascii(libusb_device_handle *dev, uint8_t desc_index, unsigned char *data, int length){ unsigned char tbuf[255]; /* Some devices choke on size > 255 */ int r, langid, si, di; /* Asking for the zero'th index is special - it returns a string * descriptor that contains all the language IDs supported by the device. * Typically there aren't many - often only one. The language IDs are 16 * bit numbers, and they start at the third byte in the descriptor. See * USB 2.0 specification section 9.6.7 for more information. */ r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf)); if (r < 0) return r; if (r < 4) return LIBUSB_ERROR_IO; langid = tbuf[2] | (tbuf[3] << 8); r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf, sizeof(tbuf)); if (r < 0) return r; if (tbuf[1] != LIBUSB_DT_STRING) return LIBUSB_ERROR_IO; if (tbuf[0] > r) return LIBUSB_ERROR_IO; for (di = 0, si = 2; si < tbuf[0]; si += 2) { if (di >= (length - 1)) break; if (tbuf[si + 1]) /* high byte */ data[di++] = '?'; else data[di++] = tbuf[si]; } data[di] = 0; return di;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -