Home | History | Annotate | Download | only in libusb
      1 /*
      2  * USB descriptor handling functions for libusb
      3  * Copyright (C) 2007 Daniel Drake <dsd (at) gentoo.org>
      4  * Copyright (c) 2001 Johannes Erdfelt <johannes (at) erdfelt.com>
      5  *
      6  * This library is free software; you can redistribute it and/or
      7  * modify it under the terms of the GNU Lesser General Public
      8  * License as published by the Free Software Foundation; either
      9  * version 2.1 of the License, or (at your option) any later version.
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Lesser General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU Lesser General Public
     17  * License along with this library; if not, write to the Free Software
     18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     19  */
     20 
     21 #include <errno.h>
     22 #include <stdint.h>
     23 #include <stdlib.h>
     24 #include <string.h>
     25 
     26 #include "libusbi.h"
     27 
     28 #define DESC_HEADER_LENGTH		2
     29 #define DEVICE_DESC_LENGTH		18
     30 #define CONFIG_DESC_LENGTH		9
     31 #define INTERFACE_DESC_LENGTH		9
     32 #define ENDPOINT_DESC_LENGTH		7
     33 #define ENDPOINT_AUDIO_DESC_LENGTH	9
     34 
     35 /** @defgroup desc USB descriptors
     36  * This page details how to examine the various standard USB descriptors
     37  * for detected devices
     38  */
     39 
     40 /* set host_endian if the w values are already in host endian format,
     41  * as opposed to bus endian. */
     42 int usbi_parse_descriptor(unsigned char *source, const char *descriptor,
     43 	void *dest, int host_endian)
     44 {
     45 	unsigned char *sp = source, *dp = dest;
     46 	uint16_t w;
     47 	const char *cp;
     48 
     49 	for (cp = descriptor; *cp; cp++) {
     50 		switch (*cp) {
     51 			case 'b':	/* 8-bit byte */
     52 				*dp++ = *sp++;
     53 				break;
     54 			case 'w':	/* 16-bit word, convert from little endian to CPU */
     55 				dp += ((uintptr_t)dp & 1);	/* Align to word boundary */
     56 
     57 				if (host_endian) {
     58 					memcpy(dp, sp, 2);
     59 				} else {
     60 					w = (sp[1] << 8) | sp[0];
     61 					*((uint16_t *)dp) = w;
     62 				}
     63 				sp += 2;
     64 				dp += 2;
     65 				break;
     66 		}
     67 	}
     68 
     69 	return (int) (sp - source);
     70 }
     71 
     72 static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
     73 {
     74 	if (endpoint->extra)
     75 		free((unsigned char *) endpoint->extra);
     76 }
     77 
     78 static int parse_endpoint(struct libusb_context *ctx,
     79 	struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer,
     80 	int size, int host_endian)
     81 {
     82 	struct usb_descriptor_header header;
     83 	unsigned char *extra;
     84 	unsigned char *begin;
     85 	int parsed = 0;
     86 	int len;
     87 
     88 	usbi_parse_descriptor(buffer, "bb", &header, 0);
     89 
     90 	/* Everything should be fine being passed into here, but we sanity */
     91 	/*  check JIC */
     92 	if (header.bLength > size) {
     93 		usbi_err(ctx, "ran out of descriptors parsing");
     94 		return -1;
     95 	}
     96 
     97 	if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) {
     98 		usbi_err(ctx, "unexpected descriptor %x (expected %x)",
     99 			header.bDescriptorType, LIBUSB_DT_ENDPOINT);
    100 		return parsed;
    101 	}
    102 
    103 	if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH)
    104 		usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian);
    105 	else if (header.bLength >= ENDPOINT_DESC_LENGTH)
    106 		usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian);
    107 
    108 	buffer += header.bLength;
    109 	size -= header.bLength;
    110 	parsed += header.bLength;
    111 
    112 	/* Skip over the rest of the Class Specific or Vendor Specific */
    113 	/*  descriptors */
    114 	begin = buffer;
    115 	while (size >= DESC_HEADER_LENGTH) {
    116 		usbi_parse_descriptor(buffer, "bb", &header, 0);
    117 
    118 		if (header.bLength < 2) {
    119 			usbi_err(ctx, "invalid descriptor length %d", header.bLength);
    120 			return -1;
    121 		}
    122 
    123 		/* If we find another "proper" descriptor then we're done  */
    124 		if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
    125 				(header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
    126 				(header.bDescriptorType == LIBUSB_DT_CONFIG) ||
    127 				(header.bDescriptorType == LIBUSB_DT_DEVICE))
    128 			break;
    129 
    130 		usbi_dbg("skipping descriptor %x", header.bDescriptorType);
    131 		buffer += header.bLength;
    132 		size -= header.bLength;
    133 		parsed += header.bLength;
    134 	}
    135 
    136 	/* Copy any unknown descriptors into a storage area for drivers */
    137 	/*  to later parse */
    138 	len = (int)(buffer - begin);
    139 	if (!len) {
    140 		endpoint->extra = NULL;
    141 		endpoint->extra_length = 0;
    142 		return parsed;
    143 	}
    144 
    145 	extra = malloc(len);
    146 	endpoint->extra = extra;
    147 	if (!extra) {
    148 		endpoint->extra_length = 0;
    149 		return LIBUSB_ERROR_NO_MEM;
    150 	}
    151 
    152 	memcpy(extra, begin, len);
    153 	endpoint->extra_length = len;
    154 
    155 	return parsed;
    156 }
    157 
    158 static void clear_interface(struct libusb_interface *usb_interface)
    159 {
    160 	int i;
    161 	int j;
    162 
    163 	if (usb_interface->altsetting) {
    164 		for (i = 0; i < usb_interface->num_altsetting; i++) {
    165 			struct libusb_interface_descriptor *ifp =
    166 				(struct libusb_interface_descriptor *)
    167 				usb_interface->altsetting + i;
    168 			if (ifp->extra)
    169 				free((void *) ifp->extra);
    170 			if (ifp->endpoint) {
    171 				for (j = 0; j < ifp->bNumEndpoints; j++)
    172 					clear_endpoint((struct libusb_endpoint_descriptor *)
    173 						ifp->endpoint + j);
    174 				free((void *) ifp->endpoint);
    175 			}
    176 		}
    177 		free((void *) usb_interface->altsetting);
    178 		usb_interface->altsetting = NULL;
    179 	}
    180 
    181 }
    182 
    183 static int parse_interface(libusb_context *ctx,
    184 	struct libusb_interface *usb_interface, unsigned char *buffer, int size,
    185 	int host_endian)
    186 {
    187 	int i;
    188 	int len;
    189 	int r;
    190 	int parsed = 0;
    191 	size_t tmp;
    192 	struct usb_descriptor_header header;
    193 	struct libusb_interface_descriptor *ifp;
    194 	unsigned char *begin;
    195 
    196 	usb_interface->num_altsetting = 0;
    197 
    198 	while (size >= INTERFACE_DESC_LENGTH) {
    199 		struct libusb_interface_descriptor *altsetting =
    200 			(struct libusb_interface_descriptor *) usb_interface->altsetting;
    201 		altsetting = realloc(altsetting,
    202 			sizeof(struct libusb_interface_descriptor) *
    203 			(usb_interface->num_altsetting + 1));
    204 		if (!altsetting) {
    205 			r = LIBUSB_ERROR_NO_MEM;
    206 			goto err;
    207 		}
    208 		usb_interface->altsetting = altsetting;
    209 
    210 		ifp = altsetting + usb_interface->num_altsetting;
    211 		usb_interface->num_altsetting++;
    212 		usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0);
    213 		ifp->extra = NULL;
    214 		ifp->extra_length = 0;
    215 		ifp->endpoint = NULL;
    216 
    217 		/* Skip over the interface */
    218 		buffer += ifp->bLength;
    219 		parsed += ifp->bLength;
    220 		size -= ifp->bLength;
    221 
    222 		begin = buffer;
    223 
    224 		/* Skip over any interface, class or vendor descriptors */
    225 		while (size >= DESC_HEADER_LENGTH) {
    226 			usbi_parse_descriptor(buffer, "bb", &header, 0);
    227 			if (header.bLength < 2) {
    228 				usbi_err(ctx, "invalid descriptor of length %d",
    229 					header.bLength);
    230 				r = LIBUSB_ERROR_IO;
    231 				goto err;
    232 			}
    233 
    234 			/* If we find another "proper" descriptor then we're done */
    235 			if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
    236 					(header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
    237 					(header.bDescriptorType == LIBUSB_DT_CONFIG) ||
    238 					(header.bDescriptorType == LIBUSB_DT_DEVICE))
    239 				break;
    240 
    241 			buffer += header.bLength;
    242 			parsed += header.bLength;
    243 			size -= header.bLength;
    244 		}
    245 
    246 		/* Copy any unknown descriptors into a storage area for */
    247 		/*  drivers to later parse */
    248 		len = (int)(buffer - begin);
    249 		if (len) {
    250 			ifp->extra = malloc(len);
    251 			if (!ifp->extra) {
    252 				r = LIBUSB_ERROR_NO_MEM;
    253 				goto err;
    254 			}
    255 			memcpy((unsigned char *) ifp->extra, begin, len);
    256 			ifp->extra_length = len;
    257 		}
    258 
    259 		/* Did we hit an unexpected descriptor? */
    260 		if (size >= DESC_HEADER_LENGTH) {
    261 			usbi_parse_descriptor(buffer, "bb", &header, 0);
    262 			if ((header.bDescriptorType == LIBUSB_DT_CONFIG) ||
    263 			    (header.bDescriptorType == LIBUSB_DT_DEVICE)) {
    264 				return parsed;
    265 			}
    266 		}
    267 
    268 		if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
    269 			usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoints);
    270 			r = LIBUSB_ERROR_IO;
    271 			goto err;
    272 		}
    273 
    274 		if (ifp->bNumEndpoints > 0) {
    275 			struct libusb_endpoint_descriptor *endpoint;
    276 			tmp = ifp->bNumEndpoints * sizeof(struct libusb_endpoint_descriptor);
    277 			endpoint = malloc(tmp);
    278 			ifp->endpoint = endpoint;
    279 			if (!endpoint) {
    280 				r = LIBUSB_ERROR_NO_MEM;
    281 				goto err;
    282 			}
    283 
    284 			memset(endpoint, 0, tmp);
    285 			for (i = 0; i < ifp->bNumEndpoints; i++) {
    286 				usbi_parse_descriptor(buffer, "bb", &header, 0);
    287 
    288 				if (header.bLength > size) {
    289 					usbi_err(ctx, "ran out of descriptors parsing");
    290 					r = LIBUSB_ERROR_IO;
    291 					goto err;
    292 				}
    293 
    294 				r = parse_endpoint(ctx, endpoint + i, buffer, size,
    295 					host_endian);
    296 				if (r < 0)
    297 					goto err;
    298 
    299 				buffer += r;
    300 				parsed += r;
    301 				size -= r;
    302 			}
    303 		}
    304 
    305 		/* We check to see if it's an alternate to this one */
    306 		ifp = (struct libusb_interface_descriptor *) buffer;
    307 		if (size < LIBUSB_DT_INTERFACE_SIZE ||
    308 				ifp->bDescriptorType != LIBUSB_DT_INTERFACE ||
    309 				!ifp->bAlternateSetting)
    310 			return parsed;
    311 	}
    312 
    313 	return parsed;
    314 err:
    315 	clear_interface(usb_interface);
    316 	return r;
    317 }
    318 
    319 static void clear_configuration(struct libusb_config_descriptor *config)
    320 {
    321 	if (config->interface) {
    322 		int i;
    323 		for (i = 0; i < config->bNumInterfaces; i++)
    324 			clear_interface((struct libusb_interface *)
    325 				config->interface + i);
    326 		free((void *) config->interface);
    327 	}
    328 	if (config->extra)
    329 		free((void *) config->extra);
    330 }
    331 
    332 static int parse_configuration(struct libusb_context *ctx,
    333 	struct libusb_config_descriptor *config, unsigned char *buffer,
    334 	int host_endian)
    335 {
    336 	int i;
    337 	int r;
    338 	int size;
    339 	size_t tmp;
    340 	struct usb_descriptor_header header;
    341 	struct libusb_interface *usb_interface;
    342 
    343 	usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian);
    344 	size = config->wTotalLength;
    345 
    346 	if (config->bNumInterfaces > USB_MAXINTERFACES) {
    347 		usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces);
    348 		return LIBUSB_ERROR_IO;
    349 	}
    350 
    351 	tmp = config->bNumInterfaces * sizeof(struct libusb_interface);
    352 	usb_interface = malloc(tmp);
    353 	config->interface = usb_interface;
    354 	if (!config->interface)
    355 		return LIBUSB_ERROR_NO_MEM;
    356 
    357 	memset(usb_interface, 0, tmp);
    358 	buffer += config->bLength;
    359 	size -= config->bLength;
    360 
    361 	config->extra = NULL;
    362 	config->extra_length = 0;
    363 
    364 	for (i = 0; i < config->bNumInterfaces; i++) {
    365 		int len;
    366 		unsigned char *begin;
    367 
    368 		/* Skip over the rest of the Class Specific or Vendor */
    369 		/*  Specific descriptors */
    370 		begin = buffer;
    371 		while (size >= DESC_HEADER_LENGTH) {
    372 			usbi_parse_descriptor(buffer, "bb", &header, 0);
    373 
    374 			if ((header.bLength > size) ||
    375 					(header.bLength < DESC_HEADER_LENGTH)) {
    376 				usbi_err(ctx, "invalid descriptor length of %d",
    377 					header.bLength);
    378 				r = LIBUSB_ERROR_IO;
    379 				goto err;
    380 			}
    381 
    382 			/* If we find another "proper" descriptor then we're done */
    383 			if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
    384 					(header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
    385 					(header.bDescriptorType == LIBUSB_DT_CONFIG) ||
    386 					(header.bDescriptorType == LIBUSB_DT_DEVICE))
    387 				break;
    388 
    389 			usbi_dbg("skipping descriptor 0x%x\n", header.bDescriptorType);
    390 			buffer += header.bLength;
    391 			size -= header.bLength;
    392 		}
    393 
    394 		/* Copy any unknown descriptors into a storage area for */
    395 		/*  drivers to later parse */
    396 		len = (int)(buffer - begin);
    397 		if (len) {
    398 			/* FIXME: We should realloc and append here */
    399 			if (!config->extra_length) {
    400 				config->extra = malloc(len);
    401 				if (!config->extra) {
    402 					r = LIBUSB_ERROR_NO_MEM;
    403 					goto err;
    404 				}
    405 
    406 				memcpy((unsigned char *) config->extra, begin, len);
    407 				config->extra_length = len;
    408 			}
    409 		}
    410 
    411 		r = parse_interface(ctx, usb_interface + i, buffer, size, host_endian);
    412 		if (r < 0)
    413 			goto err;
    414 
    415 		buffer += r;
    416 		size -= r;
    417 	}
    418 
    419 	return size;
    420 
    421 err:
    422 	clear_configuration(config);
    423 	return r;
    424 }
    425 
    426 /** \ingroup desc
    427  * Get the USB device descriptor for a given device.
    428  *
    429  * This is a non-blocking function; the device descriptor is cached in memory.
    430  *
    431  * \param dev the device
    432  * \param desc output location for the descriptor data
    433  * \returns 0 on success or a LIBUSB_ERROR code on failure
    434  */
    435 int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
    436 	struct libusb_device_descriptor *desc)
    437 {
    438 	unsigned char raw_desc[DEVICE_DESC_LENGTH];
    439 	int host_endian = 0;
    440 	int r;
    441 
    442 	usbi_dbg("");
    443 	r = usbi_backend->get_device_descriptor(dev, raw_desc, &host_endian);
    444 	if (r < 0)
    445 		return r;
    446 
    447 	memcpy((unsigned char *) desc, raw_desc, sizeof(raw_desc));
    448 	if (!host_endian) {
    449 		desc->bcdUSB = libusb_le16_to_cpu(desc->bcdUSB);
    450 		desc->idVendor = libusb_le16_to_cpu(desc->idVendor);
    451 		desc->idProduct = libusb_le16_to_cpu(desc->idProduct);
    452 		desc->bcdDevice = libusb_le16_to_cpu(desc->bcdDevice);
    453 	}
    454 	return 0;
    455 }
    456 
    457 /** \ingroup desc
    458  * Get the USB configuration descriptor for the currently active configuration.
    459  * This is a non-blocking function which does not involve any requests being
    460  * sent to the device.
    461  *
    462  * \param dev a device
    463  * \param config output location for the USB configuration descriptor. Only
    464  * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
    465  * after use.
    466  * \returns 0 on success
    467  * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
    468  * \returns another LIBUSB_ERROR code on error
    469  * \see libusb_get_config_descriptor
    470  */
    471 int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
    472 	struct libusb_config_descriptor **config)
    473 {
    474 	struct libusb_config_descriptor *_config = malloc(sizeof(*_config));
    475 	unsigned char tmp[8];
    476 	unsigned char *buf = NULL;
    477 	int host_endian = 0;
    478 	int r;
    479 
    480 	usbi_dbg("");
    481 	if (!_config)
    482 		return LIBUSB_ERROR_NO_MEM;
    483 
    484 	r = usbi_backend->get_active_config_descriptor(dev, tmp, sizeof(tmp),
    485 		&host_endian);
    486 	if (r < 0)
    487 		goto err;
    488 
    489 	usbi_parse_descriptor(tmp, "bbw", _config, host_endian);
    490 	buf = malloc(_config->wTotalLength);
    491 	if (!buf) {
    492 		r = LIBUSB_ERROR_NO_MEM;
    493 		goto err;
    494 	}
    495 
    496 	r = usbi_backend->get_active_config_descriptor(dev, buf,
    497 		_config->wTotalLength, &host_endian);
    498 	if (r < 0)
    499 		goto err;
    500 
    501 	r = parse_configuration(dev->ctx, _config, buf, host_endian);
    502 	if (r < 0) {
    503 		usbi_err(dev->ctx, "parse_configuration failed with error %d", r);
    504 		goto err;
    505 	} else if (r > 0) {
    506 		usbi_warn(dev->ctx, "descriptor data still left");
    507 	}
    508 
    509 	free(buf);
    510 	*config = _config;
    511 	return 0;
    512 
    513 err:
    514 	free(_config);
    515 	if (buf)
    516 		free(buf);
    517 	return r;
    518 }
    519 
    520 /** \ingroup desc
    521  * Get a USB configuration descriptor based on its index.
    522  * This is a non-blocking function which does not involve any requests being
    523  * sent to the device.
    524  *
    525  * \param dev a device
    526  * \param config_index the index of the configuration you wish to retrieve
    527  * \param config output location for the USB configuration descriptor. Only
    528  * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
    529  * after use.
    530  * \returns 0 on success
    531  * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
    532  * \returns another LIBUSB_ERROR code on error
    533  * \see libusb_get_active_config_descriptor()
    534  * \see libusb_get_config_descriptor_by_value()
    535  */
    536 int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
    537 	uint8_t config_index, struct libusb_config_descriptor **config)
    538 {
    539 	struct libusb_config_descriptor *_config;
    540 	unsigned char tmp[8];
    541 	unsigned char *buf = NULL;
    542 	int host_endian = 0;
    543 	int r;
    544 
    545 	usbi_dbg("index %d", config_index);
    546 	if (config_index >= dev->num_configurations)
    547 		return LIBUSB_ERROR_NOT_FOUND;
    548 
    549 	_config = malloc(sizeof(*_config));
    550 	if (!_config)
    551 		return LIBUSB_ERROR_NO_MEM;
    552 
    553 	r = usbi_backend->get_config_descriptor(dev, config_index, tmp,
    554 		sizeof(tmp), &host_endian);
    555 	if (r < 0)
    556 		goto err;
    557 
    558 	usbi_parse_descriptor(tmp, "bbw", _config, host_endian);
    559 	buf = malloc(_config->wTotalLength);
    560 	if (!buf) {
    561 		r = LIBUSB_ERROR_NO_MEM;
    562 		goto err;
    563 	}
    564 
    565 	host_endian = 0;
    566 	r = usbi_backend->get_config_descriptor(dev, config_index, buf,
    567 		_config->wTotalLength, &host_endian);
    568 	if (r < 0)
    569 		goto err;
    570 
    571 	r = parse_configuration(dev->ctx, _config, buf, host_endian);
    572 	if (r < 0) {
    573 		usbi_err(dev->ctx, "parse_configuration failed with error %d", r);
    574 		goto err;
    575 	} else if (r > 0) {
    576 		usbi_warn(dev->ctx, "descriptor data still left");
    577 	}
    578 
    579 	free(buf);
    580 	*config = _config;
    581 	return 0;
    582 
    583 err:
    584 	free(_config);
    585 	if (buf)
    586 		free(buf);
    587 	return r;
    588 }
    589 
    590 /* iterate through all configurations, returning the index of the configuration
    591  * matching a specific bConfigurationValue in the idx output parameter, or -1
    592  * if the config was not found.
    593  * returns 0 or a LIBUSB_ERROR code
    594  */
    595 int usbi_get_config_index_by_value(struct libusb_device *dev,
    596 	uint8_t bConfigurationValue, int *idx)
    597 {
    598 	uint8_t i;
    599 
    600 	usbi_dbg("value %d", bConfigurationValue);
    601 	for (i = 0; i < dev->num_configurations; i++) {
    602 		unsigned char tmp[6];
    603 		int host_endian;
    604 		int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp),
    605 			&host_endian);
    606 		if (r < 0)
    607 			return r;
    608 		if (tmp[5] == bConfigurationValue) {
    609 			*idx = i;
    610 			return 0;
    611 		}
    612 	}
    613 
    614 	*idx = -1;
    615 	return 0;
    616 }
    617 
    618 /** \ingroup desc
    619  * Get a USB configuration descriptor with a specific bConfigurationValue.
    620  * This is a non-blocking function which does not involve any requests being
    621  * sent to the device.
    622  *
    623  * \param dev a device
    624  * \param bConfigurationValue the bConfigurationValue of the configuration you
    625  * wish to retrieve
    626  * \param config output location for the USB configuration descriptor. Only
    627  * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
    628  * after use.
    629  * \returns 0 on success
    630  * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
    631  * \returns another LIBUSB_ERROR code on error
    632  * \see libusb_get_active_config_descriptor()
    633  * \see libusb_get_config_descriptor()
    634  */
    635 int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
    636 	uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
    637 {
    638 	int idx;
    639 	int r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx);
    640 	if (r < 0)
    641 		return r;
    642 	else if (idx == -1)
    643 		return LIBUSB_ERROR_NOT_FOUND;
    644 	else
    645 		return libusb_get_config_descriptor(dev, (uint8_t) idx, config);
    646 }
    647 
    648 /** \ingroup desc
    649  * Free a configuration descriptor obtained from
    650  * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
    651  * It is safe to call this function with a NULL config parameter, in which
    652  * case the function simply returns.
    653  *
    654  * \param config the configuration descriptor to free
    655  */
    656 void API_EXPORTED libusb_free_config_descriptor(
    657 	struct libusb_config_descriptor *config)
    658 {
    659 	if (!config)
    660 		return;
    661 
    662 	clear_configuration(config);
    663 	free(config);
    664 }
    665 
    666 /** \ingroup desc
    667  * Retrieve a string descriptor in C style ASCII.
    668  *
    669  * Wrapper around libusb_get_string_descriptor(). Uses the first language
    670  * supported by the device.
    671  *
    672  * \param dev a device handle
    673  * \param desc_index the index of the descriptor to retrieve
    674  * \param data output buffer for ASCII string descriptor
    675  * \param length size of data buffer
    676  * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
    677  */
    678 int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
    679 	uint8_t desc_index, unsigned char *data, int length)
    680 {
    681 	unsigned char tbuf[255]; /* Some devices choke on size > 255 */
    682 	int r, si, di;
    683 	uint16_t langid;
    684 
    685 	/* Asking for the zero'th index is special - it returns a string
    686 	 * descriptor that contains all the language IDs supported by the
    687 	 * device. Typically there aren't many - often only one. Language
    688 	 * IDs are 16 bit numbers, and they start at the third byte in the
    689 	 * descriptor. There's also no point in trying to read descriptor 0
    690 	 * with this function. See USB 2.0 specification section 9.6.7 for
    691 	 * more information.
    692 	 */
    693 
    694 	if (desc_index == 0)
    695 		return LIBUSB_ERROR_INVALID_PARAM;
    696 
    697 	r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf));
    698 	if (r < 0)
    699 		return r;
    700 
    701 	if (r < 4)
    702 		return LIBUSB_ERROR_IO;
    703 
    704 	langid = tbuf[2] | (tbuf[3] << 8);
    705 
    706 	r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf,
    707 		sizeof(tbuf));
    708 	if (r < 0)
    709 		return r;
    710 
    711 	if (tbuf[1] != LIBUSB_DT_STRING)
    712 		return LIBUSB_ERROR_IO;
    713 
    714 	if (tbuf[0] > r)
    715 		return LIBUSB_ERROR_IO;
    716 
    717 	for (di = 0, si = 2; si < tbuf[0]; si += 2) {
    718 		if (di >= (length - 1))
    719 			break;
    720 
    721 		if (tbuf[si + 1]) /* high byte */
    722 			data[di++] = '?';
    723 		else
    724 			data[di++] = tbuf[si];
    725 	}
    726 
    727 	data[di] = 0;
    728 	return di;
    729 }
    730 
    731