2 * USB descriptor handling functions for libusbx
3 * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
4 * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 #define DESC_HEADER_LENGTH 2
29 #define DEVICE_DESC_LENGTH 18
30 #define CONFIG_DESC_LENGTH 9
31 #define INTERFACE_DESC_LENGTH 9
32 #define ENDPOINT_DESC_LENGTH 7
33 #define ENDPOINT_AUDIO_DESC_LENGTH 9
35 /** @defgroup desc USB descriptors
36 * This page details how to examine the various standard USB descriptors
37 * for detected devices
40 /* set host_endian if the w values are already in host endian format,
41 * as opposed to bus endian. */
42 int usbi_parse_descriptor(unsigned char *source
, const char *descriptor
,
43 void *dest
, int host_endian
)
45 unsigned char *sp
= source
, *dp
= dest
;
49 for (cp
= descriptor
; *cp
; cp
++) {
51 case 'b': /* 8-bit byte */
54 case 'w': /* 16-bit word, convert from little endian to CPU */
55 dp
+= ((uintptr_t)dp
& 1); /* Align to word boundary */
60 w
= (sp
[1] << 8) | sp
[0];
61 *((uint16_t *)dp
) = w
;
69 return (int) (sp
- source
);
72 static void clear_endpoint(struct libusb_endpoint_descriptor
*endpoint
)
75 free((unsigned char *) endpoint
->extra
);
78 static int parse_endpoint(struct libusb_context
*ctx
,
79 struct libusb_endpoint_descriptor
*endpoint
, unsigned char *buffer
,
80 int size
, int host_endian
)
82 struct usb_descriptor_header header
;
88 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
90 /* Everything should be fine being passed into here, but we sanity */
92 if (header
.bLength
> size
) {
93 usbi_err(ctx
, "ran out of descriptors parsing");
97 if (header
.bDescriptorType
!= LIBUSB_DT_ENDPOINT
) {
98 usbi_err(ctx
, "unexpected descriptor %x (expected %x)",
99 header
.bDescriptorType
, LIBUSB_DT_ENDPOINT
);
103 if (header
.bLength
>= ENDPOINT_AUDIO_DESC_LENGTH
)
104 usbi_parse_descriptor(buffer
, "bbbbwbbb", endpoint
, host_endian
);
105 else if (header
.bLength
>= ENDPOINT_DESC_LENGTH
)
106 usbi_parse_descriptor(buffer
, "bbbbwb", endpoint
, host_endian
);
108 buffer
+= header
.bLength
;
109 size
-= header
.bLength
;
110 parsed
+= header
.bLength
;
112 /* Skip over the rest of the Class Specific or Vendor Specific */
115 while (size
>= DESC_HEADER_LENGTH
) {
116 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
118 if (header
.bLength
< 2) {
119 usbi_err(ctx
, "invalid descriptor length %d", header
.bLength
);
123 /* If we find another "proper" descriptor then we're done */
124 if ((header
.bDescriptorType
== LIBUSB_DT_ENDPOINT
) ||
125 (header
.bDescriptorType
== LIBUSB_DT_INTERFACE
) ||
126 (header
.bDescriptorType
== LIBUSB_DT_CONFIG
) ||
127 (header
.bDescriptorType
== LIBUSB_DT_DEVICE
))
130 usbi_dbg("skipping descriptor %x", header
.bDescriptorType
);
131 buffer
+= header
.bLength
;
132 size
-= header
.bLength
;
133 parsed
+= header
.bLength
;
136 /* Copy any unknown descriptors into a storage area for drivers */
138 len
= (int)(buffer
- begin
);
140 endpoint
->extra
= NULL
;
141 endpoint
->extra_length
= 0;
146 endpoint
->extra
= extra
;
148 endpoint
->extra_length
= 0;
149 return LIBUSB_ERROR_NO_MEM
;
152 memcpy(extra
, begin
, len
);
153 endpoint
->extra_length
= len
;
158 static void clear_interface(struct libusb_interface
*usb_interface
)
163 if (usb_interface
->altsetting
) {
164 for (i
= 0; i
< usb_interface
->num_altsetting
; i
++) {
165 struct libusb_interface_descriptor
*ifp
=
166 (struct libusb_interface_descriptor
*)
167 usb_interface
->altsetting
+ i
;
169 free((void *) ifp
->extra
);
171 for (j
= 0; j
< ifp
->bNumEndpoints
; j
++)
172 clear_endpoint((struct libusb_endpoint_descriptor
*)
174 free((void *) ifp
->endpoint
);
177 free((void *) usb_interface
->altsetting
);
178 usb_interface
->altsetting
= NULL
;
183 static int parse_interface(libusb_context
*ctx
,
184 struct libusb_interface
*usb_interface
, unsigned char *buffer
, int size
,
192 struct usb_descriptor_header header
;
193 struct libusb_interface_descriptor
*ifp
;
194 unsigned char *begin
;
196 usb_interface
->num_altsetting
= 0;
198 while (size
>= INTERFACE_DESC_LENGTH
) {
199 struct libusb_interface_descriptor
*altsetting
=
200 (struct libusb_interface_descriptor
*) usb_interface
->altsetting
;
201 altsetting
= usbi_reallocf(altsetting
,
202 sizeof(struct libusb_interface_descriptor
) *
203 (usb_interface
->num_altsetting
+ 1));
205 r
= LIBUSB_ERROR_NO_MEM
;
208 usb_interface
->altsetting
= altsetting
;
210 ifp
= altsetting
+ usb_interface
->num_altsetting
;
211 usb_interface
->num_altsetting
++;
212 usbi_parse_descriptor(buffer
, "bbbbbbbbb", ifp
, 0);
214 ifp
->extra_length
= 0;
215 ifp
->endpoint
= NULL
;
217 /* Skip over the interface */
218 buffer
+= ifp
->bLength
;
219 parsed
+= ifp
->bLength
;
220 size
-= ifp
->bLength
;
224 /* Skip over any interface, class or vendor descriptors */
225 while (size
>= DESC_HEADER_LENGTH
) {
226 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
227 if (header
.bLength
< 2) {
228 usbi_err(ctx
, "invalid descriptor of length %d",
232 } else if (header
.bLength
> size
) {
233 usbi_warn(ctx
, "invalid descriptor of length %d",
235 /* The remaining bytes are bogus, but at least
236 * one interface is OK, so let's continue. */
240 /* If we find another "proper" descriptor then we're done */
241 if ((header
.bDescriptorType
== LIBUSB_DT_INTERFACE
) ||
242 (header
.bDescriptorType
== LIBUSB_DT_ENDPOINT
) ||
243 (header
.bDescriptorType
== LIBUSB_DT_CONFIG
) ||
244 (header
.bDescriptorType
== LIBUSB_DT_DEVICE
))
247 buffer
+= header
.bLength
;
248 parsed
+= header
.bLength
;
249 size
-= header
.bLength
;
252 /* Copy any unknown descriptors into a storage area for */
253 /* drivers to later parse */
254 len
= (int)(buffer
- begin
);
256 ifp
->extra
= malloc(len
);
258 r
= LIBUSB_ERROR_NO_MEM
;
261 memcpy((unsigned char *) ifp
->extra
, begin
, len
);
262 ifp
->extra_length
= len
;
265 /* Did we hit an unexpected descriptor? */
266 if (size
>= DESC_HEADER_LENGTH
) {
267 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
268 if ((header
.bDescriptorType
== LIBUSB_DT_CONFIG
) ||
269 (header
.bDescriptorType
== LIBUSB_DT_DEVICE
)) {
274 if (ifp
->bNumEndpoints
> USB_MAXENDPOINTS
) {
275 usbi_err(ctx
, "too many endpoints (%d)", ifp
->bNumEndpoints
);
280 if (ifp
->bNumEndpoints
> 0) {
281 struct libusb_endpoint_descriptor
*endpoint
;
282 tmp
= ifp
->bNumEndpoints
* sizeof(struct libusb_endpoint_descriptor
);
283 endpoint
= malloc(tmp
);
284 ifp
->endpoint
= endpoint
;
286 r
= LIBUSB_ERROR_NO_MEM
;
290 memset(endpoint
, 0, tmp
);
291 for (i
= 0; i
< ifp
->bNumEndpoints
; i
++) {
292 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
294 if (header
.bLength
> size
) {
295 usbi_err(ctx
, "ran out of descriptors parsing");
300 r
= parse_endpoint(ctx
, endpoint
+ i
, buffer
, size
,
311 /* We check to see if it's an alternate to this one */
312 ifp
= (struct libusb_interface_descriptor
*) buffer
;
313 if (size
< LIBUSB_DT_INTERFACE_SIZE
||
314 ifp
->bDescriptorType
!= LIBUSB_DT_INTERFACE
||
315 !ifp
->bAlternateSetting
)
321 clear_interface(usb_interface
);
325 static void clear_configuration(struct libusb_config_descriptor
*config
)
327 if (config
->interface
) {
329 for (i
= 0; i
< config
->bNumInterfaces
; i
++)
330 clear_interface((struct libusb_interface
*)
331 config
->interface
+ i
);
332 free((void *) config
->interface
);
335 free((void *) config
->extra
);
338 static int parse_configuration(struct libusb_context
*ctx
,
339 struct libusb_config_descriptor
*config
, unsigned char *buffer
,
346 struct usb_descriptor_header header
;
347 struct libusb_interface
*usb_interface
;
349 usbi_parse_descriptor(buffer
, "bbwbbbbb", config
, host_endian
);
350 size
= config
->wTotalLength
;
352 if (config
->bNumInterfaces
> USB_MAXINTERFACES
) {
353 usbi_err(ctx
, "too many interfaces (%d)", config
->bNumInterfaces
);
354 return LIBUSB_ERROR_IO
;
357 tmp
= config
->bNumInterfaces
* sizeof(struct libusb_interface
);
358 usb_interface
= malloc(tmp
);
359 config
->interface
= usb_interface
;
360 if (!config
->interface
)
361 return LIBUSB_ERROR_NO_MEM
;
363 memset(usb_interface
, 0, tmp
);
364 buffer
+= config
->bLength
;
365 size
-= config
->bLength
;
367 config
->extra
= NULL
;
368 config
->extra_length
= 0;
370 for (i
= 0; i
< config
->bNumInterfaces
; i
++) {
372 unsigned char *begin
;
374 /* Skip over the rest of the Class Specific or Vendor */
375 /* Specific descriptors */
377 while (size
>= DESC_HEADER_LENGTH
) {
378 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
380 /* If we've parsed at least one config descriptor then
381 * let's return that. */
382 if (header
.bLength
> size
&& i
) {
383 usbi_warn(ctx
, "invalid descriptor length of %d",
388 if ((header
.bLength
> size
) ||
389 (header
.bLength
< DESC_HEADER_LENGTH
)) {
390 usbi_err(ctx
, "invalid descriptor length of %d",
396 /* If we find another "proper" descriptor then we're done */
397 if ((header
.bDescriptorType
== LIBUSB_DT_ENDPOINT
) ||
398 (header
.bDescriptorType
== LIBUSB_DT_INTERFACE
) ||
399 (header
.bDescriptorType
== LIBUSB_DT_CONFIG
) ||
400 (header
.bDescriptorType
== LIBUSB_DT_DEVICE
))
403 usbi_dbg("skipping descriptor 0x%x\n", header
.bDescriptorType
);
404 buffer
+= header
.bLength
;
405 size
-= header
.bLength
;
408 /* Copy any unknown descriptors into a storage area for */
409 /* drivers to later parse */
410 len
= (int)(buffer
- begin
);
412 /* FIXME: We should realloc and append here */
413 if (!config
->extra_length
) {
414 config
->extra
= malloc(len
);
415 if (!config
->extra
) {
416 r
= LIBUSB_ERROR_NO_MEM
;
420 memcpy((unsigned char *) config
->extra
, begin
, len
);
421 config
->extra_length
= len
;
425 r
= parse_interface(ctx
, usb_interface
+ i
, buffer
, size
, host_endian
);
436 clear_configuration(config
);
440 int usbi_device_cache_descriptor(libusb_device
*dev
)
444 r
= usbi_backend
->get_device_descriptor(dev
, (unsigned char *) &dev
->device_descriptor
,
450 dev
->device_descriptor
.bcdUSB
= libusb_le16_to_cpu(dev
->device_descriptor
.bcdUSB
);
451 dev
->device_descriptor
.idVendor
= libusb_le16_to_cpu(dev
->device_descriptor
.idVendor
);
452 dev
->device_descriptor
.idProduct
= libusb_le16_to_cpu(dev
->device_descriptor
.idProduct
);
453 dev
->device_descriptor
.bcdDevice
= libusb_le16_to_cpu(dev
->device_descriptor
.bcdDevice
);
456 return LIBUSB_SUCCESS
;
460 * Get the USB device descriptor for a given device.
462 * This is a non-blocking function; the device descriptor is cached in memory.
464 * \param dev the device
465 * \param desc output location for the descriptor data
466 * \returns 0 on success or a LIBUSB_ERROR code on failure
468 int API_EXPORTED
libusb_get_device_descriptor(libusb_device
*dev
,
469 struct libusb_device_descriptor
*desc
)
472 memcpy((unsigned char *) desc
, (unsigned char *) &dev
->device_descriptor
,
473 sizeof (dev
->device_descriptor
));
478 * Get the USB configuration descriptor for the currently active configuration.
479 * This is a non-blocking function which does not involve any requests being
480 * sent to the device.
482 * \param dev a device
483 * \param config output location for the USB configuration descriptor. Only
484 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
486 * \returns 0 on success
487 * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
488 * \returns another LIBUSB_ERROR code on error
489 * \see libusb_get_config_descriptor
491 int API_EXPORTED
libusb_get_active_config_descriptor(libusb_device
*dev
,
492 struct libusb_config_descriptor
**config
)
494 struct libusb_config_descriptor
*_config
= malloc(sizeof(*_config
));
495 unsigned char tmp
[8];
496 unsigned char *buf
= NULL
;
502 return LIBUSB_ERROR_NO_MEM
;
504 r
= usbi_backend
->get_active_config_descriptor(dev
, tmp
, sizeof(tmp
),
509 _config
->wTotalLength
= 0;
510 usbi_parse_descriptor(tmp
, "bbw", _config
, host_endian
);
511 if (_config
->wTotalLength
!= 0)
512 buf
= malloc(_config
->wTotalLength
);
514 r
= LIBUSB_ERROR_NO_MEM
;
518 r
= usbi_backend
->get_active_config_descriptor(dev
, buf
,
519 _config
->wTotalLength
, &host_endian
);
523 r
= parse_configuration(dev
->ctx
, _config
, buf
, host_endian
);
525 usbi_err(dev
->ctx
, "parse_configuration failed with error %d", r
);
528 usbi_warn(dev
->ctx
, "descriptor data still left");
543 * Get a USB configuration descriptor based on its index.
544 * This is a non-blocking function which does not involve any requests being
545 * sent to the device.
547 * \param dev a device
548 * \param config_index the index of the configuration you wish to retrieve
549 * \param config output location for the USB configuration descriptor. Only
550 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
552 * \returns 0 on success
553 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
554 * \returns another LIBUSB_ERROR code on error
555 * \see libusb_get_active_config_descriptor()
556 * \see libusb_get_config_descriptor_by_value()
558 int API_EXPORTED
libusb_get_config_descriptor(libusb_device
*dev
,
559 uint8_t config_index
, struct libusb_config_descriptor
**config
)
561 struct libusb_config_descriptor
*_config
;
562 unsigned char tmp
[8];
563 unsigned char *buf
= NULL
;
567 usbi_dbg("index %d", config_index
);
568 if (config_index
>= dev
->num_configurations
)
569 return LIBUSB_ERROR_NOT_FOUND
;
571 _config
= malloc(sizeof(*_config
));
573 return LIBUSB_ERROR_NO_MEM
;
575 r
= usbi_backend
->get_config_descriptor(dev
, config_index
, tmp
,
576 sizeof(tmp
), &host_endian
);
580 usbi_parse_descriptor(tmp
, "bbw", _config
, host_endian
);
581 buf
= malloc(_config
->wTotalLength
);
583 r
= LIBUSB_ERROR_NO_MEM
;
588 r
= usbi_backend
->get_config_descriptor(dev
, config_index
, buf
,
589 _config
->wTotalLength
, &host_endian
);
593 r
= parse_configuration(dev
->ctx
, _config
, buf
, host_endian
);
595 usbi_err(dev
->ctx
, "parse_configuration failed with error %d", r
);
598 usbi_warn(dev
->ctx
, "descriptor data still left");
612 /* iterate through all configurations, returning the index of the configuration
613 * matching a specific bConfigurationValue in the idx output parameter, or -1
614 * if the config was not found.
615 * returns 0 or a LIBUSB_ERROR code
617 int usbi_get_config_index_by_value(struct libusb_device
*dev
,
618 uint8_t bConfigurationValue
, int *idx
)
622 usbi_dbg("value %d", bConfigurationValue
);
623 for (i
= 0; i
< dev
->num_configurations
; i
++) {
624 unsigned char tmp
[6];
626 int r
= usbi_backend
->get_config_descriptor(dev
, i
, tmp
, sizeof(tmp
),
630 if (tmp
[5] == bConfigurationValue
) {
641 * Get a USB configuration descriptor with a specific bConfigurationValue.
642 * This is a non-blocking function which does not involve any requests being
643 * sent to the device.
645 * \param dev a device
646 * \param bConfigurationValue the bConfigurationValue of the configuration you
648 * \param config output location for the USB configuration descriptor. Only
649 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
651 * \returns 0 on success
652 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
653 * \returns another LIBUSB_ERROR code on error
654 * \see libusb_get_active_config_descriptor()
655 * \see libusb_get_config_descriptor()
657 int API_EXPORTED
libusb_get_config_descriptor_by_value(libusb_device
*dev
,
658 uint8_t bConfigurationValue
, struct libusb_config_descriptor
**config
)
661 int r
= usbi_get_config_index_by_value(dev
, bConfigurationValue
, &idx
);
665 return LIBUSB_ERROR_NOT_FOUND
;
667 return libusb_get_config_descriptor(dev
, (uint8_t) idx
, config
);
671 * Free a configuration descriptor obtained from
672 * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
673 * It is safe to call this function with a NULL config parameter, in which
674 * case the function simply returns.
676 * \param config the configuration descriptor to free
678 void API_EXPORTED
libusb_free_config_descriptor(
679 struct libusb_config_descriptor
*config
)
684 clear_configuration(config
);
689 * Retrieve a string descriptor in C style ASCII.
691 * Wrapper around libusb_get_string_descriptor(). Uses the first language
692 * supported by the device.
694 * \param dev a device handle
695 * \param desc_index the index of the descriptor to retrieve
696 * \param data output buffer for ASCII string descriptor
697 * \param length size of data buffer
698 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
700 int API_EXPORTED
libusb_get_string_descriptor_ascii(libusb_device_handle
*dev
,
701 uint8_t desc_index
, unsigned char *data
, int length
)
703 unsigned char tbuf
[255]; /* Some devices choke on size > 255 */
707 /* Asking for the zero'th index is special - it returns a string
708 * descriptor that contains all the language IDs supported by the
709 * device. Typically there aren't many - often only one. Language
710 * IDs are 16 bit numbers, and they start at the third byte in the
711 * descriptor. There's also no point in trying to read descriptor 0
712 * with this function. See USB 2.0 specification section 9.6.7 for
717 return LIBUSB_ERROR_INVALID_PARAM
;
719 r
= libusb_get_string_descriptor(dev
, 0, 0, tbuf
, sizeof(tbuf
));
724 return LIBUSB_ERROR_IO
;
726 langid
= tbuf
[2] | (tbuf
[3] << 8);
728 r
= libusb_get_string_descriptor(dev
, desc_index
, langid
, tbuf
,
733 if (tbuf
[1] != LIBUSB_DT_STRING
)
734 return LIBUSB_ERROR_IO
;
737 return LIBUSB_ERROR_IO
;
739 for (di
= 0, si
= 2; si
< tbuf
[0]; si
+= 2) {
740 if (di
>= (length
- 1))
743 if ((tbuf
[si
] & 0x80) || (tbuf
[si
+ 1])) /* non-ASCII */
746 data
[di
++] = tbuf
[si
];