1 /* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
3 * USB descriptor handling functions for libusbx
4 * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
5 * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
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.
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.
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
29 #define DESC_HEADER_LENGTH 2
30 #define DEVICE_DESC_LENGTH 18
31 #define CONFIG_DESC_LENGTH 9
32 #define INTERFACE_DESC_LENGTH 9
33 #define ENDPOINT_DESC_LENGTH 7
34 #define ENDPOINT_AUDIO_DESC_LENGTH 9
36 /** @defgroup desc USB descriptors
37 * This page details how to examine the various standard USB descriptors
38 * for detected devices
41 /* set host_endian if the w values are already in host endian format,
42 * as opposed to bus endian. */
43 int usbi_parse_descriptor(const unsigned char *source
, const char *descriptor
,
44 void *dest
, int host_endian
)
46 const unsigned char *sp
= source
;
47 unsigned char *dp
= dest
;
52 for (cp
= descriptor
; *cp
; cp
++) {
54 case 'b': /* 8-bit byte */
57 case 'w': /* 16-bit word, convert from little endian to CPU */
58 dp
+= ((uintptr_t)dp
& 1); /* Align to word boundary */
63 w
= (sp
[1] << 8) | sp
[0];
64 *((uint16_t *)dp
) = w
;
69 case 'd': /* 32-bit word, convert from little endian to CPU */
70 dp
+= ((uintptr_t)dp
& 1); /* Align to word boundary */
75 d
= (sp
[3] << 24) | (sp
[2] << 16) |
77 *((uint32_t *)dp
) = d
;
82 case 'u': /* 16 byte UUID */
90 return (int) (sp
- source
);
93 static void clear_endpoint(struct libusb_endpoint_descriptor
*endpoint
)
96 free((unsigned char *) endpoint
->extra
);
99 static int parse_endpoint(struct libusb_context
*ctx
,
100 struct libusb_endpoint_descriptor
*endpoint
, unsigned char *buffer
,
101 int size
, int host_endian
)
103 struct usb_descriptor_header header
;
104 unsigned char *extra
;
105 unsigned char *begin
;
109 if (size
< DESC_HEADER_LENGTH
) {
110 usbi_err(ctx
, "short endpoint descriptor read %d/%d",
111 size
, DESC_HEADER_LENGTH
);
112 return LIBUSB_ERROR_IO
;
115 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
116 if (header
.bDescriptorType
!= LIBUSB_DT_ENDPOINT
) {
117 usbi_err(ctx
, "unexpected descriptor %x (expected %x)",
118 header
.bDescriptorType
, LIBUSB_DT_ENDPOINT
);
121 if (header
.bLength
> size
) {
122 usbi_warn(ctx
, "short endpoint descriptor read %d/%d",
123 size
, header
.bLength
);
126 if (header
.bLength
>= ENDPOINT_AUDIO_DESC_LENGTH
)
127 usbi_parse_descriptor(buffer
, "bbbbwbbb", endpoint
, host_endian
);
128 else if (header
.bLength
>= ENDPOINT_DESC_LENGTH
)
129 usbi_parse_descriptor(buffer
, "bbbbwb", endpoint
, host_endian
);
131 usbi_err(ctx
, "invalid endpoint bLength (%d)", header
.bLength
);
132 return LIBUSB_ERROR_IO
;
135 buffer
+= header
.bLength
;
136 size
-= header
.bLength
;
137 parsed
+= header
.bLength
;
139 /* Skip over the rest of the Class Specific or Vendor Specific */
142 while (size
>= DESC_HEADER_LENGTH
) {
143 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
144 if (header
.bLength
< DESC_HEADER_LENGTH
) {
145 usbi_err(ctx
, "invalid extra ep desc len (%d)",
147 return LIBUSB_ERROR_IO
;
148 } else if (header
.bLength
> size
) {
149 usbi_warn(ctx
, "short extra ep desc read %d/%d",
150 size
, header
.bLength
);
154 /* If we find another "proper" descriptor then we're done */
155 if ((header
.bDescriptorType
== LIBUSB_DT_ENDPOINT
) ||
156 (header
.bDescriptorType
== LIBUSB_DT_INTERFACE
) ||
157 (header
.bDescriptorType
== LIBUSB_DT_CONFIG
) ||
158 (header
.bDescriptorType
== LIBUSB_DT_DEVICE
))
161 usbi_dbg("skipping descriptor %x", header
.bDescriptorType
);
162 buffer
+= header
.bLength
;
163 size
-= header
.bLength
;
164 parsed
+= header
.bLength
;
167 /* Copy any unknown descriptors into a storage area for drivers */
169 len
= (int)(buffer
- begin
);
171 endpoint
->extra
= NULL
;
172 endpoint
->extra_length
= 0;
177 endpoint
->extra
= extra
;
179 endpoint
->extra_length
= 0;
180 return LIBUSB_ERROR_NO_MEM
;
183 memcpy(extra
, begin
, len
);
184 endpoint
->extra_length
= len
;
189 static void clear_interface(struct libusb_interface
*usb_interface
)
194 if (usb_interface
->altsetting
) {
195 for (i
= 0; i
< usb_interface
->num_altsetting
; i
++) {
196 struct libusb_interface_descriptor
*ifp
=
197 (struct libusb_interface_descriptor
*)
198 usb_interface
->altsetting
+ i
;
200 free((void *) ifp
->extra
);
202 for (j
= 0; j
< ifp
->bNumEndpoints
; j
++)
203 clear_endpoint((struct libusb_endpoint_descriptor
*)
205 free((void *) ifp
->endpoint
);
208 free((void *) usb_interface
->altsetting
);
209 usb_interface
->altsetting
= NULL
;
214 static int parse_interface(libusb_context
*ctx
,
215 struct libusb_interface
*usb_interface
, unsigned char *buffer
, int size
,
222 int interface_number
= -1;
224 struct usb_descriptor_header header
;
225 struct libusb_interface_descriptor
*ifp
;
226 unsigned char *begin
;
228 usb_interface
->num_altsetting
= 0;
230 while (size
>= INTERFACE_DESC_LENGTH
) {
231 struct libusb_interface_descriptor
*altsetting
=
232 (struct libusb_interface_descriptor
*) usb_interface
->altsetting
;
233 altsetting
= usbi_reallocf(altsetting
,
234 sizeof(struct libusb_interface_descriptor
) *
235 (usb_interface
->num_altsetting
+ 1));
237 r
= LIBUSB_ERROR_NO_MEM
;
240 usb_interface
->altsetting
= altsetting
;
242 ifp
= altsetting
+ usb_interface
->num_altsetting
;
243 usbi_parse_descriptor(buffer
, "bbbbbbbbb", ifp
, 0);
244 if (ifp
->bDescriptorType
!= LIBUSB_DT_INTERFACE
) {
245 usbi_err(ctx
, "unexpected descriptor %x (expected %x)",
246 ifp
->bDescriptorType
, LIBUSB_DT_INTERFACE
);
249 if (ifp
->bLength
< INTERFACE_DESC_LENGTH
) {
250 usbi_err(ctx
, "invalid interface bLength (%d)",
255 if (ifp
->bLength
> size
) {
256 usbi_warn(ctx
, "short intf descriptor read %d/%d",
260 if (ifp
->bNumEndpoints
> USB_MAXENDPOINTS
) {
261 usbi_err(ctx
, "too many endpoints (%d)", ifp
->bNumEndpoints
);
266 usb_interface
->num_altsetting
++;
268 ifp
->extra_length
= 0;
269 ifp
->endpoint
= NULL
;
271 if (interface_number
== -1)
272 interface_number
= ifp
->bInterfaceNumber
;
274 /* Skip over the interface */
275 buffer
+= ifp
->bLength
;
276 parsed
+= ifp
->bLength
;
277 size
-= ifp
->bLength
;
281 /* Skip over any interface, class or vendor descriptors */
282 while (size
>= DESC_HEADER_LENGTH
) {
283 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
284 if (header
.bLength
< DESC_HEADER_LENGTH
) {
286 "invalid extra intf desc len (%d)",
290 } else if (header
.bLength
> size
) {
292 "short extra intf desc read %d/%d",
293 size
, header
.bLength
);
297 /* If we find another "proper" descriptor then we're done */
298 if ((header
.bDescriptorType
== LIBUSB_DT_INTERFACE
) ||
299 (header
.bDescriptorType
== LIBUSB_DT_ENDPOINT
) ||
300 (header
.bDescriptorType
== LIBUSB_DT_CONFIG
) ||
301 (header
.bDescriptorType
== LIBUSB_DT_DEVICE
))
304 buffer
+= header
.bLength
;
305 parsed
+= header
.bLength
;
306 size
-= header
.bLength
;
309 /* Copy any unknown descriptors into a storage area for */
310 /* drivers to later parse */
311 len
= (int)(buffer
- begin
);
313 ifp
->extra
= malloc(len
);
315 r
= LIBUSB_ERROR_NO_MEM
;
318 memcpy((unsigned char *) ifp
->extra
, begin
, len
);
319 ifp
->extra_length
= len
;
322 if (ifp
->bNumEndpoints
> 0) {
323 struct libusb_endpoint_descriptor
*endpoint
;
324 tmp
= ifp
->bNumEndpoints
* sizeof(struct libusb_endpoint_descriptor
);
325 endpoint
= malloc(tmp
);
326 ifp
->endpoint
= endpoint
;
328 r
= LIBUSB_ERROR_NO_MEM
;
332 memset(endpoint
, 0, tmp
);
333 for (i
= 0; i
< ifp
->bNumEndpoints
; i
++) {
334 r
= parse_endpoint(ctx
, endpoint
+ i
, buffer
, size
,
339 ifp
->bNumEndpoints
= (uint8_t)i
;
349 /* We check to see if it's an alternate to this one */
350 ifp
= (struct libusb_interface_descriptor
*) buffer
;
351 if (size
< LIBUSB_DT_INTERFACE_SIZE
||
352 ifp
->bDescriptorType
!= LIBUSB_DT_INTERFACE
||
353 ifp
->bInterfaceNumber
!= interface_number
)
359 clear_interface(usb_interface
);
363 static void clear_configuration(struct libusb_config_descriptor
*config
)
365 if (config
->interface
) {
367 for (i
= 0; i
< config
->bNumInterfaces
; i
++)
368 clear_interface((struct libusb_interface
*)
369 config
->interface
+ i
);
370 free((void *) config
->interface
);
373 free((void *) config
->extra
);
376 static int parse_configuration(struct libusb_context
*ctx
,
377 struct libusb_config_descriptor
*config
, unsigned char *buffer
,
378 int size
, int host_endian
)
383 struct usb_descriptor_header header
;
384 struct libusb_interface
*usb_interface
;
386 if (size
< LIBUSB_DT_CONFIG_SIZE
) {
387 usbi_err(ctx
, "short config descriptor read %d/%d",
388 size
, LIBUSB_DT_CONFIG_SIZE
);
389 return LIBUSB_ERROR_IO
;
392 usbi_parse_descriptor(buffer
, "bbwbbbbb", config
, host_endian
);
393 if (config
->bDescriptorType
!= LIBUSB_DT_CONFIG
) {
394 usbi_err(ctx
, "unexpected descriptor %x (expected %x)",
395 config
->bDescriptorType
, LIBUSB_DT_CONFIG
);
396 return LIBUSB_ERROR_IO
;
398 if (config
->bLength
< LIBUSB_DT_CONFIG_SIZE
) {
399 usbi_err(ctx
, "invalid config bLength (%d)", config
->bLength
);
400 return LIBUSB_ERROR_IO
;
402 if (config
->bLength
> size
) {
403 usbi_err(ctx
, "short config descriptor read %d/%d",
404 size
, config
->bLength
);
405 return LIBUSB_ERROR_IO
;
407 if (config
->bNumInterfaces
> USB_MAXINTERFACES
) {
408 usbi_err(ctx
, "too many interfaces (%d)", config
->bNumInterfaces
);
409 return LIBUSB_ERROR_IO
;
412 tmp
= config
->bNumInterfaces
* sizeof(struct libusb_interface
);
413 usb_interface
= malloc(tmp
);
414 config
->interface
= usb_interface
;
415 if (!config
->interface
)
416 return LIBUSB_ERROR_NO_MEM
;
418 memset(usb_interface
, 0, tmp
);
419 buffer
+= config
->bLength
;
420 size
-= config
->bLength
;
422 config
->extra
= NULL
;
423 config
->extra_length
= 0;
425 for (i
= 0; i
< config
->bNumInterfaces
; i
++) {
427 unsigned char *begin
;
429 /* Skip over the rest of the Class Specific or Vendor */
430 /* Specific descriptors */
432 while (size
>= DESC_HEADER_LENGTH
) {
433 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
435 if (header
.bLength
< DESC_HEADER_LENGTH
) {
437 "invalid extra config desc len (%d)",
441 } else if (header
.bLength
> size
) {
443 "short extra config desc read %d/%d",
444 size
, header
.bLength
);
445 config
->bNumInterfaces
= (uint8_t)i
;
449 /* If we find another "proper" descriptor then we're done */
450 if ((header
.bDescriptorType
== LIBUSB_DT_ENDPOINT
) ||
451 (header
.bDescriptorType
== LIBUSB_DT_INTERFACE
) ||
452 (header
.bDescriptorType
== LIBUSB_DT_CONFIG
) ||
453 (header
.bDescriptorType
== LIBUSB_DT_DEVICE
))
456 usbi_dbg("skipping descriptor 0x%x\n", header
.bDescriptorType
);
457 buffer
+= header
.bLength
;
458 size
-= header
.bLength
;
461 /* Copy any unknown descriptors into a storage area for */
462 /* drivers to later parse */
463 len
= (int)(buffer
- begin
);
465 /* FIXME: We should realloc and append here */
466 if (!config
->extra_length
) {
467 config
->extra
= malloc(len
);
468 if (!config
->extra
) {
469 r
= LIBUSB_ERROR_NO_MEM
;
473 memcpy((unsigned char *) config
->extra
, begin
, len
);
474 config
->extra_length
= len
;
478 r
= parse_interface(ctx
, usb_interface
+ i
, buffer
, size
, host_endian
);
482 config
->bNumInterfaces
= (uint8_t)i
;
493 clear_configuration(config
);
497 static int raw_desc_to_config(struct libusb_context
*ctx
,
498 unsigned char *buf
, int size
, int host_endian
,
499 struct libusb_config_descriptor
**config
)
501 struct libusb_config_descriptor
*_config
= malloc(sizeof(*_config
));
505 return LIBUSB_ERROR_NO_MEM
;
507 r
= parse_configuration(ctx
, _config
, buf
, size
, host_endian
);
509 usbi_err(ctx
, "parse_configuration failed with error %d", r
);
513 usbi_warn(ctx
, "still %d bytes of descriptor data left", r
);
517 return LIBUSB_SUCCESS
;
520 int usbi_device_cache_descriptor(libusb_device
*dev
)
522 int r
, host_endian
= 0;
524 r
= usbi_backend
->get_device_descriptor(dev
, (unsigned char *) &dev
->device_descriptor
,
530 dev
->device_descriptor
.bcdUSB
= libusb_le16_to_cpu(dev
->device_descriptor
.bcdUSB
);
531 dev
->device_descriptor
.idVendor
= libusb_le16_to_cpu(dev
->device_descriptor
.idVendor
);
532 dev
->device_descriptor
.idProduct
= libusb_le16_to_cpu(dev
->device_descriptor
.idProduct
);
533 dev
->device_descriptor
.bcdDevice
= libusb_le16_to_cpu(dev
->device_descriptor
.bcdDevice
);
536 return LIBUSB_SUCCESS
;
540 * Get the USB device descriptor for a given device.
542 * This is a non-blocking function; the device descriptor is cached in memory.
544 * Note since libusbx-1.0.16, \ref LIBUSBX_API_VERSION >= 0x01000102, this
545 * function always succeeds.
547 * \param dev the device
548 * \param desc output location for the descriptor data
549 * \returns 0 on success or a LIBUSB_ERROR code on failure
551 int API_EXPORTED
libusb_get_device_descriptor(libusb_device
*dev
,
552 struct libusb_device_descriptor
*desc
)
555 memcpy((unsigned char *) desc
, (unsigned char *) &dev
->device_descriptor
,
556 sizeof (dev
->device_descriptor
));
561 * Get the USB configuration descriptor for the currently active configuration.
562 * This is a non-blocking function which does not involve any requests being
563 * sent to the device.
565 * \param dev a device
566 * \param config output location for the USB configuration descriptor. Only
567 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
569 * \returns 0 on success
570 * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
571 * \returns another LIBUSB_ERROR code on error
572 * \see libusb_get_config_descriptor
574 int API_EXPORTED
libusb_get_active_config_descriptor(libusb_device
*dev
,
575 struct libusb_config_descriptor
**config
)
577 struct libusb_config_descriptor _config
;
578 unsigned char tmp
[LIBUSB_DT_CONFIG_SIZE
];
579 unsigned char *buf
= NULL
;
583 r
= usbi_backend
->get_active_config_descriptor(dev
, tmp
,
584 LIBUSB_DT_CONFIG_SIZE
, &host_endian
);
587 if (r
< LIBUSB_DT_CONFIG_SIZE
) {
588 usbi_err(dev
->ctx
, "short config descriptor read %d/%d",
589 r
, LIBUSB_DT_CONFIG_SIZE
);
590 return LIBUSB_ERROR_IO
;
593 usbi_parse_descriptor(tmp
, "bbw", &_config
, host_endian
);
594 buf
= malloc(_config
.wTotalLength
);
596 return LIBUSB_ERROR_NO_MEM
;
598 r
= usbi_backend
->get_active_config_descriptor(dev
, buf
,
599 _config
.wTotalLength
, &host_endian
);
601 r
= raw_desc_to_config(dev
->ctx
, buf
, r
, host_endian
, config
);
608 * Get a USB configuration descriptor based on its index.
609 * This is a non-blocking function which does not involve any requests being
610 * sent to the device.
612 * \param dev a device
613 * \param config_index the index of the configuration you wish to retrieve
614 * \param config output location for the USB configuration descriptor. Only
615 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
617 * \returns 0 on success
618 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
619 * \returns another LIBUSB_ERROR code on error
620 * \see libusb_get_active_config_descriptor()
621 * \see libusb_get_config_descriptor_by_value()
623 int API_EXPORTED
libusb_get_config_descriptor(libusb_device
*dev
,
624 uint8_t config_index
, struct libusb_config_descriptor
**config
)
626 struct libusb_config_descriptor _config
;
627 unsigned char tmp
[LIBUSB_DT_CONFIG_SIZE
];
628 unsigned char *buf
= NULL
;
632 usbi_dbg("index %d", config_index
);
633 if (config_index
>= dev
->num_configurations
)
634 return LIBUSB_ERROR_NOT_FOUND
;
636 r
= usbi_backend
->get_config_descriptor(dev
, config_index
, tmp
,
637 LIBUSB_DT_CONFIG_SIZE
, &host_endian
);
640 if (r
< LIBUSB_DT_CONFIG_SIZE
) {
641 usbi_err(dev
->ctx
, "short config descriptor read %d/%d",
642 r
, LIBUSB_DT_CONFIG_SIZE
);
643 return LIBUSB_ERROR_IO
;
646 usbi_parse_descriptor(tmp
, "bbw", &_config
, host_endian
);
647 buf
= malloc(_config
.wTotalLength
);
649 return LIBUSB_ERROR_NO_MEM
;
651 r
= usbi_backend
->get_config_descriptor(dev
, config_index
, buf
,
652 _config
.wTotalLength
, &host_endian
);
654 r
= raw_desc_to_config(dev
->ctx
, buf
, r
, host_endian
, config
);
660 /* iterate through all configurations, returning the index of the configuration
661 * matching a specific bConfigurationValue in the idx output parameter, or -1
662 * if the config was not found.
663 * returns 0 on success or a LIBUSB_ERROR code
665 int usbi_get_config_index_by_value(struct libusb_device
*dev
,
666 uint8_t bConfigurationValue
, int *idx
)
670 usbi_dbg("value %d", bConfigurationValue
);
671 for (i
= 0; i
< dev
->num_configurations
; i
++) {
672 unsigned char tmp
[6];
674 int r
= usbi_backend
->get_config_descriptor(dev
, i
, tmp
, sizeof(tmp
),
680 if (tmp
[5] == bConfigurationValue
) {
691 * Get a USB configuration descriptor with a specific bConfigurationValue.
692 * This is a non-blocking function which does not involve any requests being
693 * sent to the device.
695 * \param dev a device
696 * \param bConfigurationValue the bConfigurationValue of the configuration you
698 * \param config output location for the USB configuration descriptor. Only
699 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
701 * \returns 0 on success
702 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
703 * \returns another LIBUSB_ERROR code on error
704 * \see libusb_get_active_config_descriptor()
705 * \see libusb_get_config_descriptor()
707 int API_EXPORTED
libusb_get_config_descriptor_by_value(libusb_device
*dev
,
708 uint8_t bConfigurationValue
, struct libusb_config_descriptor
**config
)
710 int r
, idx
, host_endian
;
711 unsigned char *buf
= NULL
;
713 if (usbi_backend
->get_config_descriptor_by_value
) {
714 r
= usbi_backend
->get_config_descriptor_by_value(dev
,
715 bConfigurationValue
, &buf
, &host_endian
);
718 return raw_desc_to_config(dev
->ctx
, buf
, r
, host_endian
, config
);
721 r
= usbi_get_config_index_by_value(dev
, bConfigurationValue
, &idx
);
725 return LIBUSB_ERROR_NOT_FOUND
;
727 return libusb_get_config_descriptor(dev
, (uint8_t) idx
, config
);
731 * Free a configuration descriptor obtained from
732 * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
733 * It is safe to call this function with a NULL config parameter, in which
734 * case the function simply returns.
736 * \param config the configuration descriptor to free
738 void API_EXPORTED
libusb_free_config_descriptor(
739 struct libusb_config_descriptor
*config
)
744 clear_configuration(config
);
749 * Get an endpoints superspeed endpoint companion descriptor (if any)
751 * \param ctx the context to operate on, or NULL for the default context
752 * \param endpoint endpoint descriptor from which to get the superspeed
753 * endpoint companion descriptor
754 * \param ep_comp output location for the superspeed endpoint companion
755 * descriptor. Only valid if 0 was returned. Must be freed with
756 * libusb_free_ss_endpoint_companion_descriptor() after use.
757 * \returns 0 on success
758 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
759 * \returns another LIBUSB_ERROR code on error
761 int API_EXPORTED
libusb_get_ss_endpoint_companion_descriptor(
762 struct libusb_context
*ctx
,
763 const struct libusb_endpoint_descriptor
*endpoint
,
764 struct libusb_ss_endpoint_companion_descriptor
**ep_comp
)
766 struct usb_descriptor_header header
;
767 int size
= endpoint
->extra_length
;
768 const unsigned char *buffer
= endpoint
->extra
;
772 while (size
>= DESC_HEADER_LENGTH
) {
773 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
774 if (header
.bLength
< 2 || header
.bLength
> size
) {
775 usbi_err(ctx
, "invalid descriptor length %d",
777 return LIBUSB_ERROR_IO
;
779 if (header
.bDescriptorType
!= LIBUSB_DT_SS_ENDPOINT_COMPANION
) {
780 buffer
+= header
.bLength
;
781 size
-= header
.bLength
;
784 if (header
.bLength
< LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE
) {
785 usbi_err(ctx
, "invalid ss-ep-comp-desc length %d",
787 return LIBUSB_ERROR_IO
;
789 *ep_comp
= malloc(sizeof(**ep_comp
));
790 if (*ep_comp
== NULL
)
791 return LIBUSB_ERROR_NO_MEM
;
792 usbi_parse_descriptor(buffer
, "bbbbw", *ep_comp
, 0);
793 return LIBUSB_SUCCESS
;
795 return LIBUSB_ERROR_NOT_FOUND
;
799 * Free a superspeed endpoint companion descriptor obtained from
800 * libusb_get_ss_endpoint_companion_descriptor().
801 * It is safe to call this function with a NULL ep_comp parameter, in which
802 * case the function simply returns.
804 * \param ep_comp the superspeed endpoint companion descriptor to free
806 void API_EXPORTED
libusb_free_ss_endpoint_companion_descriptor(
807 struct libusb_ss_endpoint_companion_descriptor
*ep_comp
)
812 static int parse_bos(struct libusb_context
*ctx
,
813 struct libusb_bos_descriptor
**bos
,
814 unsigned char *buffer
, int size
, int host_endian
)
816 struct libusb_bos_descriptor bos_header
, *_bos
;
817 struct libusb_bos_dev_capability_descriptor dev_cap
;
820 if (size
< LIBUSB_DT_BOS_SIZE
) {
821 usbi_err(ctx
, "short bos descriptor read %d/%d",
822 size
, LIBUSB_DT_BOS_SIZE
);
823 return LIBUSB_ERROR_IO
;
826 usbi_parse_descriptor(buffer
, "bbwb", &bos_header
, host_endian
);
827 if (bos_header
.bDescriptorType
!= LIBUSB_DT_BOS
) {
828 usbi_err(ctx
, "unexpected descriptor %x (expected %x)",
829 bos_header
.bDescriptorType
, LIBUSB_DT_BOS
);
830 return LIBUSB_ERROR_IO
;
832 if (bos_header
.bLength
< LIBUSB_DT_BOS_SIZE
) {
833 usbi_err(ctx
, "invalid bos bLength (%d)", bos_header
.bLength
);
834 return LIBUSB_ERROR_IO
;
836 if (bos_header
.bLength
> size
) {
837 usbi_err(ctx
, "short bos descriptor read %d/%d",
838 size
, bos_header
.bLength
);
839 return LIBUSB_ERROR_IO
;
843 sizeof(*_bos
) + bos_header
.bNumDeviceCaps
* sizeof(void *));
845 return LIBUSB_ERROR_NO_MEM
;
847 usbi_parse_descriptor(buffer
, "bbwb", _bos
, host_endian
);
848 buffer
+= bos_header
.bLength
;
849 size
-= bos_header
.bLength
;
851 /* Get the device capability descriptors */
852 for (i
= 0; i
< bos_header
.bNumDeviceCaps
; i
++) {
853 if (size
< LIBUSB_DT_DEVICE_CAPABILITY_SIZE
) {
854 usbi_warn(ctx
, "short dev-cap descriptor read %d/%d",
855 size
, LIBUSB_DT_DEVICE_CAPABILITY_SIZE
);
858 usbi_parse_descriptor(buffer
, "bbb", &dev_cap
, host_endian
);
859 if (dev_cap
.bDescriptorType
!= LIBUSB_DT_DEVICE_CAPABILITY
) {
860 usbi_warn(ctx
, "unexpected descriptor %x (expected %x)",
861 dev_cap
.bDescriptorType
, LIBUSB_DT_DEVICE_CAPABILITY
);
864 if (dev_cap
.bLength
< LIBUSB_DT_DEVICE_CAPABILITY_SIZE
) {
865 usbi_err(ctx
, "invalid dev-cap bLength (%d)",
867 libusb_free_bos_descriptor(_bos
);
868 return LIBUSB_ERROR_IO
;
870 if (dev_cap
.bLength
> size
) {
871 usbi_warn(ctx
, "short dev-cap descriptor read %d/%d",
872 size
, dev_cap
.bLength
);
876 _bos
->dev_capability
[i
] = malloc(dev_cap
.bLength
);
877 if (!_bos
->dev_capability
[i
]) {
878 libusb_free_bos_descriptor(_bos
);
879 return LIBUSB_ERROR_NO_MEM
;
881 memcpy(_bos
->dev_capability
[i
], buffer
, dev_cap
.bLength
);
882 buffer
+= dev_cap
.bLength
;
883 size
-= dev_cap
.bLength
;
885 _bos
->bNumDeviceCaps
= (uint8_t)i
;
888 return LIBUSB_SUCCESS
;
892 * Get a Binary Object Store (BOS) descriptor
893 * This is a BLOCKING function, which will send requests to the device.
895 * \param handle the handle of an open libusb device
896 * \param bos output location for the BOS descriptor. Only valid if 0 was returned.
897 * Must be freed with \ref libusb_free_bos_descriptor() after use.
898 * \returns 0 on success
899 * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor
900 * \returns another LIBUSB_ERROR code on error
902 int API_EXPORTED
libusb_get_bos_descriptor(libusb_device_handle
*handle
,
903 struct libusb_bos_descriptor
**bos
)
905 struct libusb_bos_descriptor _bos
;
906 uint8_t bos_header
[LIBUSB_DT_BOS_SIZE
] = {0};
907 unsigned char *bos_data
= NULL
;
908 const int host_endian
= 0;
911 /* Read the BOS. This generates 2 requests on the bus,
912 * one for the header, and one for the full BOS */
913 r
= libusb_get_descriptor(handle
, LIBUSB_DT_BOS
, 0, bos_header
,
916 if (r
!= LIBUSB_ERROR_PIPE
)
917 usbi_err(handle
->dev
->ctx
, "failed to read BOS (%d)", r
);
920 if (r
< LIBUSB_DT_BOS_SIZE
) {
921 usbi_err(handle
->dev
->ctx
, "short BOS read %d/%d",
922 r
, LIBUSB_DT_BOS_SIZE
);
923 return LIBUSB_ERROR_IO
;
926 usbi_parse_descriptor(bos_header
, "bbwb", &_bos
, host_endian
);
927 usbi_dbg("found BOS descriptor: size %d bytes, %d capabilities",
928 _bos
.wTotalLength
, _bos
.bNumDeviceCaps
);
929 bos_data
= calloc(_bos
.wTotalLength
, 1);
930 if (bos_data
== NULL
)
931 return LIBUSB_ERROR_NO_MEM
;
933 r
= libusb_get_descriptor(handle
, LIBUSB_DT_BOS
, 0, bos_data
,
936 r
= parse_bos(handle
->dev
->ctx
, bos
, bos_data
, r
, host_endian
);
938 usbi_err(handle
->dev
->ctx
, "failed to read BOS (%d)", r
);
945 * Free a BOS descriptor obtained from libusb_get_bos_descriptor().
946 * It is safe to call this function with a NULL bos parameter, in which
947 * case the function simply returns.
949 * \param bos the BOS descriptor to free
951 void API_EXPORTED
libusb_free_bos_descriptor(struct libusb_bos_descriptor
*bos
)
958 for (i
= 0; i
< bos
->bNumDeviceCaps
; i
++)
959 free(bos
->dev_capability
[i
]);
964 * Get an USB 2.0 Extension descriptor
966 * \param ctx the context to operate on, or NULL for the default context
967 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
968 * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION
969 * LIBUSB_BT_USB_2_0_EXTENSION
970 * \param usb_2_0_extension output location for the USB 2.0 Extension
971 * descriptor. Only valid if 0 was returned. Must be freed with
972 * libusb_free_usb_2_0_extension_descriptor() after use.
973 * \returns 0 on success
974 * \returns a LIBUSB_ERROR code on error
976 int API_EXPORTED
libusb_get_usb_2_0_extension_descriptor(
977 struct libusb_context
*ctx
,
978 struct libusb_bos_dev_capability_descriptor
*dev_cap
,
979 struct libusb_usb_2_0_extension_descriptor
**usb_2_0_extension
)
981 struct libusb_usb_2_0_extension_descriptor
*_usb_2_0_extension
;
982 const int host_endian
= 0;
984 if (dev_cap
->bDevCapabilityType
!= LIBUSB_BT_USB_2_0_EXTENSION
) {
985 usbi_err(ctx
, "unexpected bDevCapabilityType %x (expected %x)",
986 dev_cap
->bDevCapabilityType
,
987 LIBUSB_BT_USB_2_0_EXTENSION
);
988 return LIBUSB_ERROR_INVALID_PARAM
;
990 if (dev_cap
->bLength
< LIBUSB_BT_USB_2_0_EXTENSION_SIZE
) {
991 usbi_err(ctx
, "short dev-cap descriptor read %d/%d",
992 dev_cap
->bLength
, LIBUSB_BT_USB_2_0_EXTENSION_SIZE
);
993 return LIBUSB_ERROR_IO
;
996 _usb_2_0_extension
= malloc(sizeof(*_usb_2_0_extension
));
997 if (!_usb_2_0_extension
)
998 return LIBUSB_ERROR_NO_MEM
;
1000 usbi_parse_descriptor((unsigned char *)dev_cap
, "bbbd",
1001 _usb_2_0_extension
, host_endian
);
1003 *usb_2_0_extension
= _usb_2_0_extension
;
1004 return LIBUSB_SUCCESS
;
1008 * Free a USB 2.0 Extension descriptor obtained from
1009 * libusb_get_usb_2_0_extension_descriptor().
1010 * It is safe to call this function with a NULL usb_2_0_extension parameter,
1011 * in which case the function simply returns.
1013 * \param usb_2_0_extension the USB 2.0 Extension descriptor to free
1015 void API_EXPORTED
libusb_free_usb_2_0_extension_descriptor(
1016 struct libusb_usb_2_0_extension_descriptor
*usb_2_0_extension
)
1018 free(usb_2_0_extension
);
1022 * Get a SuperSpeed USB Device Capability descriptor
1024 * \param ctx the context to operate on, or NULL for the default context
1025 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1026 * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
1027 * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
1028 * \param ss_usb_device_cap output location for the SuperSpeed USB Device
1029 * Capability descriptor. Only valid if 0 was returned. Must be freed with
1030 * libusb_free_ss_usb_device_capability_descriptor() after use.
1031 * \returns 0 on success
1032 * \returns a LIBUSB_ERROR code on error
1034 int API_EXPORTED
libusb_get_ss_usb_device_capability_descriptor(
1035 struct libusb_context
*ctx
,
1036 struct libusb_bos_dev_capability_descriptor
*dev_cap
,
1037 struct libusb_ss_usb_device_capability_descriptor
**ss_usb_device_cap
)
1039 struct libusb_ss_usb_device_capability_descriptor
*_ss_usb_device_cap
;
1040 const int host_endian
= 0;
1042 if (dev_cap
->bDevCapabilityType
!= LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
) {
1043 usbi_err(ctx
, "unexpected bDevCapabilityType %x (expected %x)",
1044 dev_cap
->bDevCapabilityType
,
1045 LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
);
1046 return LIBUSB_ERROR_INVALID_PARAM
;
1048 if (dev_cap
->bLength
< LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE
) {
1049 usbi_err(ctx
, "short dev-cap descriptor read %d/%d",
1050 dev_cap
->bLength
, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE
);
1051 return LIBUSB_ERROR_IO
;
1054 _ss_usb_device_cap
= malloc(sizeof(*_ss_usb_device_cap
));
1055 if (!_ss_usb_device_cap
)
1056 return LIBUSB_ERROR_NO_MEM
;
1058 usbi_parse_descriptor((unsigned char *)dev_cap
, "bbbbwbbw",
1059 _ss_usb_device_cap
, host_endian
);
1061 *ss_usb_device_cap
= _ss_usb_device_cap
;
1062 return LIBUSB_SUCCESS
;
1066 * Free a SuperSpeed USB Device Capability descriptor obtained from
1067 * libusb_get_ss_usb_device_capability_descriptor().
1068 * It is safe to call this function with a NULL ss_usb_device_cap
1069 * parameter, in which case the function simply returns.
1071 * \param ss_usb_device_cap the USB 2.0 Extension descriptor to free
1073 void API_EXPORTED
libusb_free_ss_usb_device_capability_descriptor(
1074 struct libusb_ss_usb_device_capability_descriptor
*ss_usb_device_cap
)
1076 free(ss_usb_device_cap
);
1080 * Get a Container ID descriptor
1082 * \param ctx the context to operate on, or NULL for the default context
1083 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1084 * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID
1085 * LIBUSB_BT_CONTAINER_ID
1086 * \param container_id output location for the Container ID descriptor.
1087 * Only valid if 0 was returned. Must be freed with
1088 * libusb_free_container_id_descriptor() after use.
1089 * \returns 0 on success
1090 * \returns a LIBUSB_ERROR code on error
1092 int API_EXPORTED
libusb_get_container_id_descriptor(struct libusb_context
*ctx
,
1093 struct libusb_bos_dev_capability_descriptor
*dev_cap
,
1094 struct libusb_container_id_descriptor
**container_id
)
1096 struct libusb_container_id_descriptor
*_container_id
;
1097 const int host_endian
= 0;
1099 if (dev_cap
->bDevCapabilityType
!= LIBUSB_BT_CONTAINER_ID
) {
1100 usbi_err(ctx
, "unexpected bDevCapabilityType %x (expected %x)",
1101 dev_cap
->bDevCapabilityType
,
1102 LIBUSB_BT_CONTAINER_ID
);
1103 return LIBUSB_ERROR_INVALID_PARAM
;
1105 if (dev_cap
->bLength
< LIBUSB_BT_CONTAINER_ID_SIZE
) {
1106 usbi_err(ctx
, "short dev-cap descriptor read %d/%d",
1107 dev_cap
->bLength
, LIBUSB_BT_CONTAINER_ID_SIZE
);
1108 return LIBUSB_ERROR_IO
;
1111 _container_id
= malloc(sizeof(*_container_id
));
1113 return LIBUSB_ERROR_NO_MEM
;
1115 usbi_parse_descriptor((unsigned char *)dev_cap
, "bbbbu",
1116 _container_id
, host_endian
);
1118 *container_id
= _container_id
;
1119 return LIBUSB_SUCCESS
;
1123 * Free a Container ID descriptor obtained from
1124 * libusb_get_container_id_descriptor().
1125 * It is safe to call this function with a NULL container_id parameter,
1126 * in which case the function simply returns.
1128 * \param container_id the USB 2.0 Extension descriptor to free
1130 void API_EXPORTED
libusb_free_container_id_descriptor(
1131 struct libusb_container_id_descriptor
*container_id
)
1137 * Retrieve a string descriptor in C style ASCII.
1139 * Wrapper around libusb_get_string_descriptor(). Uses the first language
1140 * supported by the device.
1142 * \param dev a device handle
1143 * \param desc_index the index of the descriptor to retrieve
1144 * \param data output buffer for ASCII string descriptor
1145 * \param length size of data buffer
1146 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
1148 int API_EXPORTED
libusb_get_string_descriptor_ascii(libusb_device_handle
*dev
,
1149 uint8_t desc_index
, unsigned char *data
, int length
)
1151 unsigned char tbuf
[255]; /* Some devices choke on size > 255 */
1155 /* Asking for the zero'th index is special - it returns a string
1156 * descriptor that contains all the language IDs supported by the
1157 * device. Typically there aren't many - often only one. Language
1158 * IDs are 16 bit numbers, and they start at the third byte in the
1159 * descriptor. There's also no point in trying to read descriptor 0
1160 * with this function. See USB 2.0 specification section 9.6.7 for
1164 if (desc_index
== 0)
1165 return LIBUSB_ERROR_INVALID_PARAM
;
1167 r
= libusb_get_string_descriptor(dev
, 0, 0, tbuf
, sizeof(tbuf
));
1172 return LIBUSB_ERROR_IO
;
1174 langid
= tbuf
[2] | (tbuf
[3] << 8);
1176 r
= libusb_get_string_descriptor(dev
, desc_index
, langid
, tbuf
,
1181 if (tbuf
[1] != LIBUSB_DT_STRING
)
1182 return LIBUSB_ERROR_IO
;
1185 return LIBUSB_ERROR_IO
;
1187 for (di
= 0, si
= 2; si
< tbuf
[0]; si
+= 2) {
1188 if (di
>= (length
- 1))
1191 if ((tbuf
[si
] & 0x80) || (tbuf
[si
+ 1])) /* non-ASCII */
1194 data
[di
++] = tbuf
[si
];