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
= realloc(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",
234 /* If we find another "proper" descriptor then we're done */
235 if ((header
.bDescriptorType
== LIBUSB_DT_INTERFACE
) ||
236 (header
.bDescriptorType
== LIBUSB_DT_ENDPOINT
) ||
237 (header
.bDescriptorType
== LIBUSB_DT_CONFIG
) ||
238 (header
.bDescriptorType
== LIBUSB_DT_DEVICE
))
241 buffer
+= header
.bLength
;
242 parsed
+= header
.bLength
;
243 size
-= header
.bLength
;
246 /* Copy any unknown descriptors into a storage area for */
247 /* drivers to later parse */
248 len
= (int)(buffer
- begin
);
250 ifp
->extra
= malloc(len
);
252 r
= LIBUSB_ERROR_NO_MEM
;
255 memcpy((unsigned char *) ifp
->extra
, begin
, len
);
256 ifp
->extra_length
= len
;
259 /* Did we hit an unexpected descriptor? */
260 if (size
>= DESC_HEADER_LENGTH
) {
261 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
262 if ((header
.bDescriptorType
== LIBUSB_DT_CONFIG
) ||
263 (header
.bDescriptorType
== LIBUSB_DT_DEVICE
)) {
268 if (ifp
->bNumEndpoints
> USB_MAXENDPOINTS
) {
269 usbi_err(ctx
, "too many endpoints (%d)", ifp
->bNumEndpoints
);
274 if (ifp
->bNumEndpoints
> 0) {
275 struct libusb_endpoint_descriptor
*endpoint
;
276 tmp
= ifp
->bNumEndpoints
* sizeof(struct libusb_endpoint_descriptor
);
277 endpoint
= malloc(tmp
);
278 ifp
->endpoint
= endpoint
;
280 r
= LIBUSB_ERROR_NO_MEM
;
284 memset(endpoint
, 0, tmp
);
285 for (i
= 0; i
< ifp
->bNumEndpoints
; i
++) {
286 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
288 if (header
.bLength
> size
) {
289 usbi_err(ctx
, "ran out of descriptors parsing");
294 r
= parse_endpoint(ctx
, endpoint
+ i
, buffer
, size
,
305 /* We check to see if it's an alternate to this one */
306 ifp
= (struct libusb_interface_descriptor
*) buffer
;
307 if (size
< LIBUSB_DT_INTERFACE_SIZE
||
308 ifp
->bDescriptorType
!= LIBUSB_DT_INTERFACE
||
309 !ifp
->bAlternateSetting
)
315 clear_interface(usb_interface
);
319 static void clear_configuration(struct libusb_config_descriptor
*config
)
321 if (config
->interface
) {
323 for (i
= 0; i
< config
->bNumInterfaces
; i
++)
324 clear_interface((struct libusb_interface
*)
325 config
->interface
+ i
);
326 free((void *) config
->interface
);
329 free((void *) config
->extra
);
332 static int parse_configuration(struct libusb_context
*ctx
,
333 struct libusb_config_descriptor
*config
, unsigned char *buffer
,
340 struct usb_descriptor_header header
;
341 struct libusb_interface
*usb_interface
;
343 usbi_parse_descriptor(buffer
, "bbwbbbbb", config
, host_endian
);
344 size
= config
->wTotalLength
;
346 if (config
->bNumInterfaces
> USB_MAXINTERFACES
) {
347 usbi_err(ctx
, "too many interfaces (%d)", config
->bNumInterfaces
);
348 return LIBUSB_ERROR_IO
;
351 tmp
= config
->bNumInterfaces
* sizeof(struct libusb_interface
);
352 usb_interface
= malloc(tmp
);
353 config
->interface
= usb_interface
;
354 if (!config
->interface
)
355 return LIBUSB_ERROR_NO_MEM
;
357 memset(usb_interface
, 0, tmp
);
358 buffer
+= config
->bLength
;
359 size
-= config
->bLength
;
361 config
->extra
= NULL
;
362 config
->extra_length
= 0;
364 for (i
= 0; i
< config
->bNumInterfaces
; i
++) {
366 unsigned char *begin
;
368 /* Skip over the rest of the Class Specific or Vendor */
369 /* Specific descriptors */
371 while (size
>= DESC_HEADER_LENGTH
) {
372 usbi_parse_descriptor(buffer
, "bb", &header
, 0);
374 if ((header
.bLength
> size
) ||
375 (header
.bLength
< DESC_HEADER_LENGTH
)) {
376 usbi_err(ctx
, "invalid descriptor length of %d",
382 /* If we find another "proper" descriptor then we're done */
383 if ((header
.bDescriptorType
== LIBUSB_DT_ENDPOINT
) ||
384 (header
.bDescriptorType
== LIBUSB_DT_INTERFACE
) ||
385 (header
.bDescriptorType
== LIBUSB_DT_CONFIG
) ||
386 (header
.bDescriptorType
== LIBUSB_DT_DEVICE
))
389 usbi_dbg("skipping descriptor 0x%x\n", header
.bDescriptorType
);
390 buffer
+= header
.bLength
;
391 size
-= header
.bLength
;
394 /* Copy any unknown descriptors into a storage area for */
395 /* drivers to later parse */
396 len
= (int)(buffer
- begin
);
398 /* FIXME: We should realloc and append here */
399 if (!config
->extra_length
) {
400 config
->extra
= malloc(len
);
401 if (!config
->extra
) {
402 r
= LIBUSB_ERROR_NO_MEM
;
406 memcpy((unsigned char *) config
->extra
, begin
, len
);
407 config
->extra_length
= len
;
411 r
= parse_interface(ctx
, usb_interface
+ i
, buffer
, size
, host_endian
);
422 clear_configuration(config
);
427 * Get the USB device descriptor for a given device.
429 * This is a non-blocking function; the device descriptor is cached in memory.
431 * \param dev the device
432 * \param desc output location for the descriptor data
433 * \returns 0 on success or a LIBUSB_ERROR code on failure
435 int API_EXPORTED
libusb_get_device_descriptor(libusb_device
*dev
,
436 struct libusb_device_descriptor
*desc
)
438 unsigned char raw_desc
[DEVICE_DESC_LENGTH
];
443 r
= usbi_backend
->get_device_descriptor(dev
, raw_desc
, &host_endian
);
447 memcpy((unsigned char *) desc
, raw_desc
, sizeof(raw_desc
));
449 desc
->bcdUSB
= libusb_le16_to_cpu(desc
->bcdUSB
);
450 desc
->idVendor
= libusb_le16_to_cpu(desc
->idVendor
);
451 desc
->idProduct
= libusb_le16_to_cpu(desc
->idProduct
);
452 desc
->bcdDevice
= libusb_le16_to_cpu(desc
->bcdDevice
);
458 * Get the USB configuration descriptor for the currently active configuration.
459 * This is a non-blocking function which does not involve any requests being
460 * sent to the device.
462 * \param dev a device
463 * \param config output location for the USB configuration descriptor. Only
464 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
466 * \returns 0 on success
467 * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
468 * \returns another LIBUSB_ERROR code on error
469 * \see libusb_get_config_descriptor
471 int API_EXPORTED
libusb_get_active_config_descriptor(libusb_device
*dev
,
472 struct libusb_config_descriptor
**config
)
474 struct libusb_config_descriptor
*_config
= malloc(sizeof(*_config
));
475 unsigned char tmp
[8];
476 unsigned char *buf
= NULL
;
482 return LIBUSB_ERROR_NO_MEM
;
484 r
= usbi_backend
->get_active_config_descriptor(dev
, tmp
, sizeof(tmp
),
489 usbi_parse_descriptor(tmp
, "bbw", _config
, host_endian
);
490 buf
= malloc(_config
->wTotalLength
);
492 r
= LIBUSB_ERROR_NO_MEM
;
496 r
= usbi_backend
->get_active_config_descriptor(dev
, buf
,
497 _config
->wTotalLength
, &host_endian
);
501 r
= parse_configuration(dev
->ctx
, _config
, buf
, host_endian
);
503 usbi_err(dev
->ctx
, "parse_configuration failed with error %d", r
);
506 usbi_warn(dev
->ctx
, "descriptor data still left");
521 * Get a USB configuration descriptor based on its index.
522 * This is a non-blocking function which does not involve any requests being
523 * sent to the device.
525 * \param dev a device
526 * \param config_index the index of the configuration you wish to retrieve
527 * \param config output location for the USB configuration descriptor. Only
528 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
530 * \returns 0 on success
531 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
532 * \returns another LIBUSB_ERROR code on error
533 * \see libusb_get_active_config_descriptor()
534 * \see libusb_get_config_descriptor_by_value()
536 int API_EXPORTED
libusb_get_config_descriptor(libusb_device
*dev
,
537 uint8_t config_index
, struct libusb_config_descriptor
**config
)
539 struct libusb_config_descriptor
*_config
;
540 unsigned char tmp
[8];
541 unsigned char *buf
= NULL
;
545 usbi_dbg("index %d", config_index
);
546 if (config_index
>= dev
->num_configurations
)
547 return LIBUSB_ERROR_NOT_FOUND
;
549 _config
= malloc(sizeof(*_config
));
551 return LIBUSB_ERROR_NO_MEM
;
553 r
= usbi_backend
->get_config_descriptor(dev
, config_index
, tmp
,
554 sizeof(tmp
), &host_endian
);
558 usbi_parse_descriptor(tmp
, "bbw", _config
, host_endian
);
559 buf
= malloc(_config
->wTotalLength
);
561 r
= LIBUSB_ERROR_NO_MEM
;
566 r
= usbi_backend
->get_config_descriptor(dev
, config_index
, buf
,
567 _config
->wTotalLength
, &host_endian
);
571 r
= parse_configuration(dev
->ctx
, _config
, buf
, host_endian
);
573 usbi_err(dev
->ctx
, "parse_configuration failed with error %d", r
);
576 usbi_warn(dev
->ctx
, "descriptor data still left");
590 /* iterate through all configurations, returning the index of the configuration
591 * matching a specific bConfigurationValue in the idx output parameter, or -1
592 * if the config was not found.
593 * returns 0 or a LIBUSB_ERROR code
595 int usbi_get_config_index_by_value(struct libusb_device
*dev
,
596 uint8_t bConfigurationValue
, int *idx
)
600 usbi_dbg("value %d", bConfigurationValue
);
601 for (i
= 0; i
< dev
->num_configurations
; i
++) {
602 unsigned char tmp
[6];
604 int r
= usbi_backend
->get_config_descriptor(dev
, i
, tmp
, sizeof(tmp
),
608 if (tmp
[5] == bConfigurationValue
) {
619 * Get a USB configuration descriptor with a specific bConfigurationValue.
620 * This is a non-blocking function which does not involve any requests being
621 * sent to the device.
623 * \param dev a device
624 * \param bConfigurationValue the bConfigurationValue of the configuration you
626 * \param config output location for the USB configuration descriptor. Only
627 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
629 * \returns 0 on success
630 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
631 * \returns another LIBUSB_ERROR code on error
632 * \see libusb_get_active_config_descriptor()
633 * \see libusb_get_config_descriptor()
635 int API_EXPORTED
libusb_get_config_descriptor_by_value(libusb_device
*dev
,
636 uint8_t bConfigurationValue
, struct libusb_config_descriptor
**config
)
639 int r
= usbi_get_config_index_by_value(dev
, bConfigurationValue
, &idx
);
643 return LIBUSB_ERROR_NOT_FOUND
;
645 return libusb_get_config_descriptor(dev
, (uint8_t) idx
, config
);
649 * Free a configuration descriptor obtained from
650 * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
651 * It is safe to call this function with a NULL config parameter, in which
652 * case the function simply returns.
654 * \param config the configuration descriptor to free
656 void API_EXPORTED
libusb_free_config_descriptor(
657 struct libusb_config_descriptor
*config
)
662 clear_configuration(config
);
667 * Retrieve a string descriptor in C style ASCII.
669 * Wrapper around libusb_get_string_descriptor(). Uses the first language
670 * supported by the device.
672 * \param dev a device handle
673 * \param desc_index the index of the descriptor to retrieve
674 * \param data output buffer for ASCII string descriptor
675 * \param length size of data buffer
676 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
678 int API_EXPORTED
libusb_get_string_descriptor_ascii(libusb_device_handle
*dev
,
679 uint8_t desc_index
, unsigned char *data
, int length
)
681 unsigned char tbuf
[255]; /* Some devices choke on size > 255 */
685 /* Asking for the zero'th index is special - it returns a string
686 * descriptor that contains all the language IDs supported by the
687 * device. Typically there aren't many - often only one. Language
688 * IDs are 16 bit numbers, and they start at the third byte in the
689 * descriptor. There's also no point in trying to read descriptor 0
690 * with this function. See USB 2.0 specification section 9.6.7 for
695 return LIBUSB_ERROR_INVALID_PARAM
;
697 r
= libusb_get_string_descriptor(dev
, 0, 0, tbuf
, sizeof(tbuf
));
702 return LIBUSB_ERROR_IO
;
704 langid
= tbuf
[2] | (tbuf
[3] << 8);
706 r
= libusb_get_string_descriptor(dev
, desc_index
, langid
, tbuf
,
711 if (tbuf
[1] != LIBUSB_DT_STRING
)
712 return LIBUSB_ERROR_IO
;
715 return LIBUSB_ERROR_IO
;
717 for (di
= 0, si
= 2; si
< tbuf
[0]; si
+= 2) {
718 if (di
>= (length
- 1))
721 if (tbuf
[si
+ 1]) /* high byte */
724 data
[di
++] = tbuf
[si
];