• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
2 /*
3  * USB descriptor handling functions for libusb
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 "libusbi.h"
23 
24 #include <string.h>
25 
26 #define DESC_HEADER_LENGTH	2
27 
28 /** @defgroup libusb_desc USB descriptors
29  * This page details how to examine the various standard USB descriptors
30  * for detected devices
31  */
32 
33 #define READ_LE16(p) ((uint16_t)	\
34 	(((uint16_t)((p)[1]) << 8) |	\
35 	 ((uint16_t)((p)[0]))))
36 
37 #define READ_LE32(p) ((uint32_t)	\
38 	(((uint32_t)((p)[3]) << 24) |	\
39 	 ((uint32_t)((p)[2]) << 16) |	\
40 	 ((uint32_t)((p)[1]) <<  8) |	\
41 	 ((uint32_t)((p)[0]))))
42 
parse_descriptor(const void * source,const char * descriptor,void * dest)43 static void parse_descriptor(const void *source, const char *descriptor, void *dest)
44 {
45 	const uint8_t *sp = source;
46 	uint8_t *dp = dest;
47 	char field_type;
48 
49 	while (*descriptor) {
50 		field_type = *descriptor++;
51 		switch (field_type) {
52 		case 'b':	/* 8-bit byte */
53 			*dp++ = *sp++;
54 			break;
55 		case 'w':	/* 16-bit word, convert from little endian to CPU */
56 			dp += ((uintptr_t)dp & 1);	/* Align to 16-bit word boundary */
57 
58 			*((uint16_t *)dp) = READ_LE16(sp);
59 			sp += 2;
60 			dp += 2;
61 			break;
62 		case 'd':	/* 32-bit word, convert from little endian to CPU (4-byte align dst before write). */
63 			dp += 4 - ((uintptr_t)dp & 3);	/* Align to 32-bit word boundary */
64 
65 			*((uint32_t *)dp) = READ_LE32(sp);
66 			sp += 4;
67 			dp += 4;
68 			break;
69 		case 'i':	/* 32-bit word, convert from little endian to CPU (no dst alignment before write) */
70 			*((uint32_t *)dp) = READ_LE32(sp);
71 			sp += 4;
72 			dp += 4;
73 			break;
74 		case 'u':	/* 16 byte UUID */
75 			memcpy(dp, sp, 16);
76 			sp += 16;
77 			dp += 16;
78 			break;
79 		}
80 	}
81 }
82 
clear_endpoint(struct libusb_endpoint_descriptor * endpoint)83 static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
84 {
85 	free((void *)endpoint->extra);
86 }
87 
parse_endpoint(struct libusb_context * ctx,struct libusb_endpoint_descriptor * endpoint,const uint8_t * buffer,int size)88 static int parse_endpoint(struct libusb_context *ctx,
89 	struct libusb_endpoint_descriptor *endpoint, const uint8_t *buffer, int size)
90 {
91 	const struct usbi_descriptor_header *header;
92 	const uint8_t *begin;
93 	void *extra;
94 	int parsed = 0;
95 	int len;
96 
97 	if (size < DESC_HEADER_LENGTH) {
98 		usbi_err(ctx, "short endpoint descriptor read %d/%d",
99 			 size, DESC_HEADER_LENGTH);
100 		return LIBUSB_ERROR_IO;
101 	}
102 
103 	header = (const struct usbi_descriptor_header *)buffer;
104 	if (header->bDescriptorType != LIBUSB_DT_ENDPOINT) {
105 		usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
106 			header->bDescriptorType, LIBUSB_DT_ENDPOINT);
107 		return parsed;
108 	} else if (header->bLength < LIBUSB_DT_ENDPOINT_SIZE) {
109 		usbi_err(ctx, "invalid endpoint bLength (%u)", header->bLength);
110 		return LIBUSB_ERROR_IO;
111 	} else if (header->bLength > size) {
112 		usbi_warn(ctx, "short endpoint descriptor read %d/%u",
113 			  size, header->bLength);
114 		return parsed;
115 	}
116 
117 	if (header->bLength >= LIBUSB_DT_ENDPOINT_AUDIO_SIZE)
118 		parse_descriptor(buffer, "bbbbwbbb", endpoint);
119 	else
120 		parse_descriptor(buffer, "bbbbwb", endpoint);
121 
122 	buffer += header->bLength;
123 	size -= header->bLength;
124 	parsed += header->bLength;
125 
126 	/* Skip over the rest of the Class Specific or Vendor Specific */
127 	/*  descriptors */
128 	begin = buffer;
129 	while (size >= DESC_HEADER_LENGTH) {
130 		header = (const struct usbi_descriptor_header *)buffer;
131 		if (header->bLength < DESC_HEADER_LENGTH) {
132 			usbi_err(ctx, "invalid extra ep desc len (%u)",
133 				 header->bLength);
134 			return LIBUSB_ERROR_IO;
135 		} else if (header->bLength > size) {
136 			usbi_warn(ctx, "short extra ep desc read %d/%u",
137 				  size, header->bLength);
138 			return parsed;
139 		}
140 
141 		/* If we find another "proper" descriptor then we're done  */
142 		if (header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
143 		    header->bDescriptorType == LIBUSB_DT_INTERFACE ||
144 		    header->bDescriptorType == LIBUSB_DT_CONFIG ||
145 		    header->bDescriptorType == LIBUSB_DT_DEVICE)
146 			break;
147 
148 		usbi_dbg(ctx, "skipping descriptor 0x%x", header->bDescriptorType);
149 		buffer += header->bLength;
150 		size -= header->bLength;
151 		parsed += header->bLength;
152 	}
153 
154 	/* Copy any unknown descriptors into a storage area for drivers */
155 	/*  to later parse */
156 	len = (int)(buffer - begin);
157 	if (len <= 0)
158 		return parsed;
159 
160 	extra = malloc((size_t)len);
161 	if (!extra)
162 		return LIBUSB_ERROR_NO_MEM;
163 
164 	memcpy(extra, begin, (size_t)len);
165 	endpoint->extra = extra;
166 	endpoint->extra_length = len;
167 
168 	return parsed;
169 }
170 
clear_interface(struct libusb_interface * usb_interface)171 static void clear_interface(struct libusb_interface *usb_interface)
172 {
173 	int i;
174 
175 	if (usb_interface->altsetting) {
176 		for (i = 0; i < usb_interface->num_altsetting; i++) {
177 			struct libusb_interface_descriptor *ifp =
178 				(struct libusb_interface_descriptor *)
179 				usb_interface->altsetting + i;
180 
181 			free((void *)ifp->extra);
182 			if (ifp->endpoint) {
183 				uint8_t j;
184 
185 				for (j = 0; j < ifp->bNumEndpoints; j++)
186 					clear_endpoint((struct libusb_endpoint_descriptor *)
187 						       ifp->endpoint + j);
188 			}
189 			free((void *)ifp->endpoint);
190 		}
191 	}
192 	free((void *)usb_interface->altsetting);
193 	usb_interface->altsetting = NULL;
194 }
195 
parse_interface(libusb_context * ctx,struct libusb_interface * usb_interface,const uint8_t * buffer,int size)196 static int parse_interface(libusb_context *ctx,
197 	struct libusb_interface *usb_interface, const uint8_t *buffer, int size)
198 {
199 	int len;
200 	int r;
201 	int parsed = 0;
202 	int interface_number = -1;
203 	const struct usbi_descriptor_header *header;
204 	const struct usbi_interface_descriptor *if_desc;
205 	struct libusb_interface_descriptor *ifp;
206 	const uint8_t *begin;
207 
208 	while (size >= LIBUSB_DT_INTERFACE_SIZE) {
209 		struct libusb_interface_descriptor *altsetting;
210 
211 		altsetting = realloc((void *)usb_interface->altsetting,
212 			sizeof(*altsetting) * (size_t)(usb_interface->num_altsetting + 1));
213 		if (!altsetting) {
214 			r = LIBUSB_ERROR_NO_MEM;
215 			goto err;
216 		}
217 		usb_interface->altsetting = altsetting;
218 
219 		ifp = altsetting + usb_interface->num_altsetting;
220 		parse_descriptor(buffer, "bbbbbbbbb", ifp);
221 		if (ifp->bDescriptorType != LIBUSB_DT_INTERFACE) {
222 			usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
223 				 ifp->bDescriptorType, LIBUSB_DT_INTERFACE);
224 			return parsed;
225 		} else if (ifp->bLength < LIBUSB_DT_INTERFACE_SIZE) {
226 			usbi_err(ctx, "invalid interface bLength (%u)",
227 				 ifp->bLength);
228 			r = LIBUSB_ERROR_IO;
229 			goto err;
230 		} else if (ifp->bLength > size) {
231 			usbi_warn(ctx, "short intf descriptor read %d/%u",
232 				 size, ifp->bLength);
233 			return parsed;
234 		} else if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
235 			usbi_err(ctx, "too many endpoints (%u)", ifp->bNumEndpoints);
236 			r = LIBUSB_ERROR_IO;
237 			goto err;
238 		}
239 
240 		usb_interface->num_altsetting++;
241 		ifp->extra = NULL;
242 		ifp->extra_length = 0;
243 		ifp->endpoint = NULL;
244 
245 		if (interface_number == -1)
246 			interface_number = ifp->bInterfaceNumber;
247 
248 		/* Skip over the interface */
249 		buffer += ifp->bLength;
250 		parsed += ifp->bLength;
251 		size -= ifp->bLength;
252 
253 		begin = buffer;
254 
255 		/* Skip over any interface, class or vendor descriptors */
256 		while (size >= DESC_HEADER_LENGTH) {
257 			header = (const struct usbi_descriptor_header *)buffer;
258 			if (header->bLength < DESC_HEADER_LENGTH) {
259 				usbi_err(ctx,
260 					 "invalid extra intf desc len (%u)",
261 					 header->bLength);
262 				r = LIBUSB_ERROR_IO;
263 				goto err;
264 			} else if (header->bLength > size) {
265 				usbi_warn(ctx,
266 					  "short extra intf desc read %d/%u",
267 					  size, header->bLength);
268 				return parsed;
269 			}
270 
271 			/* If we find another "proper" descriptor then we're done */
272 			if (header->bDescriptorType == LIBUSB_DT_INTERFACE ||
273 			    header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
274 			    header->bDescriptorType == LIBUSB_DT_CONFIG ||
275 			    header->bDescriptorType == LIBUSB_DT_DEVICE)
276 				break;
277 
278 			buffer += header->bLength;
279 			parsed += header->bLength;
280 			size -= header->bLength;
281 		}
282 
283 		/* Copy any unknown descriptors into a storage area for */
284 		/*  drivers to later parse */
285 		len = (int)(buffer - begin);
286 		if (len > 0) {
287 			void *extra = malloc((size_t)len);
288 
289 			if (!extra) {
290 				r = LIBUSB_ERROR_NO_MEM;
291 				goto err;
292 			}
293 
294 			memcpy(extra, begin, (size_t)len);
295 			ifp->extra = extra;
296 			ifp->extra_length = len;
297 		}
298 
299 		if (ifp->bNumEndpoints > 0) {
300 			struct libusb_endpoint_descriptor *endpoint;
301 			uint8_t i;
302 
303 			endpoint = calloc(ifp->bNumEndpoints, sizeof(*endpoint));
304 			if (!endpoint) {
305 				r = LIBUSB_ERROR_NO_MEM;
306 				goto err;
307 			}
308 
309 			ifp->endpoint = endpoint;
310 			for (i = 0; i < ifp->bNumEndpoints; i++) {
311 				r = parse_endpoint(ctx, endpoint + i, buffer, size);
312 				if (r < 0)
313 					goto err;
314 				if (r == 0) {
315 					ifp->bNumEndpoints = i;
316 					break;
317 				}
318 
319 				buffer += r;
320 				parsed += r;
321 				size -= r;
322 			}
323 		}
324 
325 		/* We check to see if it's an alternate to this one */
326 		if_desc = (const struct usbi_interface_descriptor *)buffer;
327 		if (size < LIBUSB_DT_INTERFACE_SIZE ||
328 		    if_desc->bDescriptorType != LIBUSB_DT_INTERFACE ||
329 		    if_desc->bInterfaceNumber != interface_number)
330 			return parsed;
331 	}
332 
333 	return parsed;
334 err:
335 	clear_interface(usb_interface);
336 	return r;
337 }
338 
clear_configuration(struct libusb_config_descriptor * config)339 static void clear_configuration(struct libusb_config_descriptor *config)
340 {
341 	uint8_t i;
342 
343 	if (config->interface) {
344 		for (i = 0; i < config->bNumInterfaces; i++)
345 			clear_interface((struct libusb_interface *)
346 					config->interface + i);
347 	}
348 	free((void *)config->interface);
349 	free((void *)config->extra);
350 }
351 
parse_configuration(struct libusb_context * ctx,struct libusb_config_descriptor * config,const uint8_t * buffer,int size)352 static int parse_configuration(struct libusb_context *ctx,
353 	struct libusb_config_descriptor *config, const uint8_t *buffer, int size)
354 {
355 	uint8_t i;
356 	int r;
357 	const struct usbi_descriptor_header *header;
358 	struct libusb_interface *usb_interface;
359 
360 	if (size < LIBUSB_DT_CONFIG_SIZE) {
361 		usbi_err(ctx, "short config descriptor read %d/%d",
362 			 size, LIBUSB_DT_CONFIG_SIZE);
363 		return LIBUSB_ERROR_IO;
364 	}
365 
366 	parse_descriptor(buffer, "bbwbbbbb", config);
367 	if (config->bDescriptorType != LIBUSB_DT_CONFIG) {
368 		usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
369 			 config->bDescriptorType, LIBUSB_DT_CONFIG);
370 		return LIBUSB_ERROR_IO;
371 	} else if (config->bLength < LIBUSB_DT_CONFIG_SIZE) {
372 		usbi_err(ctx, "invalid config bLength (%u)", config->bLength);
373 		return LIBUSB_ERROR_IO;
374 	} else if (config->bLength > size) {
375 		usbi_err(ctx, "short config descriptor read %d/%u",
376 			 size, config->bLength);
377 		return LIBUSB_ERROR_IO;
378 	} else if (config->bNumInterfaces > USB_MAXINTERFACES) {
379 		usbi_err(ctx, "too many interfaces (%u)", config->bNumInterfaces);
380 		return LIBUSB_ERROR_IO;
381 	}
382 
383 	usb_interface = calloc(config->bNumInterfaces, sizeof(*usb_interface));
384 	if (!usb_interface)
385 		return LIBUSB_ERROR_NO_MEM;
386 
387 	config->interface = usb_interface;
388 
389 	buffer += config->bLength;
390 	size -= config->bLength;
391 
392 	for (i = 0; i < config->bNumInterfaces; i++) {
393 		int len;
394 		const uint8_t *begin;
395 
396 		/* Skip over the rest of the Class Specific or Vendor */
397 		/*  Specific descriptors */
398 		begin = buffer;
399 		while (size >= DESC_HEADER_LENGTH) {
400 			header = (const struct usbi_descriptor_header *)buffer;
401 			if (header->bLength < DESC_HEADER_LENGTH) {
402 				usbi_err(ctx,
403 					 "invalid extra config desc len (%u)",
404 					 header->bLength);
405 				r = LIBUSB_ERROR_IO;
406 				goto err;
407 			} else if (header->bLength > size) {
408 				usbi_warn(ctx,
409 					  "short extra config desc read %d/%u",
410 					  size, header->bLength);
411 				config->bNumInterfaces = i;
412 				return size;
413 			}
414 
415 			/* If we find another "proper" descriptor then we're done */
416 			if (header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
417 			    header->bDescriptorType == LIBUSB_DT_INTERFACE ||
418 			    header->bDescriptorType == LIBUSB_DT_CONFIG ||
419 			    header->bDescriptorType == LIBUSB_DT_DEVICE)
420 				break;
421 
422 			usbi_dbg(ctx, "skipping descriptor 0x%x", header->bDescriptorType);
423 			buffer += header->bLength;
424 			size -= header->bLength;
425 		}
426 
427 		/* Copy any unknown descriptors into a storage area for */
428 		/*  drivers to later parse */
429 		len = (int)(buffer - begin);
430 		if (len > 0) {
431 			uint8_t *extra = realloc((void *)config->extra,
432 						 (size_t)(config->extra_length + len));
433 
434 			if (!extra) {
435 				r = LIBUSB_ERROR_NO_MEM;
436 				goto err;
437 			}
438 
439 			memcpy(extra + config->extra_length, begin, (size_t)len);
440 			config->extra = extra;
441 			config->extra_length += len;
442 		}
443 
444 		r = parse_interface(ctx, usb_interface + i, buffer, size);
445 		if (r < 0)
446 			goto err;
447 		if (r == 0) {
448 			config->bNumInterfaces = i;
449 			break;
450 		}
451 
452 		buffer += r;
453 		size -= r;
454 	}
455 
456 	return size;
457 
458 err:
459 	clear_configuration(config);
460 	return r;
461 }
462 
raw_desc_to_config(struct libusb_context * ctx,const uint8_t * buf,int size,struct libusb_config_descriptor ** config)463 static int raw_desc_to_config(struct libusb_context *ctx,
464 	const uint8_t *buf, int size, struct libusb_config_descriptor **config)
465 {
466 	struct libusb_config_descriptor *_config = calloc(1, sizeof(*_config));
467 	int r;
468 
469 	if (!_config)
470 		return LIBUSB_ERROR_NO_MEM;
471 
472 	r = parse_configuration(ctx, _config, buf, size);
473 	if (r < 0) {
474 		usbi_err(ctx, "parse_configuration failed with error %d", r);
475 		free(_config);
476 		return r;
477 	} else if (r > 0) {
478 		usbi_warn(ctx, "still %d bytes of descriptor data left", r);
479 	}
480 
481 	*config = _config;
482 	return LIBUSB_SUCCESS;
483 }
484 
get_active_config_descriptor(struct libusb_device * dev,uint8_t * buffer,size_t size)485 static int get_active_config_descriptor(struct libusb_device *dev,
486 	uint8_t *buffer, size_t size)
487 {
488 	int r = usbi_backend.get_active_config_descriptor(dev, buffer, size);
489 
490 	if (r < 0)
491 		return r;
492 
493 	if (r < LIBUSB_DT_CONFIG_SIZE) {
494 		usbi_err(DEVICE_CTX(dev), "short config descriptor read %d/%d",
495 			 r, LIBUSB_DT_CONFIG_SIZE);
496 		return LIBUSB_ERROR_IO;
497 	} else if (r != (int)size) {
498 		usbi_warn(DEVICE_CTX(dev), "short config descriptor read %d/%d",
499 			 r, (int)size);
500 	}
501 
502 	return r;
503 }
504 
get_config_descriptor(struct libusb_device * dev,uint8_t config_idx,uint8_t * buffer,size_t size)505 static int get_config_descriptor(struct libusb_device *dev, uint8_t config_idx,
506 	uint8_t *buffer, size_t size)
507 {
508 	int r = usbi_backend.get_config_descriptor(dev, config_idx, buffer, size);
509 
510 	if (r < 0)
511 		return r;
512 	if (r < LIBUSB_DT_CONFIG_SIZE) {
513 		usbi_err(DEVICE_CTX(dev), "short config descriptor read %d/%d",
514 			 r, LIBUSB_DT_CONFIG_SIZE);
515 		return LIBUSB_ERROR_IO;
516 	} else if (r != (int)size) {
517 		usbi_warn(DEVICE_CTX(dev), "short config descriptor read %d/%d",
518 			 r, (int)size);
519 	}
520 
521 	return r;
522 }
523 
524 /** \ingroup libusb_desc
525  * Get the USB device descriptor for a given device.
526  *
527  * This is a non-blocking function; the device descriptor is cached in memory.
528  *
529  * Note since libusb-1.0.16, \ref LIBUSBX_API_VERSION >= 0x01000102, this
530  * function always succeeds.
531  *
532  * \param dev the device
533  * \param desc output location for the descriptor data
534  * \returns 0 on success or a LIBUSB_ERROR code on failure
535  */
libusb_get_device_descriptor(libusb_device * dev,struct libusb_device_descriptor * desc)536 int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
537 	struct libusb_device_descriptor *desc)
538 {
539 	usbi_dbg(DEVICE_CTX(dev), " ");
540 	static_assert(sizeof(dev->device_descriptor) == LIBUSB_DT_DEVICE_SIZE,
541 		      "struct libusb_device_descriptor is not expected size");
542 	*desc = dev->device_descriptor;
543 	return 0;
544 }
545 
546 /** \ingroup libusb_desc
547  * Get the USB configuration descriptor for the currently active configuration.
548  * This is a non-blocking function which does not involve any requests being
549  * sent to the device.
550  *
551  * \param dev a device
552  * \param config output location for the USB configuration descriptor. Only
553  * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
554  * after use.
555  * \returns 0 on success
556  * \returns \ref LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
557  * \returns another LIBUSB_ERROR code on error
558  * \see libusb_get_config_descriptor
559  */
libusb_get_active_config_descriptor(libusb_device * dev,struct libusb_config_descriptor ** config)560 int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
561 	struct libusb_config_descriptor **config)
562 {
563 	union usbi_config_desc_buf _config;
564 	uint16_t config_len;
565 	uint8_t *buf;
566 	int r;
567 
568 	r = get_active_config_descriptor(dev, _config.buf, sizeof(_config.buf));
569 	if (r < 0)
570 		return r;
571 
572 	config_len = libusb_le16_to_cpu(_config.desc.wTotalLength);
573 	buf = malloc(config_len);
574 	if (!buf)
575 		return LIBUSB_ERROR_NO_MEM;
576 
577 	r = get_active_config_descriptor(dev, buf, config_len);
578 	if (r >= 0)
579 		r = raw_desc_to_config(DEVICE_CTX(dev), buf, r, config);
580 
581 	free(buf);
582 	return r;
583 }
584 
585 /** \ingroup libusb_desc
586  * Get a USB configuration descriptor based on its index.
587  * This is a non-blocking function which does not involve any requests being
588  * sent to the device.
589  *
590  * \param dev a device
591  * \param config_index the index of the configuration you wish to retrieve
592  * \param config output location for the USB configuration descriptor. Only
593  * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
594  * after use.
595  * \returns 0 on success
596  * \returns \ref LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
597  * \returns another LIBUSB_ERROR code on error
598  * \see libusb_get_active_config_descriptor()
599  * \see libusb_get_config_descriptor_by_value()
600  */
libusb_get_config_descriptor(libusb_device * dev,uint8_t config_index,struct libusb_config_descriptor ** config)601 int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
602 	uint8_t config_index, struct libusb_config_descriptor **config)
603 {
604 	union usbi_config_desc_buf _config;
605 	uint16_t config_len;
606 	uint8_t *buf;
607 	int r;
608 
609 	usbi_dbg(DEVICE_CTX(dev), "index %u", config_index);
610 	if (config_index >= dev->device_descriptor.bNumConfigurations)
611 		return LIBUSB_ERROR_NOT_FOUND;
612 
613 	r = get_config_descriptor(dev, config_index, _config.buf, sizeof(_config.buf));
614 	if (r < 0)
615 		return r;
616 
617 	config_len = libusb_le16_to_cpu(_config.desc.wTotalLength);
618 	buf = malloc(config_len);
619 	if (!buf)
620 		return LIBUSB_ERROR_NO_MEM;
621 
622 	r = get_config_descriptor(dev, config_index, buf, config_len);
623 	if (r >= 0)
624 		r = raw_desc_to_config(DEVICE_CTX(dev), buf, r, config);
625 
626 	free(buf);
627 	return r;
628 }
629 
630 /** \ingroup libusb_desc
631  * Get a USB configuration descriptor with a specific bConfigurationValue.
632  * This is a non-blocking function which does not involve any requests being
633  * sent to the device.
634  *
635  * \param dev a device
636  * \param bConfigurationValue the bConfigurationValue of the configuration you
637  * wish to retrieve
638  * \param config output location for the USB configuration descriptor. Only
639  * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
640  * after use.
641  * \returns 0 on success
642  * \returns \ref LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
643  * \returns another LIBUSB_ERROR code on error
644  * \see libusb_get_active_config_descriptor()
645  * \see libusb_get_config_descriptor()
646  */
libusb_get_config_descriptor_by_value(libusb_device * dev,uint8_t bConfigurationValue,struct libusb_config_descriptor ** config)647 int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
648 	uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
649 {
650 	uint8_t idx;
651 	int r;
652 
653 	if (usbi_backend.get_config_descriptor_by_value) {
654 		void *buf;
655 
656 		r = usbi_backend.get_config_descriptor_by_value(dev,
657 			bConfigurationValue, &buf);
658 		if (r < 0)
659 			return r;
660 
661 		return raw_desc_to_config(DEVICE_CTX(dev), buf, r, config);
662 	}
663 
664 	usbi_dbg(DEVICE_CTX(dev), "value %u", bConfigurationValue);
665 	for (idx = 0; idx < dev->device_descriptor.bNumConfigurations; idx++) {
666 		union usbi_config_desc_buf _config;
667 
668 		r = get_config_descriptor(dev, idx, _config.buf, sizeof(_config.buf));
669 		if (r < 0)
670 			return r;
671 
672 		if (_config.desc.bConfigurationValue == bConfigurationValue)
673 			return libusb_get_config_descriptor(dev, idx, config);
674 	}
675 
676 	return LIBUSB_ERROR_NOT_FOUND;
677 }
678 
679 /** \ingroup libusb_desc
680  * Free a configuration descriptor obtained from
681  * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
682  * It is safe to call this function with a NULL config parameter, in which
683  * case the function simply returns.
684  *
685  * \param config the configuration descriptor to free
686  */
libusb_free_config_descriptor(struct libusb_config_descriptor * config)687 void API_EXPORTED libusb_free_config_descriptor(
688 	struct libusb_config_descriptor *config)
689 {
690 	if (!config)
691 		return;
692 
693 	clear_configuration(config);
694 	free(config);
695 }
696 
697 /** \ingroup libusb_desc
698  * Get an endpoints superspeed endpoint companion descriptor (if any)
699  *
700  * \param ctx the context to operate on, or NULL for the default context
701  * \param endpoint endpoint descriptor from which to get the superspeed
702  * endpoint companion descriptor
703  * \param ep_comp output location for the superspeed endpoint companion
704  * descriptor. Only valid if 0 was returned. Must be freed with
705  * libusb_free_ss_endpoint_companion_descriptor() after use.
706  * \returns 0 on success
707  * \returns \ref LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
708  * \returns another LIBUSB_ERROR code on error
709  */
libusb_get_ss_endpoint_companion_descriptor(libusb_context * ctx,const struct libusb_endpoint_descriptor * endpoint,struct libusb_ss_endpoint_companion_descriptor ** ep_comp)710 int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor(
711 	libusb_context *ctx,
712 	const struct libusb_endpoint_descriptor *endpoint,
713 	struct libusb_ss_endpoint_companion_descriptor **ep_comp)
714 {
715 	struct usbi_descriptor_header *header;
716 	const uint8_t *buffer = endpoint->extra;
717 	int size = endpoint->extra_length;
718 
719 	*ep_comp = NULL;
720 
721 	while (size >= DESC_HEADER_LENGTH) {
722 		header = (struct usbi_descriptor_header *)buffer;
723 		if (header->bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) {
724 			if (header->bLength < DESC_HEADER_LENGTH) {
725 				usbi_err(ctx, "invalid descriptor length %u",
726 					 header->bLength);
727 				return LIBUSB_ERROR_IO;
728 			}
729 			buffer += header->bLength;
730 			size -= header->bLength;
731 			continue;
732 		} else if (header->bLength < LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE) {
733 			usbi_err(ctx, "invalid ss-ep-comp-desc length %u",
734 				 header->bLength);
735 			return LIBUSB_ERROR_IO;
736 		} else if (header->bLength > size) {
737 			usbi_err(ctx, "short ss-ep-comp-desc read %d/%u",
738 				 size, header->bLength);
739 			return LIBUSB_ERROR_IO;
740 		}
741 
742 		*ep_comp = malloc(sizeof(**ep_comp));
743 		if (!*ep_comp)
744 			return LIBUSB_ERROR_NO_MEM;
745 		parse_descriptor(buffer, "bbbbw", *ep_comp);
746 		return LIBUSB_SUCCESS;
747 	}
748 	return LIBUSB_ERROR_NOT_FOUND;
749 }
750 
751 /** \ingroup libusb_desc
752  * Free a superspeed endpoint companion descriptor obtained from
753  * libusb_get_ss_endpoint_companion_descriptor().
754  * It is safe to call this function with a NULL ep_comp parameter, in which
755  * case the function simply returns.
756  *
757  * \param ep_comp the superspeed endpoint companion descriptor to free
758  */
libusb_free_ss_endpoint_companion_descriptor(struct libusb_ss_endpoint_companion_descriptor * ep_comp)759 void API_EXPORTED libusb_free_ss_endpoint_companion_descriptor(
760 	struct libusb_ss_endpoint_companion_descriptor *ep_comp)
761 {
762 	free(ep_comp);
763 }
764 
parse_bos(struct libusb_context * ctx,struct libusb_bos_descriptor ** bos,const uint8_t * buffer,int size)765 static int parse_bos(struct libusb_context *ctx,
766 	struct libusb_bos_descriptor **bos,
767 	const uint8_t *buffer, int size)
768 {
769 	struct libusb_bos_descriptor *_bos;
770 	const struct usbi_bos_descriptor *bos_desc;
771 	const struct usbi_descriptor_header *header;
772 	uint8_t i;
773 
774 	if (size < LIBUSB_DT_BOS_SIZE) {
775 		usbi_err(ctx, "short bos descriptor read %d/%d",
776 			 size, LIBUSB_DT_BOS_SIZE);
777 		return LIBUSB_ERROR_IO;
778 	}
779 
780 	bos_desc = (const struct usbi_bos_descriptor *)buffer;
781 	if (bos_desc->bDescriptorType != LIBUSB_DT_BOS) {
782 		usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
783 			 bos_desc->bDescriptorType, LIBUSB_DT_BOS);
784 		return LIBUSB_ERROR_IO;
785 	} else if (bos_desc->bLength < LIBUSB_DT_BOS_SIZE) {
786 		usbi_err(ctx, "invalid bos bLength (%u)", bos_desc->bLength);
787 		return LIBUSB_ERROR_IO;
788 	} else if (bos_desc->bLength > size) {
789 		usbi_err(ctx, "short bos descriptor read %d/%u",
790 			 size, bos_desc->bLength);
791 		return LIBUSB_ERROR_IO;
792 	}
793 
794 	_bos = calloc(1, sizeof(*_bos) + bos_desc->bNumDeviceCaps * sizeof(void *));
795 	if (!_bos)
796 		return LIBUSB_ERROR_NO_MEM;
797 
798 	parse_descriptor(buffer, "bbwb", _bos);
799 	buffer += _bos->bLength;
800 	size -= _bos->bLength;
801 
802 	/* Get the device capability descriptors */
803 	for (i = 0; i < _bos->bNumDeviceCaps; i++) {
804 		if (size < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
805 			usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
806 				  size, LIBUSB_DT_DEVICE_CAPABILITY_SIZE);
807 			break;
808 		}
809 		header = (const struct usbi_descriptor_header *)buffer;
810 		if (header->bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) {
811 			usbi_warn(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
812 				  header->bDescriptorType, LIBUSB_DT_DEVICE_CAPABILITY);
813 			break;
814 		} else if (header->bLength < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
815 			usbi_err(ctx, "invalid dev-cap bLength (%u)",
816 				 header->bLength);
817 			libusb_free_bos_descriptor(_bos);
818 			return LIBUSB_ERROR_IO;
819 		} else if (header->bLength > size) {
820 			usbi_warn(ctx, "short dev-cap descriptor read %d/%u",
821 				  size, header->bLength);
822 			break;
823 		}
824 
825 		_bos->dev_capability[i] = malloc(header->bLength);
826 		if (!_bos->dev_capability[i]) {
827 			libusb_free_bos_descriptor(_bos);
828 			return LIBUSB_ERROR_NO_MEM;
829 		}
830 		memcpy(_bos->dev_capability[i], buffer, header->bLength);
831 		buffer += header->bLength;
832 		size -= header->bLength;
833 	}
834 	_bos->bNumDeviceCaps = i;
835 	*bos = _bos;
836 
837 	return LIBUSB_SUCCESS;
838 }
839 
840 /** \ingroup libusb_desc
841  * Get a Binary Object Store (BOS) descriptor
842  * This is a BLOCKING function, which will send requests to the device.
843  *
844  * \param dev_handle the handle of an open libusb device
845  * \param bos output location for the BOS descriptor. Only valid if 0 was returned.
846  * Must be freed with \ref libusb_free_bos_descriptor() after use.
847  * \returns 0 on success
848  * \returns \ref LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor
849  * \returns another LIBUSB_ERROR code on error
850  */
libusb_get_bos_descriptor(libusb_device_handle * dev_handle,struct libusb_bos_descriptor ** bos)851 int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *dev_handle,
852 	struct libusb_bos_descriptor **bos)
853 {
854 	union usbi_bos_desc_buf _bos;
855 	uint16_t bos_len;
856 	uint8_t *bos_data;
857 	int r;
858 	struct libusb_context *ctx = HANDLE_CTX(dev_handle);
859 
860 	/* Read the BOS. This generates 2 requests on the bus,
861 	 * one for the header, and one for the full BOS */
862 	r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, _bos.buf, sizeof(_bos.buf));
863 	if (r < 0) {
864 		if (r != LIBUSB_ERROR_PIPE)
865 			usbi_err(ctx, "failed to read BOS (%d)", r);
866 		return r;
867 	}
868 	if (r < LIBUSB_DT_BOS_SIZE) {
869 		usbi_err(ctx, "short BOS read %d/%d",
870 			 r, LIBUSB_DT_BOS_SIZE);
871 		return LIBUSB_ERROR_IO;
872 	}
873 
874 	bos_len = libusb_le16_to_cpu(_bos.desc.wTotalLength);
875 	usbi_dbg(ctx, "found BOS descriptor: size %u bytes, %u capabilities",
876 		 bos_len, _bos.desc.bNumDeviceCaps);
877 	bos_data = calloc(1, bos_len);
878 	if (!bos_data)
879 		return LIBUSB_ERROR_NO_MEM;
880 
881 	r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_data, bos_len);
882 	if (r >= 0) {
883 		if (r != (int)bos_len)
884 			usbi_warn(ctx, "short BOS read %d/%u", r, bos_len);
885 		r = parse_bos(HANDLE_CTX(dev_handle), bos, bos_data, r);
886 	} else {
887 		usbi_err(ctx, "failed to read BOS (%d)", r);
888 	}
889 
890 	free(bos_data);
891 	return r;
892 }
893 
894 /** \ingroup libusb_desc
895  * Free a BOS descriptor obtained from libusb_get_bos_descriptor().
896  * It is safe to call this function with a NULL bos parameter, in which
897  * case the function simply returns.
898  *
899  * \param bos the BOS descriptor to free
900  */
libusb_free_bos_descriptor(struct libusb_bos_descriptor * bos)901 void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
902 {
903 	uint8_t i;
904 
905 	if (!bos)
906 		return;
907 
908 	for (i = 0; i < bos->bNumDeviceCaps; i++)
909 		free(bos->dev_capability[i]);
910 	free(bos);
911 }
912 
913 /** \ingroup libusb_desc
914  * Get an USB 2.0 Extension descriptor
915  *
916  * \param ctx the context to operate on, or NULL for the default context
917  * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
918  * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION
919  * LIBUSB_BT_USB_2_0_EXTENSION
920  * \param usb_2_0_extension output location for the USB 2.0 Extension
921  * descriptor. Only valid if 0 was returned. Must be freed with
922  * libusb_free_usb_2_0_extension_descriptor() after use.
923  * \returns 0 on success
924  * \returns a LIBUSB_ERROR code on error
925  */
libusb_get_usb_2_0_extension_descriptor(libusb_context * ctx,struct libusb_bos_dev_capability_descriptor * dev_cap,struct libusb_usb_2_0_extension_descriptor ** usb_2_0_extension)926 int API_EXPORTED libusb_get_usb_2_0_extension_descriptor(
927 	libusb_context *ctx,
928 	struct libusb_bos_dev_capability_descriptor *dev_cap,
929 	struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)
930 {
931 	struct libusb_usb_2_0_extension_descriptor *_usb_2_0_extension;
932 
933 	if (dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) {
934 		usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
935 			 dev_cap->bDevCapabilityType,
936 			 LIBUSB_BT_USB_2_0_EXTENSION);
937 		return LIBUSB_ERROR_INVALID_PARAM;
938 	} else if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) {
939 		usbi_err(ctx, "short dev-cap descriptor read %u/%d",
940 			 dev_cap->bLength, LIBUSB_BT_USB_2_0_EXTENSION_SIZE);
941 		return LIBUSB_ERROR_IO;
942 	}
943 
944 	_usb_2_0_extension = malloc(sizeof(*_usb_2_0_extension));
945 	if (!_usb_2_0_extension)
946 		return LIBUSB_ERROR_NO_MEM;
947 
948 	parse_descriptor(dev_cap, "bbbd", _usb_2_0_extension);
949 
950 	*usb_2_0_extension = _usb_2_0_extension;
951 	return LIBUSB_SUCCESS;
952 }
953 
954 /** \ingroup libusb_desc
955  * Free a USB 2.0 Extension descriptor obtained from
956  * libusb_get_usb_2_0_extension_descriptor().
957  * It is safe to call this function with a NULL usb_2_0_extension parameter,
958  * in which case the function simply returns.
959  *
960  * \param usb_2_0_extension the USB 2.0 Extension descriptor to free
961  */
libusb_free_usb_2_0_extension_descriptor(struct libusb_usb_2_0_extension_descriptor * usb_2_0_extension)962 void API_EXPORTED libusb_free_usb_2_0_extension_descriptor(
963 	struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
964 {
965 	free(usb_2_0_extension);
966 }
967 
968 /** \ingroup libusb_desc
969  * Get a SuperSpeed USB Device Capability descriptor
970  *
971  * \param ctx the context to operate on, or NULL for the default context
972  * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
973  * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
974  * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
975  * \param ss_usb_device_cap output location for the SuperSpeed USB Device
976  * Capability descriptor. Only valid if 0 was returned. Must be freed with
977  * libusb_free_ss_usb_device_capability_descriptor() after use.
978  * \returns 0 on success
979  * \returns a LIBUSB_ERROR code on error
980  */
libusb_get_ss_usb_device_capability_descriptor(libusb_context * ctx,struct libusb_bos_dev_capability_descriptor * dev_cap,struct libusb_ss_usb_device_capability_descriptor ** ss_usb_device_cap)981 int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor(
982 	libusb_context *ctx,
983 	struct libusb_bos_dev_capability_descriptor *dev_cap,
984 	struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap)
985 {
986 	struct libusb_ss_usb_device_capability_descriptor *_ss_usb_device_cap;
987 
988 	if (dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {
989 		usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
990 			 dev_cap->bDevCapabilityType,
991 			 LIBUSB_BT_SS_USB_DEVICE_CAPABILITY);
992 		return LIBUSB_ERROR_INVALID_PARAM;
993 	} else if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) {
994 		usbi_err(ctx, "short dev-cap descriptor read %u/%d",
995 			 dev_cap->bLength, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE);
996 		return LIBUSB_ERROR_IO;
997 	}
998 
999 	_ss_usb_device_cap = malloc(sizeof(*_ss_usb_device_cap));
1000 	if (!_ss_usb_device_cap)
1001 		return LIBUSB_ERROR_NO_MEM;
1002 
1003 	parse_descriptor(dev_cap, "bbbbwbbw", _ss_usb_device_cap);
1004 
1005 	*ss_usb_device_cap = _ss_usb_device_cap;
1006 	return LIBUSB_SUCCESS;
1007 }
1008 
1009 /* We use this private struct only to parse a SuperSpeedPlus device capability
1010    descriptor according to section 9.6.2.5 of the USB 3.1 specification.
1011    We don't expose it. */
1012 struct internal_ssplus_capability_descriptor {
1013 	uint8_t  bLength;
1014 	uint8_t  bDescriptorType;
1015 	uint8_t  bDevCapabilityType;
1016 	uint8_t  bReserved;
1017 	uint32_t bmAttributes;
1018 	uint16_t wFunctionalitySupport;
1019 	uint16_t wReserved;
1020 };
1021 
libusb_get_ssplus_usb_device_capability_descriptor(libusb_context * ctx,struct libusb_bos_dev_capability_descriptor * dev_cap,struct libusb_ssplus_usb_device_capability_descriptor ** ssplus_usb_device_cap)1022 int API_EXPORTED libusb_get_ssplus_usb_device_capability_descriptor(
1023 	libusb_context *ctx,
1024 	struct libusb_bos_dev_capability_descriptor *dev_cap,
1025 	struct libusb_ssplus_usb_device_capability_descriptor **ssplus_usb_device_cap)
1026 {
1027 	struct libusb_ssplus_usb_device_capability_descriptor *_ssplus_cap;
1028 
1029 	/* Use a private struct to reuse our descriptor parsing system. */
1030 	struct internal_ssplus_capability_descriptor parsedDescriptor;
1031 
1032 	/* Some size/type checks to make sure everything is in order */
1033 	if (dev_cap->bDevCapabilityType != LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY) {
1034 		usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
1035 			 dev_cap->bDevCapabilityType,
1036 				 LIBUSB_BT_SUPERSPEED_PLUS_CAPABILITY);
1037 		return LIBUSB_ERROR_INVALID_PARAM;
1038 	} else if (dev_cap->bLength < LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE) {
1039 		usbi_err(ctx, "short dev-cap descriptor read %u/%d",
1040 			 dev_cap->bLength, LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE);
1041 		return LIBUSB_ERROR_IO;
1042 	}
1043 
1044 	/* We can only parse the non-variable size part of the SuperSpeedPlus descriptor. The attributes have to be read "manually". */
1045 	parse_descriptor(dev_cap, "bbbbiww", &parsedDescriptor);
1046 
1047 	uint8_t numSublikSpeedAttributes = (parsedDescriptor.bmAttributes & 0xF) + 1;
1048 	_ssplus_cap = malloc(sizeof(struct libusb_ssplus_usb_device_capability_descriptor) + numSublikSpeedAttributes * sizeof(struct libusb_ssplus_sublink_attribute));
1049 	if (!_ssplus_cap)
1050 		return LIBUSB_ERROR_NO_MEM;
1051 
1052 	/* Parse bmAttributes */
1053 	_ssplus_cap->numSublinkSpeedAttributes = numSublikSpeedAttributes;
1054 	_ssplus_cap->numSublinkSpeedIDs = ((parsedDescriptor.bmAttributes & 0xF0) >> 4) + 1;
1055 
1056 	/* Parse wFunctionalitySupport */
1057 	_ssplus_cap->ssid = parsedDescriptor.wFunctionalitySupport & 0xF;
1058 	_ssplus_cap->minRxLaneCount = (parsedDescriptor.wFunctionalitySupport & 0x0F00) >> 8;
1059 	_ssplus_cap->minTxLaneCount = (parsedDescriptor.wFunctionalitySupport & 0xF000) >> 12;
1060 
1061 	/* Check that we have enough to read all the sublink attributes */
1062 	if (dev_cap->bLength < LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE + _ssplus_cap->numSublinkSpeedAttributes * sizeof(uint32_t)) {
1063 		usbi_err(ctx, "short ssplus capability descriptor, unable to read sublinks: Not enough data");
1064 		return LIBUSB_ERROR_IO;
1065 	}
1066 
1067 	/* Read the attributes */
1068 	uint8_t* base = ((uint8_t*)dev_cap) + LIBUSB_BT_SSPLUS_USB_DEVICE_CAPABILITY_SIZE;
1069 	for(uint8_t i = 0 ; i < _ssplus_cap->numSublinkSpeedAttributes ; i++) {
1070 		uint32_t attr = READ_LE32(base + i * sizeof(uint32_t));
1071 		_ssplus_cap->sublinkSpeedAttributes[i].ssid = attr & 0x0f;
1072 		_ssplus_cap->sublinkSpeedAttributes[i].mantissa = attr >> 16;
1073 		_ssplus_cap->sublinkSpeedAttributes[i].exponent = (attr >> 4) & 0x3 ;
1074 		_ssplus_cap->sublinkSpeedAttributes[i].type = attr & 0x40 ? 	LIBUSB_SSPLUS_ATTR_TYPE_ASYM : LIBUSB_SSPLUS_ATTR_TYPE_SYM;
1075 		_ssplus_cap->sublinkSpeedAttributes[i].direction = attr & 0x80 ? 	LIBUSB_SSPLUS_ATTR_DIR_TX : 	LIBUSB_SSPLUS_ATTR_DIR_RX;
1076 		_ssplus_cap->sublinkSpeedAttributes[i].protocol = attr & 0x4000 ? LIBUSB_SSPLUS_ATTR_PROT_SSPLUS: LIBUSB_SSPLUS_ATTR_PROT_SS;
1077 	}
1078 
1079 	*ssplus_usb_device_cap = _ssplus_cap;
1080 	return LIBUSB_SUCCESS;
1081 }
1082 
libusb_free_ssplus_usb_device_capability_descriptor(struct libusb_ssplus_usb_device_capability_descriptor * ssplus_usb_device_cap)1083 void API_EXPORTED libusb_free_ssplus_usb_device_capability_descriptor(
1084 	struct libusb_ssplus_usb_device_capability_descriptor *ssplus_usb_device_cap)
1085 {
1086 	free(ssplus_usb_device_cap);
1087 }
1088 
1089 
1090 
1091 /** \ingroup libusb_desc
1092  * Free a SuperSpeed USB Device Capability descriptor obtained from
1093  * libusb_get_ss_usb_device_capability_descriptor().
1094  * It is safe to call this function with a NULL ss_usb_device_cap
1095  * parameter, in which case the function simply returns.
1096  *
1097  * \param ss_usb_device_cap the SuperSpeed USB Device Capability descriptor
1098  * to free
1099  */
libusb_free_ss_usb_device_capability_descriptor(struct libusb_ss_usb_device_capability_descriptor * ss_usb_device_cap)1100 void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor(
1101 	struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap)
1102 {
1103 	free(ss_usb_device_cap);
1104 }
1105 
1106 /** \ingroup libusb_desc
1107  * Get a Container ID descriptor
1108  *
1109  * \param ctx the context to operate on, or NULL for the default context
1110  * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1111  * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID
1112  * LIBUSB_BT_CONTAINER_ID
1113  * \param container_id output location for the Container ID descriptor.
1114  * Only valid if 0 was returned. Must be freed with
1115  * libusb_free_container_id_descriptor() after use.
1116  * \returns 0 on success
1117  * \returns a LIBUSB_ERROR code on error
1118  */
libusb_get_container_id_descriptor(libusb_context * ctx,struct libusb_bos_dev_capability_descriptor * dev_cap,struct libusb_container_id_descriptor ** container_id)1119 int API_EXPORTED libusb_get_container_id_descriptor(libusb_context *ctx,
1120 	struct libusb_bos_dev_capability_descriptor *dev_cap,
1121 	struct libusb_container_id_descriptor **container_id)
1122 {
1123 	struct libusb_container_id_descriptor *_container_id;
1124 
1125 	if (dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) {
1126 		usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
1127 			 dev_cap->bDevCapabilityType,
1128 			 LIBUSB_BT_CONTAINER_ID);
1129 		return LIBUSB_ERROR_INVALID_PARAM;
1130 	} else if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) {
1131 		usbi_err(ctx, "short dev-cap descriptor read %u/%d",
1132 			 dev_cap->bLength, LIBUSB_BT_CONTAINER_ID_SIZE);
1133 		return LIBUSB_ERROR_IO;
1134 	}
1135 
1136 	_container_id = malloc(sizeof(*_container_id));
1137 	if (!_container_id)
1138 		return LIBUSB_ERROR_NO_MEM;
1139 
1140 	parse_descriptor(dev_cap, "bbbbu", _container_id);
1141 
1142 	*container_id = _container_id;
1143 	return LIBUSB_SUCCESS;
1144 }
1145 
1146 /** \ingroup libusb_desc
1147  * Free a Container ID descriptor obtained from
1148  * libusb_get_container_id_descriptor().
1149  * It is safe to call this function with a NULL container_id parameter,
1150  * in which case the function simply returns.
1151  *
1152  * \param container_id the Container ID descriptor to free
1153  */
libusb_free_container_id_descriptor(struct libusb_container_id_descriptor * container_id)1154 void API_EXPORTED libusb_free_container_id_descriptor(
1155 	struct libusb_container_id_descriptor *container_id)
1156 {
1157 	free(container_id);
1158 }
1159 
1160 /** \ingroup libusb_desc
1161  * Get a platform descriptor
1162  *
1163  * Since version 1.0.27, \ref LIBUSB_API_VERSION >= 0x0100010A
1164  *
1165  * \param ctx the context to operate on, or NULL for the default context
1166  * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1167  * \ref libusb_capability_type::LIBUSB_BT_PLATFORM_DESCRIPTOR
1168  * LIBUSB_BT_PLATFORM_DESCRIPTOR
1169  * \param platform_descriptor output location for the Platform descriptor.
1170  * Only valid if 0 was returned. Must be freed with
1171  * libusb_free_platform_descriptor() after use.
1172  * \returns 0 on success
1173  * \returns a LIBUSB_ERROR code on error
1174  */
libusb_get_platform_descriptor(libusb_context * ctx,struct libusb_bos_dev_capability_descriptor * dev_cap,struct libusb_platform_descriptor ** platform_descriptor)1175 int API_EXPORTED libusb_get_platform_descriptor(libusb_context *ctx,
1176 	struct libusb_bos_dev_capability_descriptor *dev_cap,
1177 	struct libusb_platform_descriptor **platform_descriptor)
1178 {
1179 	struct libusb_platform_descriptor *_platform_descriptor;
1180 
1181 	if (dev_cap->bDevCapabilityType != LIBUSB_BT_PLATFORM_DESCRIPTOR) {
1182 		usbi_err(ctx, "unexpected bDevCapabilityType 0x%x (expected 0x%x)",
1183 			 dev_cap->bDevCapabilityType,
1184 			 LIBUSB_BT_PLATFORM_DESCRIPTOR);
1185 		return LIBUSB_ERROR_INVALID_PARAM;
1186 	} else if (dev_cap->bLength < LIBUSB_BT_PLATFORM_DESCRIPTOR_MIN_SIZE) {
1187 		usbi_err(ctx, "short dev-cap descriptor read %u/%d",
1188 			 dev_cap->bLength, LIBUSB_BT_PLATFORM_DESCRIPTOR_MIN_SIZE);
1189 		return LIBUSB_ERROR_IO;
1190 	}
1191 
1192 	_platform_descriptor = malloc(dev_cap->bLength);
1193 	if (!_platform_descriptor)
1194 		return LIBUSB_ERROR_NO_MEM;
1195 
1196 	parse_descriptor(dev_cap, "bbbbu", _platform_descriptor);
1197 
1198 	/* Capability data is located after reserved byte and 128-bit UUID */
1199 	uint8_t* capability_data = dev_cap->dev_capability_data + 1 + 16;
1200 
1201 	/* Capability data length is total descriptor length minus initial fields */
1202 	size_t capability_data_length = _platform_descriptor->bLength - (16 + 4);
1203 
1204 	memcpy(_platform_descriptor->CapabilityData, capability_data, capability_data_length);
1205 
1206 	*platform_descriptor = _platform_descriptor;
1207 	return LIBUSB_SUCCESS;
1208 }
1209 
1210 /** \ingroup libusb_desc
1211  * Free a platform descriptor obtained from
1212  * libusb_get_platform_descriptor().
1213  * It is safe to call this function with a NULL platform_descriptor parameter,
1214  * in which case the function simply returns.
1215  *
1216  * \param platform_descriptor the Platform descriptor to free
1217  */
libusb_free_platform_descriptor(struct libusb_platform_descriptor * platform_descriptor)1218 void API_EXPORTED libusb_free_platform_descriptor(
1219 	struct libusb_platform_descriptor *platform_descriptor)
1220 {
1221 	free(platform_descriptor);
1222 }
1223 
1224 /** \ingroup libusb_desc
1225  * Retrieve a string descriptor in C style ASCII.
1226  *
1227  * Wrapper around libusb_get_string_descriptor(). Uses the first language
1228  * supported by the device.
1229  *
1230  * \param dev_handle a device handle
1231  * \param desc_index the index of the descriptor to retrieve
1232  * \param data output buffer for ASCII string descriptor
1233  * \param length size of data buffer
1234  * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
1235  */
libusb_get_string_descriptor_ascii(libusb_device_handle * dev_handle,uint8_t desc_index,unsigned char * data,int length)1236 int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle,
1237 	uint8_t desc_index, unsigned char *data, int length)
1238 {
1239 	union usbi_string_desc_buf str;
1240 	int r;
1241 	uint16_t langid, wdata;
1242 
1243 	/* Asking for the zero'th index is special - it returns a string
1244 	 * descriptor that contains all the language IDs supported by the
1245 	 * device. Typically there aren't many - often only one. Language
1246 	 * IDs are 16 bit numbers, and they start at the third byte in the
1247 	 * descriptor. There's also no point in trying to read descriptor 0
1248 	 * with this function. See USB 2.0 specification section 9.6.7 for
1249 	 * more information.
1250 	 */
1251 
1252 	if (desc_index == 0)
1253 		return LIBUSB_ERROR_INVALID_PARAM;
1254 
1255 	r = libusb_get_string_descriptor(dev_handle, 0, 0, str.buf, 4);
1256 	if (r < 0)
1257 		return r;
1258 	else if (r != 4 || str.desc.bLength < 4)
1259 		return LIBUSB_ERROR_IO;
1260 	else if (str.desc.bDescriptorType != LIBUSB_DT_STRING)
1261 		return LIBUSB_ERROR_IO;
1262 	else if (str.desc.bLength & 1)
1263 		usbi_warn(HANDLE_CTX(dev_handle), "suspicious bLength %u for language ID string descriptor", str.desc.bLength);
1264 
1265 	langid = libusb_le16_to_cpu(str.desc.wData[0]);
1266 	r = libusb_get_string_descriptor(dev_handle, desc_index, langid, str.buf, sizeof(str.buf));
1267 	if (r < 0)
1268 		return r;
1269 	else if (r < DESC_HEADER_LENGTH || str.desc.bLength > r)
1270 		return LIBUSB_ERROR_IO;
1271 	else if (str.desc.bDescriptorType != LIBUSB_DT_STRING)
1272 		return LIBUSB_ERROR_IO;
1273 	else if ((str.desc.bLength & 1) || str.desc.bLength != r)
1274 		usbi_warn(HANDLE_CTX(dev_handle), "suspicious bLength %u for string descriptor (read %d)", str.desc.bLength, r);
1275 
1276 	/* Stop one byte before the end to leave room for null termination. */
1277 	int dest_max = length - 1;
1278 
1279 	/* The descriptor has this number of wide characters */
1280 	int src_max = (str.desc.bLength - 1 - 1) / 2;
1281 
1282 	/* Neither read nor write more than the smallest buffer */
1283 	int idx_max = MIN(dest_max, src_max);
1284 
1285 	int idx;
1286 	for (idx = 0; idx < idx_max; ++idx) {
1287 		wdata = libusb_le16_to_cpu(str.desc.wData[idx]);
1288 		if (wdata < 0x80)
1289 			data[idx] = (unsigned char)wdata;
1290 		else
1291 			data[idx] = '?'; /* non-ASCII */
1292 	}
1293 
1294 	data[idx] = 0; /* null-terminate string */
1295 	return idx;
1296 }
1297 
parse_iad_array(struct libusb_context * ctx,struct libusb_interface_association_descriptor_array * iad_array,const uint8_t * buffer,int size)1298 static int parse_iad_array(struct libusb_context *ctx,
1299 	struct libusb_interface_association_descriptor_array *iad_array,
1300 	const uint8_t *buffer, int size)
1301 {
1302 	uint8_t i;
1303 	struct usbi_descriptor_header header;
1304 	int consumed = 0;
1305 	const uint8_t *buf = buffer;
1306 	struct libusb_interface_association_descriptor *iad;
1307 
1308 	if (size < LIBUSB_DT_CONFIG_SIZE) {
1309 		usbi_err(ctx, "short config descriptor read %d/%d",
1310 			 size, LIBUSB_DT_CONFIG_SIZE);
1311 		return LIBUSB_ERROR_IO;
1312 	}
1313 
1314 	/* First pass: Iterate through desc list, count number of IADs */
1315 	iad_array->length = 0;
1316 	while (consumed < size) {
1317 		parse_descriptor(buf, "bb", &header);
1318 		if (header.bLength < 2) {
1319 			usbi_err(ctx, "invalid descriptor bLength %d",
1320 				 header.bLength);
1321 			return LIBUSB_ERROR_IO;
1322 		}
1323 		if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION)
1324 			iad_array->length++;
1325 		buf += header.bLength;
1326 		consumed += header.bLength;
1327 	}
1328 
1329 	iad_array->iad = NULL;
1330 	if (iad_array->length > 0) {
1331 		iad = calloc((size_t)iad_array->length, sizeof(*iad));
1332 		if (!iad)
1333 			return LIBUSB_ERROR_NO_MEM;
1334 
1335 		iad_array->iad = iad;
1336 
1337 		/* Second pass: Iterate through desc list, fill IAD structures */
1338 		consumed = 0;
1339 		i = 0;
1340 		while (consumed < size) {
1341 		   parse_descriptor(buffer, "bb", &header);
1342 		   if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION)
1343 			  parse_descriptor(buffer, "bbbbbbbb", &iad[i++]);
1344 		   buffer += header.bLength;
1345 		   consumed += header.bLength;
1346 		}
1347 	}
1348 
1349 	return LIBUSB_SUCCESS;
1350 }
1351 
raw_desc_to_iad_array(struct libusb_context * ctx,const uint8_t * buf,int size,struct libusb_interface_association_descriptor_array ** iad_array)1352 static int raw_desc_to_iad_array(struct libusb_context *ctx, const uint8_t *buf,
1353 		int size, struct libusb_interface_association_descriptor_array **iad_array)
1354 {
1355 	struct libusb_interface_association_descriptor_array *_iad_array
1356 		= calloc(1, sizeof(*_iad_array));
1357 	int r;
1358 
1359 	if (!_iad_array)
1360 		return LIBUSB_ERROR_NO_MEM;
1361 
1362 	r = parse_iad_array(ctx, _iad_array, buf, size);
1363 	if (r < 0) {
1364 		usbi_err(ctx, "parse_iad_array failed with error %d", r);
1365 		free(_iad_array);
1366 		return r;
1367 	}
1368 
1369 	*iad_array = _iad_array;
1370 	return LIBUSB_SUCCESS;
1371 }
1372 
1373 /** \ingroup libusb_desc
1374  * Get an array of interface association descriptors (IAD) for a given
1375  * configuration.
1376  * This is a non-blocking function which does not involve any requests being
1377  * sent to the device.
1378  *
1379  * \param dev a device
1380  * \param config_index the index of the configuration you wish to retrieve the
1381  * IADs for.
1382  * \param iad_array output location for the array of IADs. Only valid if 0 was
1383  * returned. Must be freed with libusb_free_interface_association_descriptors()
1384  * after use. It's possible that a given configuration contains no IADs. In this
1385  * case the iad_array is still output, but will have 'length' field set to 0, and
1386  * iad field set to NULL.
1387  * \returns 0 on success
1388  * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
1389  * \returns another LIBUSB_ERROR code on error
1390  * \see libusb_get_active_interface_association_descriptors()
1391  */
libusb_get_interface_association_descriptors(libusb_device * dev,uint8_t config_index,struct libusb_interface_association_descriptor_array ** iad_array)1392 int API_EXPORTED libusb_get_interface_association_descriptors(libusb_device *dev,
1393 	uint8_t config_index, struct libusb_interface_association_descriptor_array **iad_array)
1394 {
1395 	union usbi_config_desc_buf _config;
1396 	uint16_t config_len;
1397 	uint8_t *buf;
1398 	int r;
1399 
1400 	if (!iad_array)
1401 		return LIBUSB_ERROR_INVALID_PARAM;
1402 
1403 	usbi_dbg(DEVICE_CTX(dev), "IADs for config index %u", config_index);
1404 	if (config_index >= dev->device_descriptor.bNumConfigurations)
1405 		return LIBUSB_ERROR_NOT_FOUND;
1406 
1407 	r = get_config_descriptor(dev, config_index, _config.buf, sizeof(_config.buf));
1408 	if (r < 0)
1409 		return r;
1410 
1411 	config_len = libusb_le16_to_cpu(_config.desc.wTotalLength);
1412 	buf = malloc(config_len);
1413 	if (!buf)
1414 		return LIBUSB_ERROR_NO_MEM;
1415 
1416 	r = get_config_descriptor(dev, config_index, buf, config_len);
1417 	if (r >= 0)
1418 		r = raw_desc_to_iad_array(DEVICE_CTX(dev), buf, r, iad_array);
1419 
1420 	free(buf);
1421 	return r;
1422 }
1423 
1424 /** \ingroup libusb_desc
1425  * Get an array of interface association descriptors (IAD) for the currently
1426  * active configuration.
1427  * This is a non-blocking function which does not involve any requests being
1428  * sent to the device.
1429  *
1430  * \param dev a device
1431  * \param iad_array output location for the array of IADs. Only valid if 0 was
1432  * returned. Must be freed with libusb_free_interface_association_descriptors()
1433  * after use. It's possible that a given configuration contains no IADs. In this
1434  * case the iad_array is still output, but will have 'length' field set to 0, and
1435  * iad field set to NULL.
1436  * \returns 0 on success
1437  * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
1438  * \returns another LIBUSB_ERROR code on error
1439  * \see libusb_get_interface_association_descriptors
1440  */
libusb_get_active_interface_association_descriptors(libusb_device * dev,struct libusb_interface_association_descriptor_array ** iad_array)1441 int API_EXPORTED libusb_get_active_interface_association_descriptors(libusb_device *dev,
1442 	struct libusb_interface_association_descriptor_array **iad_array)
1443 {
1444 	union usbi_config_desc_buf _config;
1445 	uint16_t config_len;
1446 	uint8_t *buf;
1447 	int r;
1448 
1449 	if (!iad_array)
1450 		return LIBUSB_ERROR_INVALID_PARAM;
1451 
1452 	r = get_active_config_descriptor(dev, _config.buf, sizeof(_config.buf));
1453 	if (r < 0)
1454 		return r;
1455 
1456 	config_len = libusb_le16_to_cpu(_config.desc.wTotalLength);
1457 	buf = malloc(config_len);
1458 	if (!buf)
1459 		return LIBUSB_ERROR_NO_MEM;
1460 
1461 	r = get_active_config_descriptor(dev, buf, config_len);
1462 	if (r >= 0)
1463 		r = raw_desc_to_iad_array(DEVICE_CTX(dev), buf, r, iad_array);
1464 	free(buf);
1465 	return r;
1466 }
1467 
1468 /** \ingroup libusb_desc
1469  * Free an array of interface association descriptors (IADs) obtained from
1470  * libusb_get_interface_association_descriptors() or
1471  * libusb_get_active_interface_association_descriptors().
1472  * It is safe to call this function with a NULL iad_array parameter, in which
1473  * case the function simply returns.
1474  *
1475  * \param iad_array the IAD array to free
1476  */
libusb_free_interface_association_descriptors(struct libusb_interface_association_descriptor_array * iad_array)1477 void API_EXPORTED libusb_free_interface_association_descriptors(
1478 	struct libusb_interface_association_descriptor_array *iad_array)
1479 {
1480 	if (!iad_array)
1481 		return;
1482 
1483 	if (iad_array->iad)
1484 		free((void*)iad_array->iad);
1485 	free(iad_array);
1486 }
1487