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