descriptor.c revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
1/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
2/*
3 * USB descriptor handling functions for libusbx
4 * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
5 * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <errno.h>
23#include <stdint.h>
24#include <stdlib.h>
25#include <string.h>
26
27#include "libusbi.h"
28
29#define DESC_HEADER_LENGTH		2
30#define DEVICE_DESC_LENGTH		18
31#define CONFIG_DESC_LENGTH		9
32#define INTERFACE_DESC_LENGTH		9
33#define ENDPOINT_DESC_LENGTH		7
34#define ENDPOINT_AUDIO_DESC_LENGTH	9
35
36/** @defgroup desc USB descriptors
37 * This page details how to examine the various standard USB descriptors
38 * for detected devices
39 */
40
41/* set host_endian if the w values are already in host endian format,
42 * as opposed to bus endian. */
43int usbi_parse_descriptor(const unsigned char *source, const char *descriptor,
44	void *dest, int host_endian)
45{
46	const unsigned char *sp = source;
47	unsigned char *dp = dest;
48	uint16_t w;
49	const char *cp;
50	uint32_t d;
51
52	for (cp = descriptor; *cp; cp++) {
53		switch (*cp) {
54			case 'b':	/* 8-bit byte */
55				*dp++ = *sp++;
56				break;
57			case 'w':	/* 16-bit word, convert from little endian to CPU */
58				dp += ((uintptr_t)dp & 1);	/* Align to word boundary */
59
60				if (host_endian) {
61					memcpy(dp, sp, 2);
62				} else {
63					w = (sp[1] << 8) | sp[0];
64					*((uint16_t *)dp) = w;
65				}
66				sp += 2;
67				dp += 2;
68				break;
69			case 'd':	/* 32-bit word, convert from little endian to CPU */
70				dp += ((uintptr_t)dp & 1);	/* Align to word boundary */
71
72				if (host_endian) {
73					memcpy(dp, sp, 4);
74				} else {
75					d = (sp[3] << 24) | (sp[2] << 16) |
76						(sp[1] << 8) | sp[0];
77					*((uint32_t *)dp) = d;
78				}
79				sp += 4;
80				dp += 4;
81				break;
82			case 'u':	/* 16 byte UUID */
83				memcpy(dp, sp, 16);
84				sp += 16;
85				dp += 16;
86				break;
87		}
88	}
89
90	return (int) (sp - source);
91}
92
93static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
94{
95	if (endpoint->extra)
96		free((unsigned char *) endpoint->extra);
97}
98
99static int parse_endpoint(struct libusb_context *ctx,
100	struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer,
101	int size, int host_endian)
102{
103	struct usb_descriptor_header header;
104	unsigned char *extra;
105	unsigned char *begin;
106	int parsed = 0;
107	int len;
108
109	if (size < DESC_HEADER_LENGTH) {
110		usbi_err(ctx, "short endpoint descriptor read %d/%d",
111			 size, DESC_HEADER_LENGTH);
112		return LIBUSB_ERROR_IO;
113	}
114
115	usbi_parse_descriptor(buffer, "bb", &header, 0);
116	if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) {
117		usbi_err(ctx, "unexpected descriptor %x (expected %x)",
118			header.bDescriptorType, LIBUSB_DT_ENDPOINT);
119		return parsed;
120	}
121	if (header.bLength > size) {
122		usbi_warn(ctx, "short endpoint descriptor read %d/%d",
123			  size, header.bLength);
124		return parsed;
125	}
126	if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH)
127		usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian);
128	else if (header.bLength >= ENDPOINT_DESC_LENGTH)
129		usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian);
130	else {
131		usbi_err(ctx, "invalid endpoint bLength (%d)", header.bLength);
132		return LIBUSB_ERROR_IO;
133	}
134
135	buffer += header.bLength;
136	size -= header.bLength;
137	parsed += header.bLength;
138
139	/* Skip over the rest of the Class Specific or Vendor Specific */
140	/*  descriptors */
141	begin = buffer;
142	while (size >= DESC_HEADER_LENGTH) {
143		usbi_parse_descriptor(buffer, "bb", &header, 0);
144		if (header.bLength < DESC_HEADER_LENGTH) {
145			usbi_err(ctx, "invalid extra ep desc len (%d)",
146				 header.bLength);
147			return LIBUSB_ERROR_IO;
148		} else if (header.bLength > size) {
149			usbi_warn(ctx, "short extra ep desc read %d/%d",
150				  size, header.bLength);
151			return parsed;
152		}
153
154		/* If we find another "proper" descriptor then we're done  */
155		if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
156				(header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
157				(header.bDescriptorType == LIBUSB_DT_CONFIG) ||
158				(header.bDescriptorType == LIBUSB_DT_DEVICE))
159			break;
160
161		usbi_dbg("skipping descriptor %x", header.bDescriptorType);
162		buffer += header.bLength;
163		size -= header.bLength;
164		parsed += header.bLength;
165	}
166
167	/* Copy any unknown descriptors into a storage area for drivers */
168	/*  to later parse */
169	len = (int)(buffer - begin);
170	if (!len) {
171		endpoint->extra = NULL;
172		endpoint->extra_length = 0;
173		return parsed;
174	}
175
176	extra = malloc(len);
177	endpoint->extra = extra;
178	if (!extra) {
179		endpoint->extra_length = 0;
180		return LIBUSB_ERROR_NO_MEM;
181	}
182
183	memcpy(extra, begin, len);
184	endpoint->extra_length = len;
185
186	return parsed;
187}
188
189static void clear_interface(struct libusb_interface *usb_interface)
190{
191	int i;
192	int j;
193
194	if (usb_interface->altsetting) {
195		for (i = 0; i < usb_interface->num_altsetting; i++) {
196			struct libusb_interface_descriptor *ifp =
197				(struct libusb_interface_descriptor *)
198				usb_interface->altsetting + i;
199			if (ifp->extra)
200				free((void *) ifp->extra);
201			if (ifp->endpoint) {
202				for (j = 0; j < ifp->bNumEndpoints; j++)
203					clear_endpoint((struct libusb_endpoint_descriptor *)
204						ifp->endpoint + j);
205				free((void *) ifp->endpoint);
206			}
207		}
208		free((void *) usb_interface->altsetting);
209		usb_interface->altsetting = NULL;
210	}
211
212}
213
214static int parse_interface(libusb_context *ctx,
215	struct libusb_interface *usb_interface, unsigned char *buffer, int size,
216	int host_endian)
217{
218	int i;
219	int len;
220	int r;
221	int parsed = 0;
222	int interface_number = -1;
223	size_t tmp;
224	struct usb_descriptor_header header;
225	struct libusb_interface_descriptor *ifp;
226	unsigned char *begin;
227
228	usb_interface->num_altsetting = 0;
229
230	while (size >= INTERFACE_DESC_LENGTH) {
231		struct libusb_interface_descriptor *altsetting =
232			(struct libusb_interface_descriptor *) usb_interface->altsetting;
233		altsetting = usbi_reallocf(altsetting,
234			sizeof(struct libusb_interface_descriptor) *
235			(usb_interface->num_altsetting + 1));
236		if (!altsetting) {
237			r = LIBUSB_ERROR_NO_MEM;
238			goto err;
239		}
240		usb_interface->altsetting = altsetting;
241
242		ifp = altsetting + usb_interface->num_altsetting;
243		usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0);
244		if (ifp->bDescriptorType != LIBUSB_DT_INTERFACE) {
245			usbi_err(ctx, "unexpected descriptor %x (expected %x)",
246				 ifp->bDescriptorType, LIBUSB_DT_INTERFACE);
247			return parsed;
248		}
249		if (ifp->bLength < INTERFACE_DESC_LENGTH) {
250			usbi_err(ctx, "invalid interface bLength (%d)",
251				 ifp->bLength);
252			r = LIBUSB_ERROR_IO;
253			goto err;
254		}
255		if (ifp->bLength > size) {
256			usbi_warn(ctx, "short intf descriptor read %d/%d",
257				 size, ifp->bLength);
258			return parsed;
259		}
260		if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
261			usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoints);
262			r = LIBUSB_ERROR_IO;
263			goto err;
264		}
265
266		usb_interface->num_altsetting++;
267		ifp->extra = NULL;
268		ifp->extra_length = 0;
269		ifp->endpoint = NULL;
270
271		if (interface_number == -1)
272			interface_number = ifp->bInterfaceNumber;
273
274		/* Skip over the interface */
275		buffer += ifp->bLength;
276		parsed += ifp->bLength;
277		size -= ifp->bLength;
278
279		begin = buffer;
280
281		/* Skip over any interface, class or vendor descriptors */
282		while (size >= DESC_HEADER_LENGTH) {
283			usbi_parse_descriptor(buffer, "bb", &header, 0);
284			if (header.bLength < DESC_HEADER_LENGTH) {
285				usbi_err(ctx,
286					 "invalid extra intf desc len (%d)",
287					 header.bLength);
288				r = LIBUSB_ERROR_IO;
289				goto err;
290			} else if (header.bLength > size) {
291				usbi_warn(ctx,
292					  "short extra intf desc read %d/%d",
293					  size, header.bLength);
294				return parsed;
295			}
296
297			/* If we find another "proper" descriptor then we're done */
298			if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
299					(header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
300					(header.bDescriptorType == LIBUSB_DT_CONFIG) ||
301					(header.bDescriptorType == LIBUSB_DT_DEVICE))
302				break;
303
304			buffer += header.bLength;
305			parsed += header.bLength;
306			size -= header.bLength;
307		}
308
309		/* Copy any unknown descriptors into a storage area for */
310		/*  drivers to later parse */
311		len = (int)(buffer - begin);
312		if (len) {
313			ifp->extra = malloc(len);
314			if (!ifp->extra) {
315				r = LIBUSB_ERROR_NO_MEM;
316				goto err;
317			}
318			memcpy((unsigned char *) ifp->extra, begin, len);
319			ifp->extra_length = len;
320		}
321
322		if (ifp->bNumEndpoints > 0) {
323			struct libusb_endpoint_descriptor *endpoint;
324			tmp = ifp->bNumEndpoints * sizeof(struct libusb_endpoint_descriptor);
325			endpoint = malloc(tmp);
326			ifp->endpoint = endpoint;
327			if (!endpoint) {
328				r = LIBUSB_ERROR_NO_MEM;
329				goto err;
330			}
331
332			memset(endpoint, 0, tmp);
333			for (i = 0; i < ifp->bNumEndpoints; i++) {
334				r = parse_endpoint(ctx, endpoint + i, buffer, size,
335					host_endian);
336				if (r < 0)
337					goto err;
338				if (r == 0) {
339					ifp->bNumEndpoints = (uint8_t)i;
340					break;;
341				}
342
343				buffer += r;
344				parsed += r;
345				size -= r;
346			}
347		}
348
349		/* We check to see if it's an alternate to this one */
350		ifp = (struct libusb_interface_descriptor *) buffer;
351		if (size < LIBUSB_DT_INTERFACE_SIZE ||
352				ifp->bDescriptorType != LIBUSB_DT_INTERFACE ||
353				ifp->bInterfaceNumber != interface_number)
354			return parsed;
355	}
356
357	return parsed;
358err:
359	clear_interface(usb_interface);
360	return r;
361}
362
363static void clear_configuration(struct libusb_config_descriptor *config)
364{
365	if (config->interface) {
366		int i;
367		for (i = 0; i < config->bNumInterfaces; i++)
368			clear_interface((struct libusb_interface *)
369				config->interface + i);
370		free((void *) config->interface);
371	}
372	if (config->extra)
373		free((void *) config->extra);
374}
375
376static int parse_configuration(struct libusb_context *ctx,
377	struct libusb_config_descriptor *config, unsigned char *buffer,
378	int size, int host_endian)
379{
380	int i;
381	int r;
382	size_t tmp;
383	struct usb_descriptor_header header;
384	struct libusb_interface *usb_interface;
385
386	if (size < LIBUSB_DT_CONFIG_SIZE) {
387		usbi_err(ctx, "short config descriptor read %d/%d",
388			 size, LIBUSB_DT_CONFIG_SIZE);
389		return LIBUSB_ERROR_IO;
390	}
391
392	usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian);
393	if (config->bDescriptorType != LIBUSB_DT_CONFIG) {
394		usbi_err(ctx, "unexpected descriptor %x (expected %x)",
395			 config->bDescriptorType, LIBUSB_DT_CONFIG);
396		return LIBUSB_ERROR_IO;
397	}
398	if (config->bLength < LIBUSB_DT_CONFIG_SIZE) {
399		usbi_err(ctx, "invalid config bLength (%d)", config->bLength);
400		return LIBUSB_ERROR_IO;
401	}
402	if (config->bLength > size) {
403		usbi_err(ctx, "short config descriptor read %d/%d",
404			 size, config->bLength);
405		return LIBUSB_ERROR_IO;
406	}
407	if (config->bNumInterfaces > USB_MAXINTERFACES) {
408		usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces);
409		return LIBUSB_ERROR_IO;
410	}
411
412	tmp = config->bNumInterfaces * sizeof(struct libusb_interface);
413	usb_interface = malloc(tmp);
414	config->interface = usb_interface;
415	if (!config->interface)
416		return LIBUSB_ERROR_NO_MEM;
417
418	memset(usb_interface, 0, tmp);
419	buffer += config->bLength;
420	size -= config->bLength;
421
422	config->extra = NULL;
423	config->extra_length = 0;
424
425	for (i = 0; i < config->bNumInterfaces; i++) {
426		int len;
427		unsigned char *begin;
428
429		/* Skip over the rest of the Class Specific or Vendor */
430		/*  Specific descriptors */
431		begin = buffer;
432		while (size >= DESC_HEADER_LENGTH) {
433			usbi_parse_descriptor(buffer, "bb", &header, 0);
434
435			if (header.bLength < DESC_HEADER_LENGTH) {
436				usbi_err(ctx,
437					 "invalid extra config desc len (%d)",
438					 header.bLength);
439				r = LIBUSB_ERROR_IO;
440				goto err;
441			} else if (header.bLength > size) {
442				usbi_warn(ctx,
443					  "short extra config desc read %d/%d",
444					  size, header.bLength);
445				config->bNumInterfaces = (uint8_t)i;
446				return size;
447			}
448
449			/* If we find another "proper" descriptor then we're done */
450			if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
451					(header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
452					(header.bDescriptorType == LIBUSB_DT_CONFIG) ||
453					(header.bDescriptorType == LIBUSB_DT_DEVICE))
454				break;
455
456			usbi_dbg("skipping descriptor 0x%x\n", header.bDescriptorType);
457			buffer += header.bLength;
458			size -= header.bLength;
459		}
460
461		/* Copy any unknown descriptors into a storage area for */
462		/*  drivers to later parse */
463		len = (int)(buffer - begin);
464		if (len) {
465			/* FIXME: We should realloc and append here */
466			if (!config->extra_length) {
467				config->extra = malloc(len);
468				if (!config->extra) {
469					r = LIBUSB_ERROR_NO_MEM;
470					goto err;
471				}
472
473				memcpy((unsigned char *) config->extra, begin, len);
474				config->extra_length = len;
475			}
476		}
477
478		r = parse_interface(ctx, usb_interface + i, buffer, size, host_endian);
479		if (r < 0)
480			goto err;
481		if (r == 0) {
482			config->bNumInterfaces = (uint8_t)i;
483			break;
484		}
485
486		buffer += r;
487		size -= r;
488	}
489
490	return size;
491
492err:
493	clear_configuration(config);
494	return r;
495}
496
497static int raw_desc_to_config(struct libusb_context *ctx,
498	unsigned char *buf, int size, int host_endian,
499	struct libusb_config_descriptor **config)
500{
501	struct libusb_config_descriptor *_config = malloc(sizeof(*_config));
502	int r;
503
504	if (!_config)
505		return LIBUSB_ERROR_NO_MEM;
506
507	r = parse_configuration(ctx, _config, buf, size, host_endian);
508	if (r < 0) {
509		usbi_err(ctx, "parse_configuration failed with error %d", r);
510		free(_config);
511		return r;
512	} else if (r > 0) {
513		usbi_warn(ctx, "still %d bytes of descriptor data left", r);
514	}
515
516	*config = _config;
517	return LIBUSB_SUCCESS;
518}
519
520int usbi_device_cache_descriptor(libusb_device *dev)
521{
522	int r, host_endian = 0;
523
524	r = usbi_backend->get_device_descriptor(dev, (unsigned char *) &dev->device_descriptor,
525						&host_endian);
526	if (r < 0)
527		return r;
528
529	if (!host_endian) {
530		dev->device_descriptor.bcdUSB = libusb_le16_to_cpu(dev->device_descriptor.bcdUSB);
531		dev->device_descriptor.idVendor = libusb_le16_to_cpu(dev->device_descriptor.idVendor);
532		dev->device_descriptor.idProduct = libusb_le16_to_cpu(dev->device_descriptor.idProduct);
533		dev->device_descriptor.bcdDevice = libusb_le16_to_cpu(dev->device_descriptor.bcdDevice);
534	}
535
536	return LIBUSB_SUCCESS;
537}
538
539/** \ingroup desc
540 * Get the USB device descriptor for a given device.
541 *
542 * This is a non-blocking function; the device descriptor is cached in memory.
543 *
544 * Note since libusbx-1.0.16, \ref LIBUSBX_API_VERSION >= 0x01000102, this
545 * function always succeeds.
546 *
547 * \param dev the device
548 * \param desc output location for the descriptor data
549 * \returns 0 on success or a LIBUSB_ERROR code on failure
550 */
551int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
552	struct libusb_device_descriptor *desc)
553{
554	usbi_dbg("");
555	memcpy((unsigned char *) desc, (unsigned char *) &dev->device_descriptor,
556	       sizeof (dev->device_descriptor));
557	return 0;
558}
559
560/** \ingroup desc
561 * Get the USB configuration descriptor for the currently active configuration.
562 * This is a non-blocking function which does not involve any requests being
563 * sent to the device.
564 *
565 * \param dev a device
566 * \param config output location for the USB configuration descriptor. Only
567 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
568 * after use.
569 * \returns 0 on success
570 * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
571 * \returns another LIBUSB_ERROR code on error
572 * \see libusb_get_config_descriptor
573 */
574int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
575	struct libusb_config_descriptor **config)
576{
577	struct libusb_config_descriptor _config;
578	unsigned char tmp[LIBUSB_DT_CONFIG_SIZE];
579	unsigned char *buf = NULL;
580	int host_endian = 0;
581	int r;
582
583	r = usbi_backend->get_active_config_descriptor(dev, tmp,
584		LIBUSB_DT_CONFIG_SIZE, &host_endian);
585	if (r < 0)
586		return r;
587	if (r < LIBUSB_DT_CONFIG_SIZE) {
588		usbi_err(dev->ctx, "short config descriptor read %d/%d",
589			 r, LIBUSB_DT_CONFIG_SIZE);
590		return LIBUSB_ERROR_IO;
591	}
592
593	usbi_parse_descriptor(tmp, "bbw", &_config, host_endian);
594	buf = malloc(_config.wTotalLength);
595	if (!buf)
596		return LIBUSB_ERROR_NO_MEM;
597
598	r = usbi_backend->get_active_config_descriptor(dev, buf,
599		_config.wTotalLength, &host_endian);
600	if (r >= 0)
601		r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
602
603	free(buf);
604	return r;
605}
606
607/** \ingroup desc
608 * Get a USB configuration descriptor based on its index.
609 * This is a non-blocking function which does not involve any requests being
610 * sent to the device.
611 *
612 * \param dev a device
613 * \param config_index the index of the configuration you wish to retrieve
614 * \param config output location for the USB configuration descriptor. Only
615 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
616 * after use.
617 * \returns 0 on success
618 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
619 * \returns another LIBUSB_ERROR code on error
620 * \see libusb_get_active_config_descriptor()
621 * \see libusb_get_config_descriptor_by_value()
622 */
623int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
624	uint8_t config_index, struct libusb_config_descriptor **config)
625{
626	struct libusb_config_descriptor _config;
627	unsigned char tmp[LIBUSB_DT_CONFIG_SIZE];
628	unsigned char *buf = NULL;
629	int host_endian = 0;
630	int r;
631
632	usbi_dbg("index %d", config_index);
633	if (config_index >= dev->num_configurations)
634		return LIBUSB_ERROR_NOT_FOUND;
635
636	r = usbi_backend->get_config_descriptor(dev, config_index, tmp,
637		LIBUSB_DT_CONFIG_SIZE, &host_endian);
638	if (r < 0)
639		return r;
640	if (r < LIBUSB_DT_CONFIG_SIZE) {
641		usbi_err(dev->ctx, "short config descriptor read %d/%d",
642			 r, LIBUSB_DT_CONFIG_SIZE);
643		return LIBUSB_ERROR_IO;
644	}
645
646	usbi_parse_descriptor(tmp, "bbw", &_config, host_endian);
647	buf = malloc(_config.wTotalLength);
648	if (!buf)
649		return LIBUSB_ERROR_NO_MEM;
650
651	r = usbi_backend->get_config_descriptor(dev, config_index, buf,
652		_config.wTotalLength, &host_endian);
653	if (r >= 0)
654		r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
655
656	free(buf);
657	return r;
658}
659
660/* iterate through all configurations, returning the index of the configuration
661 * matching a specific bConfigurationValue in the idx output parameter, or -1
662 * if the config was not found.
663 * returns 0 or a LIBUSB_ERROR code
664 */
665int usbi_get_config_index_by_value(struct libusb_device *dev,
666	uint8_t bConfigurationValue, int *idx)
667{
668	uint8_t i;
669
670	usbi_dbg("value %d", bConfigurationValue);
671	for (i = 0; i < dev->num_configurations; i++) {
672		unsigned char tmp[6];
673		int host_endian;
674		int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp),
675			&host_endian);
676		if (r < 0)
677			return r;
678		if (tmp[5] == bConfigurationValue) {
679			*idx = i;
680			return 0;
681		}
682	}
683
684	*idx = -1;
685	return 0;
686}
687
688/** \ingroup desc
689 * Get a USB configuration descriptor with a specific bConfigurationValue.
690 * This is a non-blocking function which does not involve any requests being
691 * sent to the device.
692 *
693 * \param dev a device
694 * \param bConfigurationValue the bConfigurationValue of the configuration you
695 * wish to retrieve
696 * \param config output location for the USB configuration descriptor. Only
697 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
698 * after use.
699 * \returns 0 on success
700 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
701 * \returns another LIBUSB_ERROR code on error
702 * \see libusb_get_active_config_descriptor()
703 * \see libusb_get_config_descriptor()
704 */
705int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
706	uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
707{
708	int r, idx, host_endian;
709	unsigned char *buf = NULL;
710
711	if (usbi_backend->get_config_descriptor_by_value) {
712		r = usbi_backend->get_config_descriptor_by_value(dev,
713			bConfigurationValue, &buf, &host_endian);
714		if (r < 0)
715			return r;
716		return raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
717	}
718
719	r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx);
720	if (r < 0)
721		return r;
722	else if (idx == -1)
723		return LIBUSB_ERROR_NOT_FOUND;
724	else
725		return libusb_get_config_descriptor(dev, (uint8_t) idx, config);
726}
727
728/** \ingroup desc
729 * Free a configuration descriptor obtained from
730 * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
731 * It is safe to call this function with a NULL config parameter, in which
732 * case the function simply returns.
733 *
734 * \param config the configuration descriptor to free
735 */
736void API_EXPORTED libusb_free_config_descriptor(
737	struct libusb_config_descriptor *config)
738{
739	if (!config)
740		return;
741
742	clear_configuration(config);
743	free(config);
744}
745
746/** \ingroup desc
747 * Get an endpoints superspeed endpoint companion descriptor (if any)
748 *
749 * \param ctx the context to operate on, or NULL for the default context
750 * \param endpoint endpoint descriptor from which to get the superspeed
751 * endpoint companion descriptor
752 * \param ep_comp output location for the superspeed endpoint companion
753 * descriptor. Only valid if 0 was returned. Must be freed with
754 * libusb_free_ss_endpoint_companion_descriptor() after use.
755 * \returns 0 on success
756 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
757 * \returns another LIBUSB_ERROR code on error
758 */
759int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor(
760	struct libusb_context *ctx,
761	const struct libusb_endpoint_descriptor *endpoint,
762	struct libusb_ss_endpoint_companion_descriptor **ep_comp)
763{
764	struct usb_descriptor_header header;
765	int size = endpoint->extra_length;
766	const unsigned char *buffer = endpoint->extra;
767
768	*ep_comp = NULL;
769
770	while (size >= DESC_HEADER_LENGTH) {
771		usbi_parse_descriptor(buffer, "bb", &header, 0);
772		if (header.bLength < 2 || header.bLength > size) {
773			usbi_err(ctx, "invalid descriptor length %d",
774				 header.bLength);
775			return LIBUSB_ERROR_IO;
776		}
777		if (header.bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) {
778			buffer += header.bLength;
779			size -= header.bLength;
780			continue;
781		}
782		if (header.bLength < LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE) {
783			usbi_err(ctx, "invalid ss-ep-comp-desc length %d",
784				 header.bLength);
785			return LIBUSB_ERROR_IO;
786		}
787		*ep_comp = malloc(sizeof(**ep_comp));
788		if (*ep_comp == NULL)
789			return LIBUSB_ERROR_NO_MEM;
790		usbi_parse_descriptor(buffer, "bbbbw", *ep_comp, 0);
791		return LIBUSB_SUCCESS;
792	}
793	return LIBUSB_ERROR_NOT_FOUND;
794}
795
796/** \ingroup desc
797 * Free a superspeed endpoint companion descriptor obtained from
798 * libusb_get_ss_endpoint_companion_descriptor().
799 * It is safe to call this function with a NULL ep_comp parameter, in which
800 * case the function simply returns.
801 *
802 * \param ep_comp the superspeed endpoint companion descriptor to free
803 */
804void API_EXPORTED libusb_free_ss_endpoint_companion_descriptor(
805	struct libusb_ss_endpoint_companion_descriptor *ep_comp)
806{
807	free(ep_comp);
808}
809
810static int parse_bos(struct libusb_context *ctx,
811	struct libusb_bos_descriptor **bos,
812	unsigned char *buffer, int size, int host_endian)
813{
814	struct libusb_bos_descriptor bos_header, *_bos;
815	struct libusb_bos_dev_capability_descriptor dev_cap;
816	int i;
817
818	if (size < LIBUSB_DT_BOS_SIZE) {
819		usbi_err(ctx, "short bos descriptor read %d/%d",
820			 size, LIBUSB_DT_BOS_SIZE);
821		return LIBUSB_ERROR_IO;
822	}
823
824	usbi_parse_descriptor(buffer, "bbwb", &bos_header, host_endian);
825	if (bos_header.bDescriptorType != LIBUSB_DT_BOS) {
826		usbi_err(ctx, "unexpected descriptor %x (expected %x)",
827			 bos_header.bDescriptorType, LIBUSB_DT_BOS);
828		return LIBUSB_ERROR_IO;
829	}
830	if (bos_header.bLength < LIBUSB_DT_BOS_SIZE) {
831		usbi_err(ctx, "invalid bos bLength (%d)", bos_header.bLength);
832		return LIBUSB_ERROR_IO;
833	}
834	if (bos_header.bLength > size) {
835		usbi_err(ctx, "short bos descriptor read %d/%d",
836			 size, bos_header.bLength);
837		return LIBUSB_ERROR_IO;
838	}
839
840	_bos = calloc (1,
841		sizeof(*_bos) + bos_header.bNumDeviceCaps * sizeof(void *));
842	if (!_bos)
843		return LIBUSB_ERROR_NO_MEM;
844
845	usbi_parse_descriptor(buffer, "bbwb", _bos, host_endian);
846	buffer += bos_header.bLength;
847	size -= bos_header.bLength;
848
849	/* Get the device capability descriptors */
850	for (i = 0; i < bos_header.bNumDeviceCaps; i++) {
851		if (size < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
852			usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
853				  size, LIBUSB_DT_DEVICE_CAPABILITY_SIZE);
854			break;
855		}
856		usbi_parse_descriptor(buffer, "bbb", &dev_cap, host_endian);
857		if (dev_cap.bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) {
858			usbi_warn(ctx, "unexpected descriptor %x (expected %x)",
859				  dev_cap.bDescriptorType, LIBUSB_DT_DEVICE_CAPABILITY);
860			break;
861		}
862		if (dev_cap.bLength < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
863			usbi_err(ctx, "invalid dev-cap bLength (%d)",
864				 dev_cap.bLength);
865			libusb_free_bos_descriptor(_bos);
866			return LIBUSB_ERROR_IO;
867		}
868		if (dev_cap.bLength > size) {
869			usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
870				  size, dev_cap.bLength);
871			break;
872		}
873
874		_bos->dev_capability[i] = malloc(dev_cap.bLength);
875		if (!_bos->dev_capability[i]) {
876			libusb_free_bos_descriptor(_bos);
877			return LIBUSB_ERROR_NO_MEM;
878		}
879		memcpy(_bos->dev_capability[i], buffer, dev_cap.bLength);
880		buffer += dev_cap.bLength;
881		size -= dev_cap.bLength;
882	}
883	_bos->bNumDeviceCaps = (uint8_t)i;
884	*bos = _bos;
885
886	return LIBUSB_SUCCESS;
887}
888
889/** \ingroup desc
890 * Get a Binary Object Store (BOS) descriptor
891 * This is a BLOCKING function, which will send requests to the device.
892 *
893 * \param handle the handle of an open libusb device
894 * \param bos output location for the BOS descriptor. Only valid if 0 was returned.
895 * Must be freed with \ref libusb_free_bos_descriptor() after use.
896 * \returns 0 on success
897 * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor
898 * \returns another LIBUSB_ERROR code on error
899 */
900int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *handle,
901	struct libusb_bos_descriptor **bos)
902{
903	struct libusb_bos_descriptor _bos;
904	uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0};
905	unsigned char *bos_data = NULL;
906	const int host_endian = 0;
907	int r;
908
909	/* Read the BOS. This generates 2 requests on the bus,
910	 * one for the header, and one for the full BOS */
911	r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_header,
912				  LIBUSB_DT_BOS_SIZE);
913	if (r < 0) {
914		if (r != LIBUSB_ERROR_PIPE)
915			usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r);
916		return r;
917	}
918	if (r < LIBUSB_DT_BOS_SIZE) {
919		usbi_err(handle->dev->ctx, "short BOS read %d/%d",
920			 r, LIBUSB_DT_BOS_SIZE);
921		return LIBUSB_ERROR_IO;
922	}
923
924	usbi_parse_descriptor(bos_header, "bbwb", &_bos, host_endian);
925	usbi_dbg("found BOS descriptor: size %d bytes, %d capabilities",
926		 _bos.wTotalLength, _bos.bNumDeviceCaps);
927	bos_data = calloc(_bos.wTotalLength, 1);
928	if (bos_data == NULL)
929		return LIBUSB_ERROR_NO_MEM;
930
931	r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_data,
932				  _bos.wTotalLength);
933	if (r >= 0)
934		r = parse_bos(handle->dev->ctx, bos, bos_data, r, host_endian);
935	else
936		usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r);
937
938	free(bos_data);
939	return r;
940}
941
942/** \ingroup desc
943 * Free a BOS descriptor obtained from libusb_get_bos_descriptor().
944 * It is safe to call this function with a NULL bos parameter, in which
945 * case the function simply returns.
946 *
947 * \param bos the BOS descriptor to free
948 */
949void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
950{
951	int i;
952
953	if (!bos)
954		return;
955
956	for (i = 0; i < bos->bNumDeviceCaps; i++)
957		free(bos->dev_capability[i]);
958	free(bos);
959}
960
961/** \ingroup desc
962 * Get an USB 2.0 Extension descriptor
963 *
964 * \param ctx the context to operate on, or NULL for the default context
965 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
966 * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION
967 * LIBUSB_BT_USB_2_0_EXTENSION
968 * \param usb_2_0_extension output location for the USB 2.0 Extension
969 * descriptor. Only valid if 0 was returned. Must be freed with
970 * libusb_free_usb_2_0_extension_descriptor() after use.
971 * \returns 0 on success
972 * \returns a LIBUSB_ERROR code on error
973 */
974int API_EXPORTED libusb_get_usb_2_0_extension_descriptor(
975	struct libusb_context *ctx,
976	struct libusb_bos_dev_capability_descriptor *dev_cap,
977	struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)
978{
979	struct libusb_usb_2_0_extension_descriptor *_usb_2_0_extension;
980	const int host_endian = 0;
981
982	if (dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) {
983		usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
984			 dev_cap->bDevCapabilityType,
985			 LIBUSB_BT_USB_2_0_EXTENSION);
986		return LIBUSB_ERROR_INVALID_PARAM;
987	}
988	if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) {
989		usbi_err(ctx, "short dev-cap descriptor read %d/%d",
990			 dev_cap->bLength, LIBUSB_BT_USB_2_0_EXTENSION_SIZE);
991		return LIBUSB_ERROR_IO;
992	}
993
994	_usb_2_0_extension = malloc(sizeof(*_usb_2_0_extension));
995	if (!_usb_2_0_extension)
996		return LIBUSB_ERROR_NO_MEM;
997
998	usbi_parse_descriptor((unsigned char *)dev_cap, "bbbd",
999			      _usb_2_0_extension, host_endian);
1000
1001	*usb_2_0_extension = _usb_2_0_extension;
1002	return LIBUSB_SUCCESS;
1003}
1004
1005/** \ingroup desc
1006 * Free a USB 2.0 Extension descriptor obtained from
1007 * libusb_get_usb_2_0_extension_descriptor().
1008 * It is safe to call this function with a NULL usb_2_0_extension parameter,
1009 * in which case the function simply returns.
1010 *
1011 * \param usb_2_0_extension the USB 2.0 Extension descriptor to free
1012 */
1013void API_EXPORTED libusb_free_usb_2_0_extension_descriptor(
1014	struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
1015{
1016	free(usb_2_0_extension);
1017}
1018
1019/** \ingroup desc
1020 * Get a SuperSpeed USB Device Capability descriptor
1021 *
1022 * \param ctx the context to operate on, or NULL for the default context
1023 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1024 * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
1025 * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
1026 * \param ss_usb_device_cap output location for the SuperSpeed USB Device
1027 * Capability descriptor. Only valid if 0 was returned. Must be freed with
1028 * libusb_free_ss_usb_device_capability_descriptor() after use.
1029 * \returns 0 on success
1030 * \returns a LIBUSB_ERROR code on error
1031 */
1032int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor(
1033	struct libusb_context *ctx,
1034	struct libusb_bos_dev_capability_descriptor *dev_cap,
1035	struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap)
1036{
1037	struct libusb_ss_usb_device_capability_descriptor *_ss_usb_device_cap;
1038	const int host_endian = 0;
1039
1040	if (dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {
1041		usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
1042			 dev_cap->bDevCapabilityType,
1043			 LIBUSB_BT_SS_USB_DEVICE_CAPABILITY);
1044		return LIBUSB_ERROR_INVALID_PARAM;
1045	}
1046	if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) {
1047		usbi_err(ctx, "short dev-cap descriptor read %d/%d",
1048			 dev_cap->bLength, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE);
1049		return LIBUSB_ERROR_IO;
1050	}
1051
1052	_ss_usb_device_cap = malloc(sizeof(*_ss_usb_device_cap));
1053	if (!_ss_usb_device_cap)
1054		return LIBUSB_ERROR_NO_MEM;
1055
1056	usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbwbbw",
1057			      _ss_usb_device_cap, host_endian);
1058
1059	*ss_usb_device_cap = _ss_usb_device_cap;
1060	return LIBUSB_SUCCESS;
1061}
1062
1063/** \ingroup desc
1064 * Free a SuperSpeed USB Device Capability descriptor obtained from
1065 * libusb_get_ss_usb_device_capability_descriptor().
1066 * It is safe to call this function with a NULL ss_usb_device_cap
1067 * parameter, in which case the function simply returns.
1068 *
1069 * \param ss_usb_device_cap the USB 2.0 Extension descriptor to free
1070 */
1071void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor(
1072	struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap)
1073{
1074	free(ss_usb_device_cap);
1075}
1076
1077/** \ingroup desc
1078 * Get a Container ID descriptor
1079 *
1080 * \param ctx the context to operate on, or NULL for the default context
1081 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1082 * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID
1083 * LIBUSB_BT_CONTAINER_ID
1084 * \param container_id output location for the Container ID descriptor.
1085 * Only valid if 0 was returned. Must be freed with
1086 * libusb_free_container_id_descriptor() after use.
1087 * \returns 0 on success
1088 * \returns a LIBUSB_ERROR code on error
1089 */
1090int API_EXPORTED libusb_get_container_id_descriptor(struct libusb_context *ctx,
1091	struct libusb_bos_dev_capability_descriptor *dev_cap,
1092	struct libusb_container_id_descriptor **container_id)
1093{
1094	struct libusb_container_id_descriptor *_container_id;
1095	const int host_endian = 0;
1096
1097	if (dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) {
1098		usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
1099			 dev_cap->bDevCapabilityType,
1100			 LIBUSB_BT_CONTAINER_ID);
1101		return LIBUSB_ERROR_INVALID_PARAM;
1102	}
1103	if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) {
1104		usbi_err(ctx, "short dev-cap descriptor read %d/%d",
1105			 dev_cap->bLength, LIBUSB_BT_CONTAINER_ID_SIZE);
1106		return LIBUSB_ERROR_IO;
1107	}
1108
1109	_container_id = malloc(sizeof(*_container_id));
1110	if (!_container_id)
1111		return LIBUSB_ERROR_NO_MEM;
1112
1113	usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbu",
1114			      _container_id, host_endian);
1115
1116	*container_id = _container_id;
1117	return LIBUSB_SUCCESS;
1118}
1119
1120/** \ingroup desc
1121 * Free a Container ID descriptor obtained from
1122 * libusb_get_container_id_descriptor().
1123 * It is safe to call this function with a NULL container_id parameter,
1124 * in which case the function simply returns.
1125 *
1126 * \param container_id the USB 2.0 Extension descriptor to free
1127 */
1128void API_EXPORTED libusb_free_container_id_descriptor(
1129	struct libusb_container_id_descriptor *container_id)
1130{
1131	free(container_id);
1132}
1133
1134/** \ingroup desc
1135 * Retrieve a string descriptor in C style ASCII.
1136 *
1137 * Wrapper around libusb_get_string_descriptor(). Uses the first language
1138 * supported by the device.
1139 *
1140 * \param dev a device handle
1141 * \param desc_index the index of the descriptor to retrieve
1142 * \param data output buffer for ASCII string descriptor
1143 * \param length size of data buffer
1144 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
1145 */
1146int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
1147	uint8_t desc_index, unsigned char *data, int length)
1148{
1149	unsigned char tbuf[255]; /* Some devices choke on size > 255 */
1150	int r, si, di;
1151	uint16_t langid;
1152
1153	/* Asking for the zero'th index is special - it returns a string
1154	 * descriptor that contains all the language IDs supported by the
1155	 * device. Typically there aren't many - often only one. Language
1156	 * IDs are 16 bit numbers, and they start at the third byte in the
1157	 * descriptor. There's also no point in trying to read descriptor 0
1158	 * with this function. See USB 2.0 specification section 9.6.7 for
1159	 * more information.
1160	 */
1161
1162	if (desc_index == 0)
1163		return LIBUSB_ERROR_INVALID_PARAM;
1164
1165	r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf));
1166	if (r < 0)
1167		return r;
1168
1169	if (r < 4)
1170		return LIBUSB_ERROR_IO;
1171
1172	langid = tbuf[2] | (tbuf[3] << 8);
1173
1174	r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf,
1175		sizeof(tbuf));
1176	if (r < 0)
1177		return r;
1178
1179	if (tbuf[1] != LIBUSB_DT_STRING)
1180		return LIBUSB_ERROR_IO;
1181
1182	if (tbuf[0] > r)
1183		return LIBUSB_ERROR_IO;
1184
1185	for (di = 0, si = 2; si < tbuf[0]; si += 2) {
1186		if (di >= (length - 1))
1187			break;
1188
1189		if ((tbuf[si] & 0x80) || (tbuf[si + 1])) /* non-ASCII */
1190			data[di++] = '?';
1191		else
1192			data[di++] = tbuf[si];
1193	}
1194
1195	data[di] = 0;
1196	return di;
1197}
1198