1 /*********************************************************************
2 *********************************************************************/
3 /*********************************************************************
4 * changed to using LogCat than stderr when compiling for Android
5 * Copyright (C) 2014 saki@serenegiant All rights reserved.
6 *********************************************************************/
7 /*********************************************************************
8 * Software License Agreement (BSD License)
10 * Copyright (C) 2010-2012 Ken Tossell
11 * All rights reserved.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
17 * * Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * * Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials provided
22 * with the distribution.
23 * * Neither the name of the author nor other contributors may be
24 * used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 *********************************************************************/
41 * @defgroup diag Diagnostics
42 * @brief Interpretation of devices, error codes and negotiated stream parameters
45 #include "libuvc/libuvc.h"
46 #include "libuvc/libuvc_internal.h"
49 typedef struct _uvc_error_msg {
54 static const _uvc_error_msg_t uvc_error_msgs[] = {
55 { UVC_SUCCESS, "Success" },
56 { UVC_ERROR_IO, "I/O error" },
57 { UVC_ERROR_INVALID_PARAM, "Invalid parameter" },
58 { UVC_ERROR_ACCESS, "Access denied" },
59 { UVC_ERROR_NO_DEVICE, "No such device" },
60 { UVC_ERROR_NOT_FOUND, "Not found" },
61 { UVC_ERROR_BUSY, "Busy" },
62 { UVC_ERROR_TIMEOUT, "Timeout" },
63 { UVC_ERROR_OVERFLOW, "Overflow" },
64 { UVC_ERROR_PIPE, "Pipe" },
65 { UVC_ERROR_INTERRUPTED, "Interrupted" },
66 { UVC_ERROR_NO_MEM, "Out of memory" },
67 { UVC_ERROR_NOT_SUPPORTED, "Not supported" },
68 { UVC_ERROR_INVALID_DEVICE, "Invalid device" },
69 { UVC_ERROR_INVALID_MODE, "Invalid mode" },
70 { UVC_ERROR_CALLBACK_EXISTS, "Callback exists" }
74 #define FPRINTF(stream, ...) MARK(__VA_ARGS__); usleep(1000);
75 #define FPRINTF_ERR(stream, ...) LOGW(__VA_ARGS__)
77 #define FPRINTF(stream, ...) fprintf(stream, __VA_ARGS__)
78 #define FPRINTF_ERR(stream, ...) fprintf(stream, __VA_ARGS__)
80 /** @brief Print a message explaining an error in the UVC driver
83 * @param err UVC error code
84 * @param msg Optional custom message, prepended to output
86 void uvc_perror(uvc_error_t err, const char *msg) {
88 FPRINTF_ERR(stderr, "%s:%s (%d)\n", msg, uvc_strerror(err), err);
90 FPRINTF_ERR(stderr, "%s (%d)\n", uvc_strerror(err), err);
98 FPRINTF(stderr, "%s (%d)\n", uvc_strerror(err), err);
102 /** @brief Return a string explaining an error in the UVC driver
105 * @param err UVC error code
106 * @return error message
108 const char* uvc_strerror(uvc_error_t err) {
111 for (idx = 0; idx < sizeof(uvc_error_msgs) / sizeof(*uvc_error_msgs);
113 if (uvc_error_msgs[idx].err == err) {
114 return uvc_error_msgs[idx].msg;
118 return "Unknown error";
121 /** @brief Print the values in a stream control block
124 * @param devh UVC device
125 * @param stream Output stream (stderr if NULL)
127 void uvc_print_stream_ctrl(uvc_stream_ctrl_t *ctrl, FILE *stream) {
131 FPRINTF(stream, "bmHint: %04x\n", ctrl->bmHint);
132 FPRINTF(stream, "bFormatIndex: %d\n", ctrl->bFormatIndex);
133 FPRINTF(stream, "bFrameIndex: %d\n", ctrl->bFrameIndex);
134 FPRINTF(stream, "dwFrameInterval: %u\n", ctrl->dwFrameInterval);
135 FPRINTF(stream, "wKeyFrameRate: %d\n", ctrl->wKeyFrameRate);
136 FPRINTF(stream, "wPFrameRate: %d\n", ctrl->wPFrameRate);
137 FPRINTF(stream, "wCompQuality: %d\n", ctrl->wCompQuality);
138 FPRINTF(stream, "wCompWindowSize: %d\n", ctrl->wCompWindowSize);
139 FPRINTF(stream, "wDelay: %d\n", ctrl->wDelay);
140 FPRINTF(stream, "dwMaxVideoFrameSize: %u\n", ctrl->dwMaxVideoFrameSize);
141 FPRINTF(stream, "dwMaxPayloadTransferSize: %u\n", ctrl->dwMaxPayloadTransferSize);
142 FPRINTF(stream, "bInterfaceNumber: %d\n", ctrl->bInterfaceNumber);
144 /** add UVC 1.1 parameters */
145 FPRINTF(stream, "dwClockFrequency: %d\n", ctrl->dwClockFrequency);
146 FPRINTF(stream, "bmFramingInfo: %d\n", ctrl->bmFramingInfo);
147 FPRINTF(stream, "bPreferedVersion: %d\n", ctrl->bPreferedVersion);
148 FPRINTF(stream, "bMinVersion: %d\n", ctrl->bMinVersion);
149 FPRINTF(stream, "bMaxVersion: %d\n", ctrl->bMaxVersion);
150 /** add UVC 1.5 parameters */
151 FPRINTF(stream, "bUsage: %d\n", ctrl->bUsage);
152 FPRINTF(stream, "bBitDepthLuma: %d\n", ctrl->bBitDepthLuma);
153 FPRINTF(stream, "bmSettings: %d\n", ctrl->bmSettings);
154 FPRINTF(stream, "bMaxNumberOfRefFramesPlus1: %d\n", ctrl->bMaxNumberOfRefFramesPlus1);
155 FPRINTF(stream, "bmRateControlModes: %d\n", ctrl->bmRateControlModes);
156 #if !defined(__LP64__)
157 FPRINTF(stream, "bmLayoutPerStream: %llx\n", ctrl->bmLayoutPerStream);
159 FPRINTF(stream, "bmLayoutPerStream: %lx\n", ctrl->bmLayoutPerStream);
163 static const char *_uvc_name_for_desc_type(const uint8_t type) {
165 case LIBUSB_DT_DEVICE: // 0x01,
166 return "Device Descriptor(0x01)";
167 case LIBUSB_DT_CONFIG: // 0x02,
168 return "Config Descriptor(0x02)";
169 case LIBUSB_DT_STRING: // 0x03,
170 return "String Descriptor(0x03)";
171 case LIBUSB_DT_INTERFACE: // 0x04,
172 return "Interface Descriptor(0x04)";
173 case LIBUSB_DT_ENDPOINT: // 0x05,
174 return "Endpoint Descriptor(0x05)";
175 case LIBUSB_DT_DEVICE_QUALIFIER: // 0x06, // deprecated on USB3.0
176 return "Qualifier Descriptor(0x06)";
177 case LIBUSB_DT_OTHER_SPEED_CONFIGURATION: // 0x07, // deprecated on USB3.0
178 return "Other speed Config Descriptor(0x07)";
179 case LIBUSB_DT_INTERFACE_POWER: // 0x08,
180 return "Power interface Descriptor(0x08)";
181 case LIBUSB_DT_OTG: // 0x09,
182 return "OTG Interface Descriptor(0x09)";
183 case LIBUSB_DT_DEBUG: // 0x0a,
184 return "Debug Descriptor(0x0a)";
185 case LIBUSB_DT_ASSOCIATION: // 0x0b,
186 return "Association Descriptor(0x0b)";
187 case LIBUSB_DT_BOS: // 0x0f,
188 return "BOS Descriptor(0x0f)";
189 case LIBUSB_DT_DEVICE_CAPABILITY: // 0x10,
190 return "Device capability Descriptor(0x10)";
191 // Class specified descriptors
192 case LIBUSB_DT_HID: // 0x21,
193 return "CS:HID Descriptor(0x21)";
194 case LIBUSB_DT_HID_REPORT: // 0x22,
195 return "CS:HID Report Descriptor(0x22)";
196 case LIBUSB_DT_HID_PHYSICAL: // 0x23,
197 return "CS:HID Pysical Descriptor(0x23)";
198 case LIBUSB_DT_CS_INTERFACE: // 0x24,
199 return "CS:Interface Descriptor(0x24)";
200 case LIBUSB_DT_CS_ENDPOINT: // 0x25,
201 return "CS:Endpoint Descriptor(0x25)";
202 case LIBUSB_DT_HUB: // 0x29,
203 return "CS:Hub Descriptor(0x29)";
204 case LIBUSB_DT_SUPERSPEED_HUB: // 0x2a,
205 return "CS:Superspeed Hub Descriptor(0x2a)";
206 case LIBUSB_DT_SS_ENDPOINT_COMPANION: // 0x30 // defined on USB 3.0
207 return "CS:Superspeed Endpoint Companion Descriptor(0x30)";
209 return "Unknown descriptor";
213 static const char *_uvc_name_for_class(const uint8_t clazz) {
215 case LIBUSB_CLASS_AUDIO: // 1, /** Audio class */
217 case LIBUSB_CLASS_COMM: // 2, /** Communications class */
219 case LIBUSB_CLASS_HID: // 3, /** Human Interface Device class */
221 case LIBUSB_CLASS_PHYSICAL: // 5, /** Physical */
223 case LIBUSB_CLASS_IMAGE: // 6, /** Image class */
225 case LIBUSB_CLASS_PRINTER: // 7, /** Printer class */
227 case LIBUSB_CLASS_MASS_STORAGE: // 8, /** Mass storage class */
228 return "Mass storage";
229 case LIBUSB_CLASS_HUB: // 9, /** Hub class */
231 case LIBUSB_CLASS_DATA: // 0x0a, /** Data class */
233 case LIBUSB_CLASS_SMART_CARD: // 0x0b, /** Smart Card */
235 case LIBUSB_CLASS_CONTENT_SECURITY: // 0x0d, /** Content Security */
237 case LIBUSB_CLASS_VIDEO: // 0x0e, /** Video */
239 case LIBUSB_CLASS_PERSONAL_HEALTHCARE: // 0x0f, /** Personal Healthcare */
241 case LIBUSB_CLASS_DIAGNOSTIC_DEVICE: // 0xdc, /** Diagnostic Device */
243 case LIBUSB_CLASS_WIRELESS: // 0xe0, /** Wireless class */
245 case LIBUSB_CLASS_APPLICATION: // 0xfe, /** Application class */
247 case LIBUSB_CLASS_VENDOR_SPEC: // 0xff /** Class is vendor-specific */
248 return "Vender specific";
254 static const char *_uvc_name_for_subtype(const uint8_t subtype) {
256 case UVC_VS_UNDEFINED: // 0x00,
257 return "Undefined(0x00)";
258 case UVC_VS_INPUT_HEADER: // 0x01,
259 return "Header(Input,0x01)";
260 case UVC_VS_OUTPUT_HEADER: // 0x02,
261 return "Header(Output,0x02)";
262 case UVC_VS_STILL_IMAGE_FRAME: // 0x03,
263 return "Frame(StillImage,0x03)";
264 case UVC_VS_FORMAT_UNCOMPRESSED: // 0x04,
265 return "Format(Uncompressed,0x04)";
266 case UVC_VS_FRAME_UNCOMPRESSED: // 0x05,
267 return "Frame(Uncompressed,0x05)";
268 case UVC_VS_FORMAT_MJPEG: // 0x06,
269 return "Format(MJPEG,0x06)";
270 case UVC_VS_FRAME_MJPEG: // 0x07,
271 return "Frame(MJPEG,0x07)";
272 case UVC_VS_FORMAT_MPEG2TS: // 0x0a,
273 return "Format(MPEG2TS,0x0a)";
274 case UVC_VS_FORMAT_DV: // 0x0c,
275 return "Format(DV,0x0c)";
276 case UVC_VS_COLORFORMAT: // 0x0d,
277 return "ColorFormat(0x0d)";
278 case UVC_VS_FORMAT_FRAME_BASED: // 0x10,
279 return "Format(FRAME_BASED,0x10)";
280 case UVC_VS_FRAME_FRAME_BASED: // 0x11,
281 return "Frame(FRAME_BASED,0x10)";
282 case UVC_VS_FORMAT_STREAM_BASED: // 0x12
283 return "Format(STREAM_BASED,0x10)";
289 /** @brief Print camera capabilities and configuration.
292 * @param devh UVC device
293 * @param stream Output stream (stderr if NULL)
295 void uvc_print_diag(uvc_device_handle_t *devh, FILE *stream) {
301 if (devh->info->ctrl_if.bcdUVC) {
302 uvc_streaming_interface_t *stream_if;
305 uvc_device_descriptor_t *desc;
306 uvc_get_device_descriptor(devh->dev, &desc);
308 FPRINTF(stream, "DEVICE CONFIGURATION (%04x:%04x/%s) ---\n",
309 desc->idVendor, desc->idProduct,
310 desc->serialNumber ? desc->serialNumber : "[none]");
312 uvc_free_device_descriptor(desc);
314 FPRINTF(stream, "Status: %s\n", devh->streams ? "streaming" : "idle");
316 FPRINTF(stream, "VideoControl:\n"
317 "\tbcdUVC: 0x%04x\n", devh->info->ctrl_if.bcdUVC);
319 DL_FOREACH(devh->info->stream_ifs, stream_if)
321 uvc_format_desc_t *fmt_desc;
326 "VideoStreaming(%d):\n"
327 "\tbEndpointAddress: %d\n\tFormats:\n",
328 stream_idx, stream_if->bEndpointAddress);
329 uvc_print_format_desc(stream_if->format_descs, stream);
332 FPRINTF(stream, "END DEVICE CONFIGURATION\n");
334 FPRINTF(stream, "uvc_print_diag: Device not configured!\n");
339 void uvc_print_format_desc_one(uvc_format_desc_t *format_desc, FILE *stream) {
341 uvc_frame_desc_t *frame_desc;
344 switch (format_desc->bDescriptorSubtype) {
345 case UVC_VS_FORMAT_UNCOMPRESSED:
346 case UVC_VS_FORMAT_MJPEG:
347 FPRINTF(stream, "\t\tFormatDescriptor(bFormatIndex=%d)", format_desc->bFormatIndex);
348 FPRINTF(stream, "\t\t bDescriptorSubtype: %s",
349 _uvc_name_for_subtype(format_desc->bDescriptorSubtype));
350 FPRINTF(stream, "\t\t bits per pixel: %d", format_desc->bBitsPerPixel);
352 "\t\t GUID:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
353 format_desc->guidFormat[0], format_desc->guidFormat[1],
354 format_desc->guidFormat[2], format_desc->guidFormat[3],
355 format_desc->guidFormat[4], format_desc->guidFormat[5],
356 format_desc->guidFormat[6], format_desc->guidFormat[7],
357 format_desc->guidFormat[8], format_desc->guidFormat[9],
358 format_desc->guidFormat[10], format_desc->guidFormat[11],
359 format_desc->guidFormat[12], format_desc->guidFormat[13],
360 format_desc->guidFormat[14], format_desc->guidFormat[15]);
362 FPRINTF(stream, "\t\t bDefaultFrameIndex: %d", format_desc->bDefaultFrameIndex);
363 FPRINTF(stream, "\t\t bAspectRatio(x,y): %dx%d", format_desc->bAspectRatioX, format_desc->bAspectRatioY);
364 FPRINTF(stream, "\t\t bmInterlaceFlags: 0x%02x", format_desc->bmInterlaceFlags);
365 FPRINTF(stream, "\t\t bCopyProtect: 0x%02x", format_desc->bCopyProtect);
367 DL_FOREACH(format_desc->frame_descs, frame_desc)
369 uint32_t *interval_ptr;
371 FPRINTF(stream, "\t\t\tFrameDescriptor(bFrameIndex=%d)", frame_desc->bFrameIndex);
372 FPRINTF(stream, "\t\t\t bDescriptorSubtype: %s", _uvc_name_for_subtype(frame_desc->bDescriptorSubtype));
373 FPRINTF(stream, "\t\t\t bmCapabilities: 0x%02x", frame_desc->bmCapabilities);
374 FPRINTF(stream, "\t\t\t size(w,h):(%d,%d)", frame_desc->wWidth, frame_desc->wHeight);
375 FPRINTF(stream, "\t\t\t bit rate(min,max): (%d,%d)", frame_desc->dwMinBitRate, frame_desc->dwMaxBitRate);
376 FPRINTF(stream, "\t\t\t dwMaxVideoFrameBufferSize: %d", frame_desc->dwMaxVideoFrameBufferSize);
377 FPRINTF(stream, "\t\t\t dwDefaultFrameInterval: 1/%d", 10000000 / frame_desc->dwDefaultFrameInterval);
378 if (frame_desc->intervals) {
379 for (interval_ptr = frame_desc->intervals;
380 *interval_ptr; ++interval_ptr) {
381 FPRINTF(stream, "\t\t\t interval[%d]: 1/%d",
382 (int ) (interval_ptr - frame_desc->intervals),
383 10000000 / *interval_ptr);
386 FPRINTF(stream, "\t\t\t min interval[%d] = 1/%d",
387 frame_desc->dwMinFrameInterval,
388 10000000 / frame_desc->dwMinFrameInterval);
389 FPRINTF(stream, "\t\t\t max interval[%d] = 1/%d",
390 frame_desc->dwMaxFrameInterval,
391 10000000 / frame_desc->dwMaxFrameInterval);
392 if (frame_desc->dwFrameIntervalStep)
393 FPRINTF(stream, "\t\t\t interval step[%d] = 1/%d",
394 frame_desc->dwFrameIntervalStep,
395 10000000 / frame_desc->dwFrameIntervalStep);
400 FPRINTF(stream, "\t-UnknownFormat:0x%2d", format_desc->bDescriptorSubtype);
404 void uvc_print_format_desc(uvc_format_desc_t *format_descriptors, FILE *stream) {
410 uvc_format_desc_t *fmt_desc;
411 MARK("FORMAT DESCRIPTOR");
412 DL_FOREACH(format_descriptors, fmt_desc)
414 uvc_print_format_desc_one(fmt_desc, stream);
416 MARK("END FORMAT DESCRIPTOR");
421 void uvc_print_device_desc(uvc_device_handle_t *devh, FILE *stream) {
427 struct libusb_device_descriptor usb_desc;
430 ret = libusb_get_device_descriptor(devh->dev->usb_dev, &usb_desc);
432 if (UNLIKELY(ret != UVC_SUCCESS)) {
433 LOGE("failed libusb_get_device_descriptor");
437 FPRINTF(stream, "DEVICE DESCRIPTOR (%04x:%04x)", usb_desc.idVendor, usb_desc.idProduct);
438 FPRINTF(stream, "\t bLength:%d", usb_desc.bLength);
439 FPRINTF(stream, "\t bDescriptorType: %s", _uvc_name_for_desc_type(usb_desc.bDescriptorType));
440 FPRINTF(stream, "\t bcdUSB:0x%04x", usb_desc.bcdUSB);
441 FPRINTF(stream, "\t bDeviceClass: %s(0x%02x)", _uvc_name_for_class(usb_desc.bDeviceClass), usb_desc.bDeviceClass);
442 FPRINTF(stream, "\t bDeviceSubClass:0x%02x", usb_desc.bDeviceSubClass);
443 FPRINTF(stream, "\t bDeviceProtocol:0x%02x", usb_desc.bDeviceProtocol);
444 FPRINTF(stream, "\t bMaxPacketSize0:%d", usb_desc.bMaxPacketSize0);
445 FPRINTF(stream, "\t idVendor:0x%04x", usb_desc.idVendor);
446 FPRINTF(stream, "\t idProduct:0x%04x", usb_desc.idProduct);
447 FPRINTF(stream, "\t bcdDevice:0x%04x", usb_desc.bcdDevice);
448 FPRINTF(stream, "\t iManufacturer:%d", usb_desc.iManufacturer);
449 FPRINTF(stream, "\t iProduct:%d", usb_desc.iProduct);
450 FPRINTF(stream, "\t iSerialNumber:%d", usb_desc.iSerialNumber);
451 FPRINTF(stream, "\t bNumConfigurations:%d", usb_desc.bNumConfigurations);
456 void uvc_print_endpoint_desc(
457 const struct libusb_endpoint_descriptor *endpoint, const int num_endpoint,
458 const char *prefix, FILE *stream) {
466 const struct libusb_endpoint_descriptor *ep;
468 for (ep_ix = 0; ep_ix < num_endpoint; ep_ix++) {
469 ep = endpoint + ep_ix;
470 FPRINTF(stream, "%s endpoint(%d)", prefix, ep_ix);
472 FPRINTF(stream, "%s\t bLength:%d", prefix, ep->bLength);
473 FPRINTF(stream, "%s\t bDescriptorType: %s", prefix, _uvc_name_for_desc_type(ep->bDescriptorType));
474 FPRINTF(stream, "%s\t bEndpointAddress:0x%02x", prefix, ep->bEndpointAddress);
475 FPRINTF(stream, "%s\t bmAttributes:0x%02x", prefix, ep->bmAttributes);
476 FPRINTF(stream, "%s\t wMaxPacketSize:%d", prefix, ep->wMaxPacketSize);
477 FPRINTF(stream, "%s\t bInterval:%d", prefix, ep->bInterval);
478 FPRINTF(stream, "%s\t bRefresh(audio):%d", prefix, ep->bRefresh);
479 FPRINTF(stream, "%s\t bSynchAddress(audio):%d", prefix, ep->bSynchAddress);
480 FPRINTF(stream, "%s\t extra_length:%d", prefix, ep->extra_length);
486 void uvc_print_interface_desc(
487 const struct libusb_interface *interface, const int num_interface,
488 const char *prefix, FILE *stream) {
495 const struct libusb_interface *usb_if;
496 const struct libusb_interface_descriptor *altsetting;
499 sprintf(pre, "%s\t\t", prefix);
500 for (if_ix = 0; if_ix < num_interface; if_ix++) {
501 usb_if = interface + if_ix;
503 FPRINTF(stream, "%s interface(%d)", prefix, if_ix);
504 for (alt_ix = 0; alt_ix < usb_if->num_altsetting; alt_ix++) {
505 altsetting = usb_if->altsetting + alt_ix;
506 if LIKELY(altsetting) {
507 FPRINTF(stream, "%s\t altsetting:%d", prefix, alt_ix);
508 FPRINTF(stream, "%s\t\t bLength:%d", prefix, altsetting->bLength);
509 FPRINTF(stream, "%s\t\t bDescriptorType: %s", prefix, _uvc_name_for_desc_type(altsetting->bDescriptorType));
510 FPRINTF(stream, "%s\t\t bInterfaceNumber:%d", prefix, altsetting->bInterfaceNumber);
511 FPRINTF(stream, "%s\t\t bAlternateSetting:%d", prefix, altsetting->bAlternateSetting);
512 FPRINTF(stream, "%s\t\t bNumEndpoints:%d", prefix, altsetting->bNumEndpoints);
513 FPRINTF(stream, "%s\t\t bInterfaceClass: %s(0x%02x)", prefix, _uvc_name_for_class(altsetting->bInterfaceClass), altsetting->bInterfaceClass);
514 FPRINTF(stream, "%s\t\t bInterfaceSubClass:0x%02x", prefix, altsetting->bInterfaceSubClass);
515 FPRINTF(stream, "%s\t\t bInterfaceProtocol:0x%02x", prefix, altsetting->bInterfaceProtocol);
516 FPRINTF(stream, "%s\t\t iInterface:%d", prefix, altsetting->iInterface);
517 FPRINTF(stream, "%s\t\t extra_length:%d", prefix, altsetting->extra_length);
518 if (altsetting->bNumEndpoints)
519 uvc_print_endpoint_desc(altsetting->endpoint, altsetting->bNumEndpoints, pre, stream);
528 void uvc_print_configuration_desc(uvc_device_handle_t *devh, FILE *stream) {
535 libusb_device_handle *usb_devh = uvc_get_libusb_handle(devh);
536 libusb_device *usb_dev = devh->dev->usb_dev;
537 struct libusb_config_descriptor *config_desc;
540 FPRINTF(stream, "CONFIGURATION DESCRIPTOR");
541 ret = libusb_get_configuration(usb_devh, &config);
543 FPRINTF(stream, "\t current=%d", config);
544 if LIKELY(config >= 0) {
545 ret = libusb_get_active_config_descriptor(usb_dev, &config_desc);
547 FPRINTF(stream, "\t\t bLength:%d", config_desc->bLength);
548 FPRINTF(stream, "\t\t bDescriptorType: %s", _uvc_name_for_desc_type(config_desc->bDescriptorType));
549 FPRINTF(stream, "\t\t wTotalLength:%d", config_desc->wTotalLength);
550 FPRINTF(stream, "\t\t bNumInterfaces:%d", config_desc->bNumInterfaces);
551 FPRINTF(stream, "\t\t bConfigurationValue:%d", config_desc->bConfigurationValue);
552 FPRINTF(stream, "\t\t iConfiguration:%d", config_desc->iConfiguration);
553 FPRINTF(stream, "\t\t bmAttributes:0x%02x", config_desc->bmAttributes);
554 FPRINTF(stream, "\t\t MaxPower:%d x2[mA]", config_desc->MaxPower);
555 FPRINTF(stream, "\t\t extra_length:%d", config_desc->extra_length);
556 if (config_desc->wTotalLength && config_desc->bNumInterfaces)
557 uvc_print_interface_desc(config_desc->interface, config_desc->bNumInterfaces, "\t\t", stream);
558 libusb_free_config_descriptor(config_desc);