2 * modified to improve compatibility with some cameras.
3 * Copyright(c) 2014 saki saki@serenegiant.com
5 /* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
7 * USB descriptor handling functions for libusb
8 * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
9 * Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 // comment out because duplicate definitions already exit in libusb.h
34 //#define DESC_HEADER_LENGTH 2 // XXX this is same as LIBUSB_DT_HEADER_SIZE in libusb.h
35 //#define DEVICE_DESC_LENGTH 18 // XXX this is same as LIBUSB_DT_DEVICE_SIZE in libusb.h
36 //#define CONFIG_DESC_LENGTH 9 // XXX this is same as LIBUSB_DT_CONFIG_SIZE in libusb.h
37 //#define INTERFACE_DESC_LENGTH 9 // XXX this is same as LIBUSB_DT_INTERFACE_SIZE in libusb.h
38 //#define ENDPOINT_DESC_LENGTH 7 // XXX this is same as LIBUSB_DT_ENDPOINT_SIZE in libusb.h
39 //#define ENDPOINT_AUDIO_DESC_LENGTH 9 // XXX this is same as LIBUSB_DT_ENDPOINT_AUDIO_SIZE in libusb.h
40 //#define ASSOCIATION_DESC_LENGTH 8 // XXX this is same as LIBUSB_DT_ASSOCIATION_SIZE in libusb.h
42 /** @defgroup desc USB descriptors
43 * This page details how to examine the various standard USB descriptors
44 * for detected devices
47 static inline int is_known_descriptor_type(int type) {
48 return ((type == LIBUSB_DT_ENDPOINT)
49 || (type == LIBUSB_DT_INTERFACE)
50 || (type == LIBUSB_DT_CONFIG)
51 || (type == LIBUSB_DT_DEVICE)
52 || (type == LIBUSB_DT_ASSOCIATION) );
55 /* set host_endian if the w values are already in host endian format,
56 * as opposed to bus endian. */
57 int usbi_parse_descriptor(const unsigned char *source, const char *descriptor,
58 void *dest, int host_endian)
60 const unsigned char *sp = source;
61 unsigned char *dp = dest;
66 for (cp = descriptor; *cp; cp++) {
68 case 'b': /* 8-bit byte */
71 case 'w': /* 16-bit word, convert from little endian to CPU */
72 dp += ((uintptr_t)dp & 1); /* Align to word boundary */
77 w = (sp[1] << 8) | sp[0];
78 *((uint16_t *)dp) = w;
83 case 'd': /* 32-bit word, convert from little endian to CPU */
84 dp += ((uintptr_t)dp & 1); /* Align to word boundary */
89 d = (sp[3] << 24) | (sp[2] << 16) |
91 *((uint32_t *)dp) = d;
96 case 'u': /* 16 byte UUID */
104 return (int) (sp - source);
107 static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint)
109 if LIKELY(endpoint && endpoint->extra) {
110 free((unsigned char *) endpoint->extra);
111 endpoint->extra = NULL; // XXX
112 endpoint->extra_length = 0;
116 static int parse_endpoint(struct libusb_context *ctx,
117 struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer,
118 int size, int host_endian)
122 struct usb_descriptor_header header;
123 unsigned char *extra;
124 unsigned char *begin;
128 if UNLIKELY(size < LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/) {
129 usbi_err(ctx, "short endpoint descriptor read %d/%d",
130 size, LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/);
131 RETURN(LIBUSB_ERROR_IO, int);
134 usbi_parse_descriptor(buffer, "bb", &header, 0);
135 if UNLIKELY(header.bDescriptorType != LIBUSB_DT_ENDPOINT) {
136 usbi_err(ctx, "unexpected descriptor %x (expected %x)",
137 header.bDescriptorType, LIBUSB_DT_ENDPOINT);
140 if UNLIKELY(header.bLength > size) {
141 usbi_warn(ctx, "short endpoint descriptor read %d/%d",
142 size, header.bLength);
145 if (header.bLength >= LIBUSB_DT_ENDPOINT_AUDIO_SIZE/*ENDPOINT_AUDIO_DESC_LENGTH*/)
146 usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian);
147 else if (header.bLength >= LIBUSB_DT_ENDPOINT_SIZE/*ENDPOINT_DESC_LENGTH*/)
148 usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian);
150 usbi_err(ctx, "invalid endpoint bLength (%d)", header.bLength);
151 RETURN(LIBUSB_ERROR_IO, int);
154 buffer += header.bLength;
155 size -= header.bLength;
156 parsed += header.bLength;
158 /* Skip over the rest of the Class Specific or Vendor Specific */
161 while (size >= LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/) {
162 usbi_parse_descriptor(buffer, "bb", &header, 0);
163 if UNLIKELY(header.bLength < LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/) {
164 usbi_err(ctx, "invalid extra ep desc len (%d)",
166 RETURN(LIBUSB_ERROR_IO, int);
167 } else if (header.bLength > size) {
168 usbi_warn(ctx, "short extra ep desc read %d/%d",
169 size, header.bLength);
173 /* If we find another "proper" descriptor then we're done */
174 if (is_known_descriptor_type(header.bDescriptorType))
177 usbi_dbg("skipping descriptor 0x%02x", header.bDescriptorType);
178 buffer += header.bLength;
179 size -= header.bLength;
180 parsed += header.bLength;
183 /* Copy any unknown descriptors into a storage area for drivers */
185 len = (int)(buffer - begin);
187 endpoint->extra = NULL;
188 endpoint->extra_length = 0;
192 endpoint->extra = extra = malloc(len);
193 if UNLIKELY(!extra) {
194 endpoint->extra_length = 0;
195 RETURN(LIBUSB_ERROR_NO_MEM, int);
198 memcpy(extra, begin, len);
199 endpoint->extra_length = len;
204 static void clear_interface(struct libusb_interface *usb_interface)
209 if (usb_interface->altsetting) {
210 for (i = 0; i < usb_interface->num_altsetting; i++) {
211 struct libusb_interface_descriptor *ifp =
212 (struct libusb_interface_descriptor *)
213 usb_interface->altsetting + i;
215 free((void *) ifp->extra);
217 for (j = 0; j < ifp->bNumEndpoints; j++)
218 clear_endpoint((struct libusb_endpoint_descriptor *)
220 free((void *) ifp->endpoint);
223 free((void *) usb_interface->altsetting);
224 usb_interface->altsetting = NULL;
229 static int parse_interface(libusb_context *ctx,
230 struct libusb_interface *usb_interface, unsigned char *buffer, int size,
239 int interface_number = -1;
241 struct usb_descriptor_header header;
242 struct libusb_interface_descriptor *ifp;
243 unsigned char *begin;
245 usb_interface->num_altsetting = 0;
247 while (size >= LIBUSB_DT_INTERFACE_SIZE/*INTERFACE_DESC_LENGTH*/) {
248 struct libusb_interface_descriptor *altsetting =
249 (struct libusb_interface_descriptor *) usb_interface->altsetting;
250 altsetting = usbi_reallocf(altsetting,
251 sizeof(struct libusb_interface_descriptor) * (usb_interface->num_altsetting + 1));
252 if UNLIKELY(!altsetting) {
253 r = LIBUSB_ERROR_NO_MEM;
256 usb_interface->altsetting = altsetting;
258 ifp = altsetting + usb_interface->num_altsetting;
259 usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0);
260 if UNLIKELY(ifp->bDescriptorType != LIBUSB_DT_INTERFACE) {
261 usbi_err(ctx, "unexpected descriptor %x (expected %x)",
262 ifp->bDescriptorType, LIBUSB_DT_INTERFACE);
265 if UNLIKELY(ifp->bLength < LIBUSB_DT_INTERFACE_SIZE/*INTERFACE_DESC_LENGTH*/) {
266 usbi_err(ctx, "invalid interface bLength (%d)",
271 if UNLIKELY(ifp->bLength > size) {
272 usbi_warn(ctx, "short intf descriptor read %d/%d",
276 if UNLIKELY(ifp->bNumEndpoints > USB_MAXENDPOINTS) {
277 usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoints);
282 usb_interface->num_altsetting++;
284 ifp->extra_length = 0;
285 ifp->endpoint = NULL;
287 if (interface_number == -1)
288 interface_number = ifp->bInterfaceNumber;
290 /* Skip over the interface */
291 buffer += ifp->bLength;
292 parsed += ifp->bLength;
293 size -= ifp->bLength;
297 /* Skip over any interface, class or vendor descriptors */
298 while (size >= LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/) {
299 usbi_parse_descriptor(buffer, "bb", &header, 0);
300 if UNLIKELY(header.bLength < LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/) {
302 "invalid extra intf desc len (%d)",
306 } else if (header.bLength > size) {
308 "short extra intf desc read %d/%d",
309 size, header.bLength);
313 MARK("bDescriptorType=0x%02x", header.bDescriptorType);
314 /* If we find another "proper" descriptor then we're done */
315 if (is_known_descriptor_type(header.bDescriptorType))
318 buffer += header.bLength;
319 parsed += header.bLength;
320 size -= header.bLength;
323 /* Copy any unknown descriptors into a storage area for */
324 /* drivers to later parse */
325 len = (int)(buffer - begin);
327 MARK("save unknown descriptors into ifp->extra:lebgth=%d", len);
328 ifp->extra = usbi_reallocf((unsigned char *)ifp->extra, ifp->extra_length + len);
329 if UNLIKELY(!ifp->extra) {
330 r = LIBUSB_ERROR_NO_MEM;
333 memcpy((unsigned char *)(ifp->extra + ifp->extra_length), begin, len);
334 ifp->extra_length += len;
337 MARK("bNumEndpoints=%d", ifp->bNumEndpoints);
338 if (ifp->bNumEndpoints > 0) {
339 struct libusb_endpoint_descriptor *endpoint;
340 tmp = ifp->bNumEndpoints * sizeof(struct libusb_endpoint_descriptor);
341 ifp->endpoint = endpoint = malloc(tmp);
342 if UNLIKELY(!endpoint) {
343 r = LIBUSB_ERROR_NO_MEM;
347 memset(endpoint, 0, tmp);
348 for (i = 0; i < ifp->bNumEndpoints; i++) {
349 MARK("parse endpoint%d", i);
350 r = parse_endpoint(ctx, endpoint + i, buffer, size,
355 ifp->bNumEndpoints = (uint8_t)i;
365 /* We check to see if it's an alternate to this one */
366 ifp = (struct libusb_interface_descriptor *) buffer;
367 if (size < LIBUSB_DT_INTERFACE_SIZE ||
368 ifp->bDescriptorType != LIBUSB_DT_INTERFACE ||
369 ifp->bInterfaceNumber != interface_number)
375 clear_interface(usb_interface);
379 static void clear_association(struct libusb_association_descriptor *association) {
380 if LIKELY(association && association->extra) {
381 free((unsigned char *) association->extra);
382 association->extra = NULL;
383 association->extra_length = 0;
387 static int parse_association(struct libusb_context *ctx,
388 struct libusb_config_descriptor *config, unsigned char *buffer,
389 int size, int host_endian) {
393 struct usb_descriptor_header header;
394 struct libusb_association_descriptor *association, *temp;
395 unsigned char *begin;
399 if UNLIKELY(size < LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/) {
400 usbi_err(ctx, "short association descriptor read %d/%d",
401 size, LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/);
402 RETURN(LIBUSB_ERROR_IO, int);
404 // ディスクリプタの先頭2バイトだけ解析して長さとディスクリプタの種類を取得
405 usbi_parse_descriptor(buffer, "bb", &header, 0);
406 if UNLIKELY(header.bDescriptorType != LIBUSB_DT_ASSOCIATION) { // 種類が違う時
407 usbi_err(ctx, "unexpected descriptor %x (expected %x)",
408 header.bDescriptorType, LIBUSB_DT_ASSOCIATION);
409 RETURN(parsed, int); // return 0;
411 if UNLIKELY(header.bLength > size) { // IADに長さが足りない時
412 usbi_warn(ctx, "short association descriptor read %d/%d",
413 size, header.bLength);
414 RETURN(parsed, int); // return 0;
416 if (header.bLength >= LIBUSB_DT_ASSOCIATION_SIZE/*ASSOCIATION_DESC_LENGTH*/) {
417 config->association_descriptor = usbi_reallocf(config->association_descriptor,
418 sizeof(struct libusb_association_descriptor) * (config->num_associations + 1));
419 if UNLIKELY(!config->association_descriptor) {
420 parsed = LIBUSB_ERROR_NO_MEM;
423 association = config->association_descriptor + config->num_associations;
424 association->extra = NULL;
425 association->extra_length = 0;
426 len = usbi_parse_descriptor(buffer, "bbbbbbbb", association, host_endian);
428 config->num_associations++;
430 LOGI("\t association:bLength=%d", association->bLength);
431 LOGI("\t association:bDescriptorType=0x%02d", association->bDescriptorType);
432 LOGI("\t association:bFirstInterface=%d", association->bFirstInterface);
433 LOGI("\t association:bInterfaceCount=%d", association->bInterfaceCount);
434 LOGI("\t association:bFunctionClass=0x%02x", association->bFunctionClass);
435 LOGI("\t association:bFunctionSubClass=0x%02x", association->bFunctionSubClass);
436 LOGI("\t association:bFunctionProtocol=0x%02x", association->bFunctionProtocol);
437 LOGI("\t association:iFunction=%d", association->iFunction);
441 config->association_descriptor = usbi_reallocf(association,
442 sizeof(struct libusb_association_descriptor) * config->num_associations);
445 // 種類はIADで有るにも関わらず長さが足りない時
446 usbi_err(ctx, "invalid interface association descriptor bLength (%d)", header.bLength);
447 RETURN(LIBUSB_ERROR_IO, int);
449 // 次の解析開始位置・残りサイズをセット
450 buffer += header.bLength;
451 size -= header.bLength;
452 parsed += header.bLength;
454 /* Skip over the rest of the Class Specific or Vendor Specific descriptors */
456 while (size >= LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/) {
457 usbi_parse_descriptor(buffer, "bb", &header, 0);
458 if UNLIKELY(header.bLength < LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/) {
459 usbi_err(ctx, "invalid extra ia desc len (%d)",
461 RETURN(LIBUSB_ERROR_IO, int);
462 } else if (header.bLength > size) {
463 usbi_warn(ctx, "short extra ia desc read %d/%d",
464 size, header.bLength);
468 MARK("bDescriptorType=0x%02x", header.bDescriptorType);
469 /* If we find another "proper" descriptor then we're done */
470 if (is_known_descriptor_type(header.bDescriptorType))
473 usbi_dbg("skipping descriptor 0x%02x", header.bDescriptorType);
474 buffer += header.bLength;
475 size -= header.bLength;
476 parsed += header.bLength;
479 // Append/Copy any unknown descriptors into a storage area for drivers to later parse
480 len = (int)(buffer - begin);
485 MARK("save unknown descriptors into config->extra:length=%d", len);
486 config->extra = usbi_reallocf((unsigned char *)config->extra, config->extra_length + len);
487 if UNLIKELY(!config->extra) {
488 config->extra_length = 0;
489 RETURN(LIBUSB_ERROR_NO_MEM, int);
491 memcpy((unsigned char *)config->extra + config->extra_length, begin, len);
492 config->extra_length += len;
496 clear_association(config->association_descriptor);
497 config->association_descriptor = NULL;
501 static void clear_configuration(struct libusb_config_descriptor *config)
503 if UNLIKELY(!config) return;
505 if LIKELY(config->interface) {
507 for (i = 0; i < config->bNumInterfaces; i++)
508 clear_interface((struct libusb_interface *)
509 config->interface + i);
510 free((void *) config->interface);
511 config->interface = NULL; // XXX
514 free((void *) config->extra);
515 config->extra = NULL; // XXX
517 if LIKELY(config->association_descriptor) {
519 for (i = 0; i < config->num_associations; i++)
520 clear_association(config->association_descriptor + i);
521 free((void *)config->association_descriptor);
522 config->association_descriptor = NULL;
526 static int parse_configuration(struct libusb_context *ctx,
527 struct libusb_config_descriptor *config, unsigned char *buffer,
528 int size, int host_endian) {
535 struct usb_descriptor_header header;
536 struct libusb_interface *usb_interface;
537 struct libusb_association_descriptor *association_desc;
539 if UNLIKELY(size < LIBUSB_DT_CONFIG_SIZE) {
540 usbi_err(ctx, "short config descriptor read %d/%d",
541 size, LIBUSB_DT_CONFIG_SIZE);
542 RETURN(LIBUSB_ERROR_IO, int);
545 usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian);
546 if UNLIKELY(config->bDescriptorType != LIBUSB_DT_CONFIG) {
547 usbi_err(ctx, "unexpected descriptor %x (expected %x)",
548 config->bDescriptorType, LIBUSB_DT_CONFIG);
549 RETURN(LIBUSB_ERROR_IO, int);
551 if UNLIKELY(config->bLength < LIBUSB_DT_CONFIG_SIZE) {
552 usbi_err(ctx, "invalid config bLength (%d)", config->bLength);
553 RETURN(LIBUSB_ERROR_IO, int);
555 if UNLIKELY(config->bLength > size) {
556 usbi_err(ctx, "short config descriptor read %d/%d",
557 size, config->bLength);
558 RETURN(LIBUSB_ERROR_IO, int);
560 if UNLIKELY(config->bNumInterfaces > USB_MAXINTERFACES) {
561 usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces);
562 RETURN(LIBUSB_ERROR_IO, int);
564 // インターフェースディスクリプタ配列を確保(長さはconfig->bNumInterfaces)
565 tmp = config->bNumInterfaces * sizeof(struct libusb_interface);
566 config->interface = usb_interface = malloc(tmp);
567 // インターフェースディスクリプタ配列を確保できなかった
568 if UNLIKELY(!config->interface)
569 RETURN(LIBUSB_ERROR_NO_MEM, int);
571 config->association_descriptor = NULL;
572 config->num_associations = 0;
574 memset(usb_interface, 0, tmp);
575 buffer += config->bLength;
576 size -= config->bLength;
578 config->extra = NULL;
579 config->extra_length = 0;
580 MARK("bNumInterfaces=%d", config->bNumInterfaces);
581 for (parsed_if = 0; (parsed_if < config->bNumInterfaces) && (size > 0); /*parsed_if++*/) {
583 unsigned char *begin;
585 /* Skip over the rest of the Class Specific or Vendor Specific descriptors */
587 while (size >= LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/) {
588 usbi_parse_descriptor(buffer, "bb", &header, 0);
590 if UNLIKELY(header.bLength < LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/) {
592 "invalid extra config desc len (%d)",
596 } else if UNLIKELY(header.bLength > size) {
598 "short extra config desc read %d/%d",
599 size, header.bLength);
600 config->bNumInterfaces = (uint8_t)parsed_if;
604 MARK("bDescriptorType=0x%02x", header.bDescriptorType);
605 /* If we find another "proper" descriptor then we're done */
606 if (is_known_descriptor_type(header.bDescriptorType))
609 usbi_dbg("skipping descriptor 0x%02x\n", header.bDescriptorType);
610 buffer += header.bLength;
611 size -= header.bLength;
614 /* Copy any unknown descriptors into a storage area for */
615 /* drivers to later parse */
616 len = (int)(buffer - begin);
618 MARK("save skipped unknown descriptors into config->extra:len=%d", len);
619 config->extra = usbi_reallocf((void *) config->extra, config->extra_length + len);
620 if UNLIKELY(!config->extra) {
621 r = LIBUSB_ERROR_NO_MEM;
624 memcpy((unsigned char *)(config->extra + config->extra_length), begin, len);
625 config->extra_length += len;
627 switch (header.bDescriptorType) {
628 case LIBUSB_DT_ASSOCIATION:
629 r = parse_association(ctx, config, buffer, size, host_endian);
634 case LIBUSB_DT_INTERFACE:
635 r = parse_interface(ctx, usb_interface + parsed_if, buffer, size, host_endian);
642 config->bNumInterfaces = (uint8_t)parsed_if;
652 clear_configuration(config);
657 static void dump_descriptors(unsigned char *buffer, int size) {
658 struct usb_descriptor_header header;
659 struct libusb_config_descriptor config;
660 struct libusb_interface_descriptor interface;
661 struct libusb_endpoint_descriptor endpoint;
664 LOGI("DUMP DESCRIPTIONS");
665 for (i = 0; size >= 0; i += header.bLength, size -= header.bLength) {
671 if (size < LIBUSB_DT_HEADER_SIZE) {
672 LOGE("short descriptor read %d/2", size);
675 usbi_parse_descriptor(buffer + i, "bb", &header, 0);
676 switch (header.bDescriptorType) {
677 case LIBUSB_DT_DEVICE:
678 LOGI("LIBUSB_DT_DEVICE(0x%02x),length=%d", header.bDescriptorType, header.bLength);
680 case LIBUSB_DT_CONFIG:
681 usbi_parse_descriptor(buffer, "bbwbbbbb", &config, 0);
682 LOGI("LIBUSB_DT_CONFIG(0x%02x)", config.bDescriptorType);
683 LOGI("\tbLength=%d", config.bLength);
684 LOGI("\tbDescriptorType=0x%02x", config.bDescriptorType);
685 LOGI("\twTotalLength=%d", config.wTotalLength);
686 LOGI("\tbNumInterfaces=%d", config.bNumInterfaces);
687 LOGI("\tbConfigurationValue=%d", config.bConfigurationValue);
688 LOGI("\tiConfiguration=%d", config.iConfiguration);
689 LOGI("\tbmAttributes=%d", config.bmAttributes);
690 LOGI("\tMaxPower=%d", config.MaxPower);
691 LOGI("\textra_length=%d", config.bLength - LIBUSB_DT_CONFIG_SIZE);
693 case LIBUSB_DT_STRING:
694 LOGI("LIBUSB_DT_STRING(0x%02x),length=%d", header.bDescriptorType, header.bLength);
696 case LIBUSB_DT_INTERFACE:
697 usbi_parse_descriptor(buffer + i, "bbbbbbbbb", &interface, 0);
698 LOGI("LIBUSB_DT_INTERFACE(0x%02x):", header.bDescriptorType);
699 LOGI("\tbLength=%d", interface.bLength);
700 LOGI("\tbDescriptorType=0x%02x", interface.bDescriptorType);
701 LOGI("\tbInterfaceNumber=%d", interface.bInterfaceNumber);
702 LOGI("\tbAlternateSetting=%d", interface.bAlternateSetting);
703 LOGI("\tbNumEndpoints=%d", interface.bNumEndpoints);
704 LOGI("\tbInterfaceClass=0x%02x", interface.bInterfaceClass);
705 LOGI("\tbInterfaceSubClass=0x%02x", interface.bInterfaceSubClass);
706 LOGI("\tbInterfaceProtocol=0x%02x", interface.bInterfaceProtocol);
707 LOGI("\tiInterface=%d", interface.iInterface);
708 LOGI("\textra_length=%d", interface.bLength - LIBUSB_DT_INTERFACE_SIZE);
710 case LIBUSB_DT_ENDPOINT:
711 usbi_parse_descriptor(buffer + i, "bbbbwbbb", &endpoint, 0);
712 LOGI("LIBUSB_DT_ENDPOINT(0x%02x):", header.bDescriptorType);
713 LOGI("\tbLength=%d", endpoint.bLength);
714 LOGI("\tbDescriptorType=0x%02x", endpoint.bDescriptorType);
715 LOGI("\tbEndpointAddress=%d", endpoint.bEndpointAddress);
716 LOGI("\tbmAttributes=%d", endpoint.bmAttributes);
717 LOGI("\twMaxPacketSize=%d", endpoint.wMaxPacketSize);
718 LOGI("\tbInterval=%d", endpoint.bInterval);
719 LOGI("\tbRefresh=%d", endpoint.bRefresh);
720 LOGI("\tbSynchAddress=%d", endpoint.bSynchAddress);
721 LOGI("\textra_length=%d", endpoint.bLength - LIBUSB_DT_ENDPOINT_SIZE);
723 case LIBUSB_DT_DEVICE_QUALIFIER:
724 LOGI("LIBUSB_DT_DEVICE_QUALIFIER(0x%02x),length=%d", header.bDescriptorType, header.bLength);
725 LOGI("\textra_length=%d", header.bLength - LIBUSB_DT_QUALIFER_SIZE);
727 case LIBUSB_DT_OTHER_SPEED_CONFIGURATION:
728 LOGI("LIBUSB_DT_OTHER_SPEED_CONFIGURATION(0x%02x),length=%d", header.bDescriptorType, header.bLength);
729 LOGI("\textra_length=%d", header.bLength - LIBUSB_DT_OTHER_SPEED_SIZE);
731 case LIBUSB_DT_INTERFACE_POWER:
732 LOGI("LIBUSB_DT_INTERFACE_POWER(0x%02x),length=%d", header.bDescriptorType, header.bLength);
735 LOGI("LIBUSB_DT_OTG(0x%02x),length=%d", header.bDescriptorType, header.bLength);
737 case LIBUSB_DT_DEBUG:
738 LOGI("LIBUSB_DT_DEBUG(0x%02x),length=%d", header.bDescriptorType, header.bLength);
740 case LIBUSB_DT_ASSOCIATION:
741 LOGI("LIBUSB_DT_ASSOCIATION(0x%02x),length=%d", header.bDescriptorType, header.bLength);
742 LOGI("\textra_length=%d", header.bLength - LIBUSB_DT_ASSOCIATION_SIZE);
745 LOGI("LIBUSB_DT_BOS(0x%02x),length=%d", header.bDescriptorType, header.bLength);
746 LOGI("\textra_length=%d", header.bLength - LIBUSB_DT_BOS_SIZE);
748 case LIBUSB_DT_DEVICE_CAPABILITY:
749 LOGI("LIBUSB_DT_DEVICE_CAPABILITY(0x%02x),length=%d", header.bDescriptorType, header.bLength);
750 LOGI("\textra_length=%d", header.bLength - LIBUSB_DT_DEVICE_CAPABILITY_SIZE);
753 LOGI("LIBUSB_DT_HID(0x%02x),length=%d", header.bDescriptorType, header.bLength);
755 case LIBUSB_DT_HID_REPORT:
756 LOGI("LIBUSB_DT_REPORT(0x%02x),length=%d", header.bDescriptorType, header.bLength);
758 case LIBUSB_DT_HID_PHYSICAL:
759 LOGI("LIBUSB_DT_PHYSICAL(0x%02x),length=%d", header.bDescriptorType, header.bLength);
761 case LIBUSB_DT_CS_INTERFACE:
762 LOGI("LIBUSB_DT_CS_INTERFACE(0x%02x),length=%d", header.bDescriptorType, header.bLength);
764 case LIBUSB_DT_CS_ENDPOINT:
765 LOGI("LIBUSB_DT_CS_ENDPOINT(0x%02x),length=%d", header.bDescriptorType, header.bLength);
768 LOGI("LIBUSB_DT_HUB(0x%02x),length=%d", header.bDescriptorType, header.bLength);
770 case LIBUSB_DT_SUPERSPEED_HUB:
771 LOGI("LIBUSB_DT_SUPERSPEED_HUB(0x%02x),length=%d", header.bDescriptorType, header.bLength);
773 case LIBUSB_DT_SS_ENDPOINT_COMPANION:
774 LOGI("LIBUSB_DT_SS_ENDPOINT_COMPANION(0x%02x),length=%d", header.bDescriptorType, header.bLength);
777 LOGI("unknown Descriptor(0x%02x),length=0x%02x", header.bDescriptorType, header.bLength);
785 static int raw_desc_to_config(struct libusb_context *ctx,
786 unsigned char *buf, int size, int host_endian,
787 struct libusb_config_descriptor **config)
791 struct libusb_config_descriptor *_config = malloc(sizeof(*_config));
794 if UNLIKELY(!_config)
795 RETURN(LIBUSB_ERROR_NO_MEM, int);
798 dump_descriptors(buf, size);
800 r = parse_configuration(ctx, _config, buf, size, host_endian);
802 usbi_err(ctx, "parse_configuration failed with error %d", r);
806 usbi_warn(ctx, "still %d bytes of descriptor data left", r);
810 RETURN(LIBUSB_SUCCESS, int);
813 int usbi_device_cache_descriptor(libusb_device *dev)
815 int r, host_endian = 0;
817 r = usbi_backend->get_device_descriptor(dev, (unsigned char *) &dev->device_descriptor,
823 dev->device_descriptor.bcdUSB = libusb_le16_to_cpu(dev->device_descriptor.bcdUSB);
824 dev->device_descriptor.idVendor = libusb_le16_to_cpu(dev->device_descriptor.idVendor);
825 dev->device_descriptor.idProduct = libusb_le16_to_cpu(dev->device_descriptor.idProduct);
826 dev->device_descriptor.bcdDevice = libusb_le16_to_cpu(dev->device_descriptor.bcdDevice);
829 return LIBUSB_SUCCESS;
832 int API_EXPORTED libusb_get_raw_descriptor(libusb_device *dev,
833 unsigned char **buffer, int *descriptors_len, int *host_endian)
835 if UNLIKELY(!buffer || !descriptors_len || !host_endian)
836 return LIBUSB_ERROR_INVALID_PARAM;
839 r = usbi_backend->get_raw_descriptor(dev, NULL, &len, host_endian);
841 unsigned char *temp = realloc(*buffer, len);
843 return LIBUSB_ERROR_NO_MEM;
845 *descriptors_len = len;
846 r = usbi_backend->get_raw_descriptor(dev, temp, &len, host_endian);
852 * Get the USB device descriptor for a given device.
854 * This is a non-blocking function; the device descriptor is cached in memory.
856 * Note since libusb-1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, this
857 * function always succeeds.
859 * \param dev the device
860 * \param desc output location for the descriptor data
861 * \returns 0 on success or a LIBUSB_ERROR code on failure
863 int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
864 struct libusb_device_descriptor *desc)
867 // FIXME add IAD support
868 LOGD("desc=%p,dev=%p,device_descriptor=%p", desc, dev, &dev->device_descriptor);
869 memcpy((unsigned char *) desc, (unsigned char *) &dev->device_descriptor,
870 sizeof (dev->device_descriptor));
875 * Get the USB configuration descriptor for the currently active configuration.
876 * This is a non-blocking function which does not involve any requests being
877 * sent to the device.
879 * \param dev a device
880 * \param config output location for the USB configuration descriptor. Only
881 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
883 * \returns 0 on success
884 * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
885 * \returns another LIBUSB_ERROR code on error
886 * \see libusb_get_config_descriptor
888 int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
889 struct libusb_config_descriptor **config)
891 struct libusb_config_descriptor _config;
892 unsigned char tmp[LIBUSB_DT_CONFIG_SIZE];
893 unsigned char *buf = NULL;
897 r = usbi_backend->get_active_config_descriptor(dev, tmp, // XXX this function will return error on some buggy device
898 LIBUSB_DT_CONFIG_SIZE, &host_endian);
901 if UNLIKELY(r < LIBUSB_DT_CONFIG_SIZE) {
902 usbi_err(dev->ctx, "short config descriptor read %d/%d",
903 r, LIBUSB_DT_CONFIG_SIZE);
904 return LIBUSB_ERROR_IO;
907 usbi_parse_descriptor(tmp, "bbw", &_config, host_endian);
908 buf = malloc(_config.wTotalLength);
910 return LIBUSB_ERROR_NO_MEM;
912 r = usbi_backend->get_active_config_descriptor(dev, buf, // XXX this function will return error on some buggy device
913 _config.wTotalLength, &host_endian);
915 r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
922 * Get a USB configuration descriptor based on its index.
923 * This is a non-blocking function which does not involve any requests being
924 * sent to the device.
926 * \param dev a device
927 * \param config_index the index of the configuration you wish to retrieve
928 * \param config output location for the USB configuration descriptor. Only
929 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
931 * \returns 0 on success
932 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
933 * \returns another LIBUSB_ERROR code on error
934 * \see libusb_get_active_config_descriptor()
935 * \see libusb_get_config_descriptor_by_value()
937 int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
938 uint8_t config_index, struct libusb_config_descriptor **config)
940 struct libusb_config_descriptor _config;
941 unsigned char tmp[LIBUSB_DT_CONFIG_SIZE];
942 unsigned char *buf = NULL;
946 usbi_dbg("index %d", config_index);
947 if UNLIKELY(config_index >= dev->num_configurations)
948 return LIBUSB_ERROR_NOT_FOUND;
950 r = usbi_backend->get_config_descriptor(dev, config_index, tmp,
951 LIBUSB_DT_CONFIG_SIZE, &host_endian);
954 if UNLIKELY(r < LIBUSB_DT_CONFIG_SIZE) {
955 usbi_err(dev->ctx, "short config descriptor read %d/%d",
956 r, LIBUSB_DT_CONFIG_SIZE);
957 return LIBUSB_ERROR_IO;
960 usbi_parse_descriptor(tmp, "bbw", &_config, host_endian);
961 buf = malloc(_config.wTotalLength);
963 return LIBUSB_ERROR_NO_MEM;
965 r = usbi_backend->get_config_descriptor(dev, config_index, buf,
966 _config.wTotalLength, &host_endian);
968 r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
974 /* iterate through all configurations, returning the index of the configuration
975 * matching a specific bConfigurationValue in the idx output parameter, or -1
976 * if the config was not found.
977 * returns 0 on success or a LIBUSB_ERROR code
979 int usbi_get_config_index_by_value(struct libusb_device *dev,
980 uint8_t bConfigurationValue, int *idx)
984 usbi_dbg("value %d", bConfigurationValue);
985 for (i = 0; i < dev->num_configurations; i++) {
986 unsigned char tmp[6];
988 int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp),
994 if (tmp[5] == bConfigurationValue) {
1005 * Get a USB configuration descriptor with a specific bConfigurationValue.
1006 * This is a non-blocking function which does not involve any requests being
1007 * sent to the device.
1009 * \param dev a device
1010 * \param bConfigurationValue the bConfigurationValue of the configuration you
1012 * \param config output location for the USB configuration descriptor. Only
1013 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor()
1015 * \returns 0 on success
1016 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
1017 * \returns another LIBUSB_ERROR code on error
1018 * \see libusb_get_active_config_descriptor()
1019 * \see libusb_get_config_descriptor()
1021 int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
1022 uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
1024 int r, idx, host_endian;
1025 unsigned char *buf = NULL;
1027 if (usbi_backend->get_config_descriptor_by_value) {
1028 r = usbi_backend->get_config_descriptor_by_value(dev,
1029 bConfigurationValue, &buf, &host_endian);
1032 return raw_desc_to_config(dev->ctx, buf, r, host_endian, config);
1035 r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx);
1038 else if UNLIKELY(idx == -1)
1039 return LIBUSB_ERROR_NOT_FOUND;
1041 return libusb_get_config_descriptor(dev, (uint8_t) idx, config);
1045 * Free a configuration descriptor obtained from
1046 * libusb_get_active_config_descriptor() or libusb_get_config_descriptor().
1047 * It is safe to call this function with a NULL config parameter, in which
1048 * case the function simply returns.
1050 * \param config the configuration descriptor to free
1052 void API_EXPORTED libusb_free_config_descriptor(
1053 struct libusb_config_descriptor *config)
1055 if UNLIKELY(!config)
1058 clear_configuration(config);
1063 * Get an endpoints superspeed endpoint companion descriptor (if any)
1065 * \param ctx the context to operate on, or NULL for the default context
1066 * \param endpoint endpoint descriptor from which to get the superspeed
1067 * endpoint companion descriptor
1068 * \param ep_comp output location for the superspeed endpoint companion
1069 * descriptor. Only valid if 0 was returned. Must be freed with
1070 * libusb_free_ss_endpoint_companion_descriptor() after use.
1071 * \returns 0 on success
1072 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
1073 * \returns another LIBUSB_ERROR code on error
1075 int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor(
1076 struct libusb_context *ctx,
1077 const struct libusb_endpoint_descriptor *endpoint,
1078 struct libusb_ss_endpoint_companion_descriptor **ep_comp)
1080 struct usb_descriptor_header header;
1081 int size = endpoint->extra_length;
1082 const unsigned char *buffer = endpoint->extra;
1086 while (size >= LIBUSB_DT_HEADER_SIZE/*DESC_HEADER_LENGTH*/) {
1087 usbi_parse_descriptor(buffer, "bb", &header, 0);
1088 if UNLIKELY(header.bLength < 2 || header.bLength > size) {
1089 usbi_err(ctx, "invalid descriptor length %d",
1091 return LIBUSB_ERROR_IO;
1093 if (header.bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) {
1094 buffer += header.bLength;
1095 size -= header.bLength;
1098 if UNLIKELY(header.bLength < LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE) {
1099 usbi_err(ctx, "invalid ss-ep-comp-desc length %d",
1101 return LIBUSB_ERROR_IO;
1103 *ep_comp = malloc(sizeof(**ep_comp));
1104 if UNLIKELY(!*ep_comp)
1105 return LIBUSB_ERROR_NO_MEM;
1106 usbi_parse_descriptor(buffer, "bbbbw", *ep_comp, 0);
1107 return LIBUSB_SUCCESS;
1109 return LIBUSB_ERROR_NOT_FOUND;
1113 * Free a superspeed endpoint companion descriptor obtained from
1114 * libusb_get_ss_endpoint_companion_descriptor().
1115 * It is safe to call this function with a NULL ep_comp parameter, in which
1116 * case the function simply returns.
1118 * \param ep_comp the superspeed endpoint companion descriptor to free
1120 void API_EXPORTED libusb_free_ss_endpoint_companion_descriptor(
1121 struct libusb_ss_endpoint_companion_descriptor *ep_comp)
1126 static int parse_bos(struct libusb_context *ctx,
1127 struct libusb_bos_descriptor **bos,
1128 unsigned char *buffer, int size, int host_endian)
1130 struct libusb_bos_descriptor bos_header, *_bos;
1131 struct libusb_bos_dev_capability_descriptor dev_cap;
1134 if UNLIKELY(size < LIBUSB_DT_BOS_SIZE) {
1135 usbi_err(ctx, "short bos descriptor read %d/%d",
1136 size, LIBUSB_DT_BOS_SIZE);
1137 return LIBUSB_ERROR_IO;
1140 usbi_parse_descriptor(buffer, "bbwb", &bos_header, host_endian);
1141 if UNLIKELY(bos_header.bDescriptorType != LIBUSB_DT_BOS) {
1142 usbi_err(ctx, "unexpected descriptor %x (expected %x)",
1143 bos_header.bDescriptorType, LIBUSB_DT_BOS);
1144 return LIBUSB_ERROR_IO;
1146 if UNLIKELY(bos_header.bLength < LIBUSB_DT_BOS_SIZE) {
1147 usbi_err(ctx, "invalid bos bLength (%d)", bos_header.bLength);
1148 return LIBUSB_ERROR_IO;
1150 if UNLIKELY(bos_header.bLength > size) {
1151 usbi_err(ctx, "short bos descriptor read %d/%d",
1152 size, bos_header.bLength);
1153 return LIBUSB_ERROR_IO;
1157 sizeof(*_bos) + bos_header.bNumDeviceCaps * sizeof(void *));
1159 return LIBUSB_ERROR_NO_MEM;
1161 usbi_parse_descriptor(buffer, "bbwb", _bos, host_endian);
1162 buffer += bos_header.bLength;
1163 size -= bos_header.bLength;
1165 /* Get the device capability descriptors */
1166 for (i = 0; i < bos_header.bNumDeviceCaps; i++) {
1167 if (size < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
1168 usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
1169 size, LIBUSB_DT_DEVICE_CAPABILITY_SIZE);
1172 usbi_parse_descriptor(buffer, "bbb", &dev_cap, host_endian);
1173 if (dev_cap.bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) {
1174 usbi_warn(ctx, "unexpected descriptor %x (expected %x)",
1175 dev_cap.bDescriptorType, LIBUSB_DT_DEVICE_CAPABILITY);
1178 if UNLIKELY(dev_cap.bLength < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) {
1179 usbi_err(ctx, "invalid dev-cap bLength (%d)",
1181 libusb_free_bos_descriptor(_bos);
1182 return LIBUSB_ERROR_IO;
1184 if (dev_cap.bLength > size) {
1185 usbi_warn(ctx, "short dev-cap descriptor read %d/%d",
1186 size, dev_cap.bLength);
1190 _bos->dev_capability[i] = malloc(dev_cap.bLength);
1191 if UNLIKELY(!_bos->dev_capability[i]) {
1192 libusb_free_bos_descriptor(_bos);
1193 return LIBUSB_ERROR_NO_MEM;
1195 memcpy(_bos->dev_capability[i], buffer, dev_cap.bLength);
1196 buffer += dev_cap.bLength;
1197 size -= dev_cap.bLength;
1199 _bos->bNumDeviceCaps = (uint8_t)i;
1202 return LIBUSB_SUCCESS;
1206 * Get a Binary Object Store (BOS) descriptor
1207 * This is a BLOCKING function, which will send requests to the device.
1209 * \param handle the handle of an open libusb device
1210 * \param bos output location for the BOS descriptor. Only valid if 0 was returned.
1211 * Must be freed with \ref libusb_free_bos_descriptor() after use.
1212 * \returns 0 on success
1213 * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor
1214 * \returns another LIBUSB_ERROR code on error
1216 int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *handle,
1217 struct libusb_bos_descriptor **bos)
1219 struct libusb_bos_descriptor _bos;
1220 uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0};
1221 unsigned char *bos_data = NULL;
1222 const int host_endian = 0;
1225 /* Read the BOS. This generates 2 requests on the bus,
1226 * one for the header, and one for the full BOS */
1227 r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_header,
1228 LIBUSB_DT_BOS_SIZE);
1229 if UNLIKELY(r < 0) {
1230 if (r != LIBUSB_ERROR_PIPE)
1231 usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r);
1234 if UNLIKELY(r < LIBUSB_DT_BOS_SIZE) {
1235 usbi_err(handle->dev->ctx, "short BOS read %d/%d",
1236 r, LIBUSB_DT_BOS_SIZE);
1237 return LIBUSB_ERROR_IO;
1240 usbi_parse_descriptor(bos_header, "bbwb", &_bos, host_endian);
1241 usbi_dbg("found BOS descriptor: size %d bytes, %d capabilities",
1242 _bos.wTotalLength, _bos.bNumDeviceCaps);
1243 bos_data = calloc(_bos.wTotalLength, 1);
1244 if UNLIKELY(!bos_data)
1245 return LIBUSB_ERROR_NO_MEM;
1247 r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_data,
1250 r = parse_bos(handle->dev->ctx, bos, bos_data, r, host_endian);
1252 usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r);
1259 * Free a BOS descriptor obtained from libusb_get_bos_descriptor().
1260 * It is safe to call this function with a NULL bos parameter, in which
1261 * case the function simply returns.
1263 * \param bos the BOS descriptor to free
1265 void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
1272 for (i = 0; i < bos->bNumDeviceCaps; i++)
1273 free(bos->dev_capability[i]);
1278 * Get an USB 2.0 Extension descriptor
1280 * \param ctx the context to operate on, or NULL for the default context
1281 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1282 * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION
1283 * LIBUSB_BT_USB_2_0_EXTENSION
1284 * \param usb_2_0_extension output location for the USB 2.0 Extension
1285 * descriptor. Only valid if 0 was returned. Must be freed with
1286 * libusb_free_usb_2_0_extension_descriptor() after use.
1287 * \returns 0 on success
1288 * \returns a LIBUSB_ERROR code on error
1290 int API_EXPORTED libusb_get_usb_2_0_extension_descriptor(
1291 struct libusb_context *ctx,
1292 struct libusb_bos_dev_capability_descriptor *dev_cap,
1293 struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)
1295 struct libusb_usb_2_0_extension_descriptor *_usb_2_0_extension;
1296 const int host_endian = 0;
1298 if UNLIKELY(dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) {
1299 usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
1300 dev_cap->bDevCapabilityType,
1301 LIBUSB_BT_USB_2_0_EXTENSION);
1302 return LIBUSB_ERROR_INVALID_PARAM;
1304 if UNLIKELY(dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) {
1305 usbi_err(ctx, "short dev-cap descriptor read %d/%d",
1306 dev_cap->bLength, LIBUSB_BT_USB_2_0_EXTENSION_SIZE);
1307 return LIBUSB_ERROR_IO;
1310 _usb_2_0_extension = malloc(sizeof(*_usb_2_0_extension));
1311 if UNLIKELY(!_usb_2_0_extension)
1312 return LIBUSB_ERROR_NO_MEM;
1314 usbi_parse_descriptor((unsigned char *)dev_cap, "bbbd",
1315 _usb_2_0_extension, host_endian);
1317 *usb_2_0_extension = _usb_2_0_extension;
1318 return LIBUSB_SUCCESS;
1322 * Free a USB 2.0 Extension descriptor obtained from
1323 * libusb_get_usb_2_0_extension_descriptor().
1324 * It is safe to call this function with a NULL usb_2_0_extension parameter,
1325 * in which case the function simply returns.
1327 * \param usb_2_0_extension the USB 2.0 Extension descriptor to free
1329 void API_EXPORTED libusb_free_usb_2_0_extension_descriptor(
1330 struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
1332 free(usb_2_0_extension);
1336 * Get a SuperSpeed USB Device Capability descriptor
1338 * \param ctx the context to operate on, or NULL for the default context
1339 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1340 * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
1341 * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
1342 * \param ss_usb_device_cap output location for the SuperSpeed USB Device
1343 * Capability descriptor. Only valid if 0 was returned. Must be freed with
1344 * libusb_free_ss_usb_device_capability_descriptor() after use.
1345 * \returns 0 on success
1346 * \returns a LIBUSB_ERROR code on error
1348 int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor(
1349 struct libusb_context *ctx,
1350 struct libusb_bos_dev_capability_descriptor *dev_cap,
1351 struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap)
1353 struct libusb_ss_usb_device_capability_descriptor *_ss_usb_device_cap;
1354 const int host_endian = 0;
1356 if UNLIKELY(dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {
1357 usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
1358 dev_cap->bDevCapabilityType,
1359 LIBUSB_BT_SS_USB_DEVICE_CAPABILITY);
1360 return LIBUSB_ERROR_INVALID_PARAM;
1362 if UNLIKELY(dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) {
1363 usbi_err(ctx, "short dev-cap descriptor read %d/%d",
1364 dev_cap->bLength, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE);
1365 return LIBUSB_ERROR_IO;
1368 _ss_usb_device_cap = malloc(sizeof(*_ss_usb_device_cap));
1369 if UNLIKELY(!_ss_usb_device_cap)
1370 return LIBUSB_ERROR_NO_MEM;
1372 usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbwbbw",
1373 _ss_usb_device_cap, host_endian);
1375 *ss_usb_device_cap = _ss_usb_device_cap;
1376 return LIBUSB_SUCCESS;
1380 * Free a SuperSpeed USB Device Capability descriptor obtained from
1381 * libusb_get_ss_usb_device_capability_descriptor().
1382 * It is safe to call this function with a NULL ss_usb_device_cap
1383 * parameter, in which case the function simply returns.
1385 * \param ss_usb_device_cap the USB 2.0 Extension descriptor to free
1387 void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor(
1388 struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap)
1390 free(ss_usb_device_cap);
1394 * Get a Container ID descriptor
1396 * \param ctx the context to operate on, or NULL for the default context
1397 * \param dev_cap Device Capability descriptor with a bDevCapabilityType of
1398 * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID
1399 * LIBUSB_BT_CONTAINER_ID
1400 * \param container_id output location for the Container ID descriptor.
1401 * Only valid if 0 was returned. Must be freed with
1402 * libusb_free_container_id_descriptor() after use.
1403 * \returns 0 on success
1404 * \returns a LIBUSB_ERROR code on error
1406 int API_EXPORTED libusb_get_container_id_descriptor(struct libusb_context *ctx,
1407 struct libusb_bos_dev_capability_descriptor *dev_cap,
1408 struct libusb_container_id_descriptor **container_id)
1410 struct libusb_container_id_descriptor *_container_id;
1411 const int host_endian = 0;
1413 if UNLIKELY(dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) {
1414 usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)",
1415 dev_cap->bDevCapabilityType,
1416 LIBUSB_BT_CONTAINER_ID);
1417 return LIBUSB_ERROR_INVALID_PARAM;
1419 if UNLIKELY(dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) {
1420 usbi_err(ctx, "short dev-cap descriptor read %d/%d",
1421 dev_cap->bLength, LIBUSB_BT_CONTAINER_ID_SIZE);
1422 return LIBUSB_ERROR_IO;
1425 _container_id = malloc(sizeof(*_container_id));
1426 if UNLIKELY(!_container_id)
1427 return LIBUSB_ERROR_NO_MEM;
1429 usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbu",
1430 _container_id, host_endian);
1432 *container_id = _container_id;
1433 return LIBUSB_SUCCESS;
1437 * Free a Container ID descriptor obtained from
1438 * libusb_get_container_id_descriptor().
1439 * It is safe to call this function with a NULL container_id parameter,
1440 * in which case the function simply returns.
1442 * \param container_id the USB 2.0 Extension descriptor to free
1444 void API_EXPORTED libusb_free_container_id_descriptor(
1445 struct libusb_container_id_descriptor *container_id)
1451 * Retrieve a string descriptor in C style ASCII.
1453 * Wrapper around libusb_get_string_descriptor(). Uses the first language
1454 * supported by the device.
1456 * \param dev a device handle
1457 * \param desc_index the index of the descriptor to retrieve
1458 * \param data output buffer for ASCII string descriptor
1459 * \param length size of data buffer
1460 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
1462 int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
1463 uint8_t desc_index, unsigned char *data, int length)
1465 unsigned char tbuf[255]; /* Some devices choke on size > 255 */
1469 /* Asking for the zero'th index is special - it returns a string
1470 * descriptor that contains all the language IDs supported by the
1471 * device. Typically there aren't many - often only one. Language
1472 * IDs are 16 bit numbers, and they start at the third byte in the
1473 * descriptor. There's also no point in trying to read descriptor 0
1474 * with this function. See USB 2.0 specification section 9.6.7 for
1478 if UNLIKELY(!desc_index)
1479 return LIBUSB_ERROR_INVALID_PARAM;
1481 r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf));
1486 return LIBUSB_ERROR_IO;
1488 langid = tbuf[2] | (tbuf[3] << 8);
1490 r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf, sizeof(tbuf));
1494 if UNLIKELY(tbuf[1] != LIBUSB_DT_STRING)
1495 return LIBUSB_ERROR_IO;
1497 if UNLIKELY(tbuf[0] > r)
1498 return LIBUSB_ERROR_IO;
1500 for (di = 0, si = 2; si < tbuf[0]; si += 2) {
1501 if (di >= (length - 1))
1504 if ((tbuf[si] & 0x80) || (tbuf[si + 1])) /* non-ASCII */
1507 data[di++] = tbuf[si];