linux: linux_parent_dev search for . from the right
[libusbx.git] / libusb / descriptor.c
blob90473527c73af427871672da83d02dea46e0bece
1 /* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
2 /*
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
22 #include <errno.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <string.h>
27 #include "libusbi.h"
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(unsigned char *source, const char *descriptor,
44 void *dest, int host_endian)
46 unsigned char *sp = source, *dp = dest;
47 uint16_t w;
48 const char *cp;
50 for (cp = descriptor; *cp; cp++) {
51 switch (*cp) {
52 case 'b': /* 8-bit byte */
53 *dp++ = *sp++;
54 break;
55 case 'w': /* 16-bit word, convert from little endian to CPU */
56 dp += ((uintptr_t)dp & 1); /* Align to word boundary */
58 if (host_endian) {
59 memcpy(dp, sp, 2);
60 } else {
61 w = (sp[1] << 8) | sp[0];
62 *((uint16_t *)dp) = w;
64 sp += 2;
65 dp += 2;
66 break;
70 return (int) (sp - source);
73 static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
75 if (endpoint->extra)
76 free((unsigned char *) endpoint->extra);
79 static int parse_endpoint(struct libusb_context *ctx,
80 struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer,
81 int size, int host_endian)
83 struct usb_descriptor_header header;
84 unsigned char *extra;
85 unsigned char *begin;
86 int parsed = 0;
87 int len;
89 usbi_parse_descriptor(buffer, "bb", &header, 0);
91 /* Everything should be fine being passed into here, but we sanity */
92 /* check JIC */
93 if (header.bLength > size) {
94 usbi_err(ctx, "ran out of descriptors parsing");
95 return -1;
98 if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) {
99 usbi_err(ctx, "unexpected descriptor %x (expected %x)",
100 header.bDescriptorType, LIBUSB_DT_ENDPOINT);
101 return parsed;
104 if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH)
105 usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian);
106 else if (header.bLength >= ENDPOINT_DESC_LENGTH)
107 usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian);
109 buffer += header.bLength;
110 size -= header.bLength;
111 parsed += header.bLength;
113 /* Skip over the rest of the Class Specific or Vendor Specific */
114 /* descriptors */
115 begin = buffer;
116 while (size >= DESC_HEADER_LENGTH) {
117 usbi_parse_descriptor(buffer, "bb", &header, 0);
119 if (header.bLength < 2) {
120 usbi_err(ctx, "invalid descriptor length %d", header.bLength);
121 return -1;
124 /* If we find another "proper" descriptor then we're done */
125 if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
126 (header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
127 (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
128 (header.bDescriptorType == LIBUSB_DT_DEVICE))
129 break;
131 usbi_dbg("skipping descriptor %x", header.bDescriptorType);
132 buffer += header.bLength;
133 size -= header.bLength;
134 parsed += header.bLength;
137 /* Copy any unknown descriptors into a storage area for drivers */
138 /* to later parse */
139 len = (int)(buffer - begin);
140 if (!len) {
141 endpoint->extra = NULL;
142 endpoint->extra_length = 0;
143 return parsed;
146 extra = malloc(len);
147 endpoint->extra = extra;
148 if (!extra) {
149 endpoint->extra_length = 0;
150 return LIBUSB_ERROR_NO_MEM;
153 memcpy(extra, begin, len);
154 endpoint->extra_length = len;
156 return parsed;
159 static void clear_interface(struct libusb_interface *usb_interface)
161 int i;
162 int j;
164 if (usb_interface->altsetting) {
165 for (i = 0; i < usb_interface->num_altsetting; i++) {
166 struct libusb_interface_descriptor *ifp =
167 (struct libusb_interface_descriptor *)
168 usb_interface->altsetting + i;
169 if (ifp->extra)
170 free((void *) ifp->extra);
171 if (ifp->endpoint) {
172 for (j = 0; j < ifp->bNumEndpoints; j++)
173 clear_endpoint((struct libusb_endpoint_descriptor *)
174 ifp->endpoint + j);
175 free((void *) ifp->endpoint);
178 free((void *) usb_interface->altsetting);
179 usb_interface->altsetting = NULL;
184 static int parse_interface(libusb_context *ctx,
185 struct libusb_interface *usb_interface, unsigned char *buffer, int size,
186 int host_endian)
188 int i;
189 int len;
190 int r;
191 int parsed = 0;
192 size_t tmp;
193 struct usb_descriptor_header header;
194 struct libusb_interface_descriptor *ifp;
195 unsigned char *begin;
197 usb_interface->num_altsetting = 0;
199 while (size >= INTERFACE_DESC_LENGTH) {
200 struct libusb_interface_descriptor *altsetting =
201 (struct libusb_interface_descriptor *) usb_interface->altsetting;
202 altsetting = usbi_reallocf(altsetting,
203 sizeof(struct libusb_interface_descriptor) *
204 (usb_interface->num_altsetting + 1));
205 if (!altsetting) {
206 r = LIBUSB_ERROR_NO_MEM;
207 goto err;
209 usb_interface->altsetting = altsetting;
211 ifp = altsetting + usb_interface->num_altsetting;
212 usb_interface->num_altsetting++;
213 usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0);
214 ifp->extra = NULL;
215 ifp->extra_length = 0;
216 ifp->endpoint = NULL;
218 /* Skip over the interface */
219 buffer += ifp->bLength;
220 parsed += ifp->bLength;
221 size -= ifp->bLength;
223 begin = buffer;
225 /* Skip over any interface, class or vendor descriptors */
226 while (size >= DESC_HEADER_LENGTH) {
227 usbi_parse_descriptor(buffer, "bb", &header, 0);
228 if (header.bLength < 2) {
229 usbi_err(ctx, "invalid descriptor of length %d",
230 header.bLength);
231 r = LIBUSB_ERROR_IO;
232 goto err;
233 } else if (header.bLength > size) {
234 usbi_warn(ctx, "invalid descriptor of length %d",
235 header.bLength);
236 /* The remaining bytes are bogus, but at least
237 * one interface is OK, so let's continue. */
238 break;
241 /* If we find another "proper" descriptor then we're done */
242 if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) ||
243 (header.bDescriptorType == LIBUSB_DT_ENDPOINT) ||
244 (header.bDescriptorType == LIBUSB_DT_CONFIG) ||
245 (header.bDescriptorType == LIBUSB_DT_DEVICE))
246 break;
248 buffer += header.bLength;
249 parsed += header.bLength;
250 size -= header.bLength;
253 /* Copy any unknown descriptors into a storage area for */
254 /* drivers to later parse */
255 len = (int)(buffer - begin);
256 if (len) {
257 ifp->extra = malloc(len);
258 if (!ifp->extra) {
259 r = LIBUSB_ERROR_NO_MEM;
260 goto err;
262 memcpy((unsigned char *) ifp->extra, begin, len);
263 ifp->extra_length = len;
266 /* Did we hit an unexpected descriptor? */
267 if (size >= DESC_HEADER_LENGTH) {
268 usbi_parse_descriptor(buffer, "bb", &header, 0);
269 if ((header.bDescriptorType == LIBUSB_DT_CONFIG) ||
270 (header.bDescriptorType == LIBUSB_DT_DEVICE)) {
271 return parsed;
275 if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
276 usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoints);
277 r = LIBUSB_ERROR_IO;
278 goto err;
281 if (ifp->bNumEndpoints > 0) {
282 struct libusb_endpoint_descriptor *endpoint;
283 tmp = ifp->bNumEndpoints * sizeof(struct libusb_endpoint_descriptor);
284 endpoint = malloc(tmp);
285 ifp->endpoint = endpoint;
286 if (!endpoint) {
287 r = LIBUSB_ERROR_NO_MEM;
288 goto err;
291 memset(endpoint, 0, tmp);
292 for (i = 0; i < ifp->bNumEndpoints; i++) {
293 usbi_parse_descriptor(buffer, "bb", &header, 0);
295 if (header.bLength > size) {
296 usbi_err(ctx, "ran out of descriptors parsing");
297 r = LIBUSB_ERROR_IO;
298 goto err;
301 r = parse_endpoint(ctx, endpoint + i, buffer, size,
302 host_endian);
303 if (r < 0)
304 goto err;
306 buffer += r;
307 parsed += r;
308 size -= r;
312 /* We check to see if it's an alternate to this one */
313 ifp = (struct libusb_interface_descriptor *) buffer;
314 if (size < LIBUSB_DT_INTERFACE_SIZE ||
315 ifp->bDescriptorType != LIBUSB_DT_INTERFACE ||
316 !ifp->bAlternateSetting)
317 return parsed;
320 return parsed;
321 err:
322 clear_interface(usb_interface);
323 return r;
326 static void clear_configuration(struct libusb_config_descriptor *config)
328 if (config->interface) {
329 int i;
330 for (i = 0; i < config->bNumInterfaces; i++)
331 clear_interface((struct libusb_interface *)
332 config->interface + i);
333 free((void *) config->interface);
335 if (config->extra)
336 free((void *) config->extra);
339 static int parse_configuration(struct libusb_context *ctx,
340 struct libusb_config_descriptor *config, unsigned char *buffer,
341 int host_endian)
343 int i;
344 int r;
345 int size;
346 size_t tmp;
347 struct usb_descriptor_header header;
348 struct libusb_interface *usb_interface;
350 usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian);
351 size = config->wTotalLength;
353 if (config->bNumInterfaces > USB_MAXINTERFACES) {
354 usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces);
355 return LIBUSB_ERROR_IO;
358 tmp = config->bNumInterfaces * sizeof(struct libusb_interface);
359 usb_interface = malloc(tmp);
360 config->interface = usb_interface;
361 if (!config->interface)
362 return LIBUSB_ERROR_NO_MEM;
364 memset(usb_interface, 0, tmp);
365 buffer += config->bLength;
366 size -= config->bLength;
368 config->extra = NULL;
369 config->extra_length = 0;
371 for (i = 0; i < config->bNumInterfaces; i++) {
372 int len;
373 unsigned char *begin;
375 /* Skip over the rest of the Class Specific or Vendor */
376 /* Specific descriptors */
377 begin = buffer;
378 while (size >= DESC_HEADER_LENGTH) {
379 usbi_parse_descriptor(buffer, "bb", &header, 0);
381 /* If we've parsed at least one config descriptor then
382 * let's return that. */
383 if (header.bLength > size && i) {
384 usbi_warn(ctx, "invalid descriptor length of %d",
385 header.bLength);
386 return size;
389 if ((header.bLength > size) ||
390 (header.bLength < DESC_HEADER_LENGTH)) {
391 usbi_err(ctx, "invalid descriptor length of %d",
392 header.bLength);
393 r = LIBUSB_ERROR_IO;
394 goto err;
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;
404 usbi_dbg("skipping descriptor 0x%x\n", header.bDescriptorType);
405 buffer += header.bLength;
406 size -= header.bLength;
409 /* Copy any unknown descriptors into a storage area for */
410 /* drivers to later parse */
411 len = (int)(buffer - begin);
412 if (len) {
413 /* FIXME: We should realloc and append here */
414 if (!config->extra_length) {
415 config->extra = malloc(len);
416 if (!config->extra) {
417 r = LIBUSB_ERROR_NO_MEM;
418 goto err;
421 memcpy((unsigned char *) config->extra, begin, len);
422 config->extra_length = len;
426 r = parse_interface(ctx, usb_interface + i, buffer, size, host_endian);
427 if (r < 0)
428 goto err;
430 buffer += r;
431 size -= r;
434 return size;
436 err:
437 clear_configuration(config);
438 return r;
441 int usbi_device_cache_descriptor(libusb_device *dev)
443 int r, host_endian;
445 r = usbi_backend->get_device_descriptor(dev, (unsigned char *) &dev->device_descriptor,
446 &host_endian);
447 if (r < 0)
448 return r;
450 if (!host_endian) {
451 dev->device_descriptor.bcdUSB = libusb_le16_to_cpu(dev->device_descriptor.bcdUSB);
452 dev->device_descriptor.idVendor = libusb_le16_to_cpu(dev->device_descriptor.idVendor);
453 dev->device_descriptor.idProduct = libusb_le16_to_cpu(dev->device_descriptor.idProduct);
454 dev->device_descriptor.bcdDevice = libusb_le16_to_cpu(dev->device_descriptor.bcdDevice);
457 return LIBUSB_SUCCESS;
460 /** \ingroup desc
461 * Get the USB device descriptor for a given device.
463 * This is a non-blocking function; the device descriptor is cached in memory.
465 * \param dev the device
466 * \param desc output location for the descriptor data
467 * \returns 0 on success or a LIBUSB_ERROR code on failure
469 int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
470 struct libusb_device_descriptor *desc)
472 usbi_dbg("");
473 memcpy((unsigned char *) desc, (unsigned char *) &dev->device_descriptor,
474 sizeof (dev->device_descriptor));
475 return 0;
478 /** \ingroup desc
479 * Get the USB configuration descriptor for the currently active configuration.
480 * This is a non-blocking function which does not involve any requests being
481 * sent to the device.
483 * \param dev a device
484 * \param config output location for the USB configuration descriptor. Only
485 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
486 * after use.
487 * \returns 0 on success
488 * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
489 * \returns another LIBUSB_ERROR code on error
490 * \see libusb_get_config_descriptor
492 int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
493 struct libusb_config_descriptor **config)
495 struct libusb_config_descriptor *_config = malloc(sizeof(*_config));
496 unsigned char tmp[8];
497 unsigned char *buf = NULL;
498 int host_endian = 0;
499 int r;
501 usbi_dbg("");
502 if (!_config)
503 return LIBUSB_ERROR_NO_MEM;
505 r = usbi_backend->get_active_config_descriptor(dev, tmp, sizeof(tmp),
506 &host_endian);
507 if (r < 0)
508 goto err;
510 _config->wTotalLength = 0;
511 usbi_parse_descriptor(tmp, "bbw", _config, host_endian);
512 if (_config->wTotalLength != 0)
513 buf = malloc(_config->wTotalLength);
514 if (!buf) {
515 r = LIBUSB_ERROR_NO_MEM;
516 goto err;
519 r = usbi_backend->get_active_config_descriptor(dev, buf,
520 _config->wTotalLength, &host_endian);
521 if (r < 0)
522 goto err;
524 r = parse_configuration(dev->ctx, _config, buf, host_endian);
525 if (r < 0) {
526 usbi_err(dev->ctx, "parse_configuration failed with error %d", r);
527 goto err;
528 } else if (r > 0) {
529 usbi_warn(dev->ctx, "descriptor data still left");
532 free(buf);
533 *config = _config;
534 return 0;
536 err:
537 free(_config);
538 if (buf)
539 free(buf);
540 return r;
543 /** \ingroup desc
544 * Get a USB configuration descriptor based on its index.
545 * This is a non-blocking function which does not involve any requests being
546 * sent to the device.
548 * \param dev a device
549 * \param config_index the index of the configuration you wish to retrieve
550 * \param config output location for the USB configuration descriptor. Only
551 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
552 * after use.
553 * \returns 0 on success
554 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
555 * \returns another LIBUSB_ERROR code on error
556 * \see libusb_get_active_config_descriptor()
557 * \see libusb_get_config_descriptor_by_value()
559 int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
560 uint8_t config_index, struct libusb_config_descriptor **config)
562 struct libusb_config_descriptor *_config;
563 unsigned char tmp[8];
564 unsigned char *buf = NULL;
565 int host_endian = 0;
566 int r;
568 usbi_dbg("index %d", config_index);
569 if (config_index >= dev->num_configurations)
570 return LIBUSB_ERROR_NOT_FOUND;
572 _config = malloc(sizeof(*_config));
573 if (!_config)
574 return LIBUSB_ERROR_NO_MEM;
576 r = usbi_backend->get_config_descriptor(dev, config_index, tmp,
577 sizeof(tmp), &host_endian);
578 if (r < 0)
579 goto err;
581 usbi_parse_descriptor(tmp, "bbw", _config, host_endian);
582 buf = malloc(_config->wTotalLength);
583 if (!buf) {
584 r = LIBUSB_ERROR_NO_MEM;
585 goto err;
588 host_endian = 0;
589 r = usbi_backend->get_config_descriptor(dev, config_index, buf,
590 _config->wTotalLength, &host_endian);
591 if (r < 0)
592 goto err;
594 r = parse_configuration(dev->ctx, _config, buf, host_endian);
595 if (r < 0) {
596 usbi_err(dev->ctx, "parse_configuration failed with error %d", r);
597 goto err;
598 } else if (r > 0) {
599 usbi_warn(dev->ctx, "descriptor data still left");
602 free(buf);
603 *config = _config;
604 return 0;
606 err:
607 free(_config);
608 if (buf)
609 free(buf);
610 return r;
613 /* iterate through all configurations, returning the index of the configuration
614 * matching a specific bConfigurationValue in the idx output parameter, or -1
615 * if the config was not found.
616 * returns 0 or a LIBUSB_ERROR code
618 int usbi_get_config_index_by_value(struct libusb_device *dev,
619 uint8_t bConfigurationValue, int *idx)
621 uint8_t i;
623 usbi_dbg("value %d", bConfigurationValue);
624 for (i = 0; i < dev->num_configurations; i++) {
625 unsigned char tmp[6];
626 int host_endian;
627 int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp),
628 &host_endian);
629 if (r < 0)
630 return r;
631 if (tmp[5] == bConfigurationValue) {
632 *idx = i;
633 return 0;
637 *idx = -1;
638 return 0;
641 /** \ingroup desc
642 * Get a USB configuration descriptor with a specific bConfigurationValue.
643 * This is a non-blocking function which does not involve any requests being
644 * sent to the device.
646 * \param dev a device
647 * \param bConfigurationValue the bConfigurationValue of the configuration you
648 * wish to retrieve
649 * \param config output location for the USB configuration descriptor. Only
650 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
651 * after use.
652 * \returns 0 on success
653 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
654 * \returns another LIBUSB_ERROR code on error
655 * \see libusb_get_active_config_descriptor()
656 * \see libusb_get_config_descriptor()
658 int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
659 uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
661 int idx;
662 int r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx);
663 if (r < 0)
664 return r;
665 else if (idx == -1)
666 return LIBUSB_ERROR_NOT_FOUND;
667 else
668 return libusb_get_config_descriptor(dev, (uint8_t) idx, config);
671 /** \ingroup desc
672 * Free a configuration descriptor obtained from
673 * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
674 * It is safe to call this function with a NULL config parameter, in which
675 * case the function simply returns.
677 * \param config the configuration descriptor to free
679 void API_EXPORTED libusb_free_config_descriptor(
680 struct libusb_config_descriptor *config)
682 if (!config)
683 return;
685 clear_configuration(config);
686 free(config);
689 /** \ingroup desc
690 * Retrieve a string descriptor in C style ASCII.
692 * Wrapper around libusb_get_string_descriptor(). Uses the first language
693 * supported by the device.
695 * \param dev a device handle
696 * \param desc_index the index of the descriptor to retrieve
697 * \param data output buffer for ASCII string descriptor
698 * \param length size of data buffer
699 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
701 int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
702 uint8_t desc_index, unsigned char *data, int length)
704 unsigned char tbuf[255]; /* Some devices choke on size > 255 */
705 int r, si, di;
706 uint16_t langid;
708 /* Asking for the zero'th index is special - it returns a string
709 * descriptor that contains all the language IDs supported by the
710 * device. Typically there aren't many - often only one. Language
711 * IDs are 16 bit numbers, and they start at the third byte in the
712 * descriptor. There's also no point in trying to read descriptor 0
713 * with this function. See USB 2.0 specification section 9.6.7 for
714 * more information.
717 if (desc_index == 0)
718 return LIBUSB_ERROR_INVALID_PARAM;
720 r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf));
721 if (r < 0)
722 return r;
724 if (r < 4)
725 return LIBUSB_ERROR_IO;
727 langid = tbuf[2] | (tbuf[3] << 8);
729 r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf,
730 sizeof(tbuf));
731 if (r < 0)
732 return r;
734 if (tbuf[1] != LIBUSB_DT_STRING)
735 return LIBUSB_ERROR_IO;
737 if (tbuf[0] > r)
738 return LIBUSB_ERROR_IO;
740 for (di = 0, si = 2; si < tbuf[0]; si += 2) {
741 if (di >= (length - 1))
742 break;
744 if ((tbuf[si] & 0x80) || (tbuf[si + 1])) /* non-ASCII */
745 data[di++] = '?';
746 else
747 data[di++] = tbuf[si];
750 data[di] = 0;
751 return di;