3 * Forked from packet-usb-masstorage.c 35224 2010-12-20 05:35:29Z guy
4 * which was authored by Ronnie Sahlberg (2006)
7 * Steven J. Magnani 2013
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/expert.h>
18 #include <wsutil/array.h>
19 #include "packet-usb.h"
21 void proto_register_usb_vid(void);
22 void proto_reg_handoff_usb_vid(void);
24 /* References are to sections in USB Video Class specifications -
25 * specifically V1.5, but versions have tended to keep
26 * the same numbering (as of this writing).
28 * http://www.usb.org/developers/devclass_docs/USB_Video_Class_1_5.zip
31 /* Table 2-1. Interrupt originators */
32 #define INT_VIDEOCONTROL 1
33 #define INT_VIDEOSTREAMING 2
35 #define INT_ORIGINATOR_MASK 0xF
37 /* Table 2-2. Video Control Status Packet bAttribute */
38 #define CONTROL_CHANGE_VALUE 0x00
39 #define CONTROL_CHANGE_INFO 0x01
40 #define CONTROL_CHANGE_FAILURE 0x02
41 #define CONTROL_CHANGE_MIN 0x03 /* UVC 1.5+ */
42 #define CONTROL_CHANGE_MAX 0x04 /* UVC 1.5+ */
45 /* A.2 Video Interface Subclass Codes */
46 #define SC_UNDEFINED 0
47 #define SC_VIDEOCONTROL 1
48 #define SC_VIDEOSTREAMING 2
49 #define SC_VIDEO_INTERFACE_COLLECTION 3
51 /* A.4. Video Class-Specific Descriptor Types */
52 #define CS_INTERFACE 0x24
53 #define CS_ENDPOINT 0x25
55 /* A.5 Video Class-Specific VC Interface Descriptor Subtypes */
57 #define VC_INPUT_TERMINAL 2
58 #define VC_OUTPUT_TERMINAL 3
59 #define VC_SELECTOR_UNIT 4
60 #define VC_PROCESSING_UNIT 5
61 #define VC_EXTENSION_UNIT 6
62 #define VC_ENCODING_UNIT 7
64 /* A.6 Video Class-Specific VS Interface Descriptor Subtypes */
65 #define VS_UNDEFINED 0x00
66 #define VS_INPUT_HEADER 0x01
67 #define VS_OUTPUT_HEADER 0x02
68 #define VS_STILL_IMAGE_FRAME 0x03
69 #define VS_FORMAT_UNCOMPRESSED 0x04
70 #define VS_FRAME_UNCOMPRESSED 0x05
71 #define VS_FORMAT_MJPEG 0x06
72 #define VS_FRAME_MJPEG 0x07
73 #define VS_FORMAT_MPEG1 0x08 /* Pre-UVC 1.1 */
74 #define VS_FORMAT_MPEG2PS 0x09 /* Pre-UVC 1.1 */
75 #define VS_FORMAT_MPEG2TS 0x0A
76 #define VS_FORMAT_MPEG4SL 0x0B /* Pre-UVC 1.1 */
77 #define VS_FORMAT_DV 0x0C
78 #define VS_COLORFORMAT 0x0D
79 #define VS_FORMAT_VENDOR 0x0E /* Pre-UVC 1.1 */
80 #define VS_FRAME_VENDOR 0x0F /* Pre-UVC 1.1 */
81 #define VS_FORMAT_FRAME_BASED 0x10
82 #define VS_FRAME_FRAME_BASED 0x11
83 #define VS_FORMAT_STREAM_BASED 0x12
84 #define VS_FORMAT_H264 0x13 /* UVC 1.5 */
85 #define VS_FRAME_H264 0x14 /* UVC 1.5 */
86 #define VS_FORMAT_H264_SIMULCAST 0x15 /* UVC 1.5 */
87 #define VS_FORMAT_VP8 0x16 /* UVC 1.5 */
88 #define VS_FRAME_VP8 0x17 /* UVC 1.5 */
89 #define VS_FORMAT_VP8_SIMULCAST 0x18 /* UVC 1.5 */
91 /* A.7 Video Class-Specific Endpoint Descriptor Subtypes */
92 #define EP_INTERRUPT 0x03
94 /* A.9.1 Video Control Interface Control Selectors */
95 #define VC_CONTROL_UNDEFINED 0x00
96 #define VC_VIDEO_POWER_MODE_CONTROL 0x01
97 #define VC_REQUEST_ERROR_CODE_CONTROL 0x02
98 #define VC_REQUEST_INDICATE_HOST_CLOCK_CONTROL 0x03 /* Pre-UVC 1.1 */
100 /* A.9.3 Selector Unit Control Selectors */
101 #define SU_CONTROL_UNDEFINED 0x00
102 #define SU_INPUT_SELECT_CONTROL 0x01
104 /* A.9.4 Camera Terminal Control Selectors */
105 #define CT_CONTROL_UNDEFINED 0x00
106 #define CT_SCANNING_MODE_CONTROL 0x01
107 #define CT_AE_MODE_CONTROL 0x02
108 #define CT_AE_PRIORITY_CONTROL 0x03
109 #define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
110 #define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
111 #define CT_FOCUS_ABSOLUTE_CONTROL 0x06
112 #define CT_FOCUS_RELATIVE_CONTROL 0x07
113 #define CT_FOCUS_AUTO_CONTROL 0x08
114 #define CT_IRIS_ABSOLUTE_CONTROL 0x09
115 #define CT_IRIS_RELATIVE_CONTROL 0x0A
116 #define CT_ZOOM_ABSOLUTE_CONTROL 0x0B
117 #define CT_ZOOM_RELATIVE_CONTROL 0x0C
118 #define CT_PANTILT_ABSOLUTE_CONTROL 0x0D
119 #define CT_PANTILT_RELATIVE_CONTROL 0x0E
120 #define CT_ROLL_ABSOLUTE_CONTROL 0x0F
121 #define CT_ROLL_RELATIVE_CONTROL 0x10
122 #define CT_PRIVACY_CONTROL 0x11
123 #define CT_FOCUS_SIMPLE_CONTROL 0x12 /* UVC 1.5 */
124 #define CT_WINDOW_CONTROL 0x13 /* UVC 1.5 */
125 #define CT_REGION_OF_INTEREST_CONTROL 0x14 /* UVC 1.5 */
127 /* A.9.5 Processing Unit Control Selectors */
128 #define PU_CONTROL_UNDEFINED 0x00
129 #define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
130 #define PU_BRIGHTNESS_CONTROL 0x02
131 #define PU_CONTRAST_CONTROL 0x03
132 #define PU_GAIN_CONTROL 0x04
133 #define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
134 #define PU_HUE_CONTROL 0x06
135 #define PU_SATURATION_CONTROL 0x07
136 #define PU_SHARPNESS_CONTROL 0x08
137 #define PU_GAMMA_CONTROL 0x09
138 #define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0A
139 #define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0B
140 #define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0C
141 #define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0D
142 #define PU_DIGITAL_MULTIPLIER_CONTROL 0x0E
143 #define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0F
144 #define PU_HUE_AUTO_CONTROL 0x10
145 #define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
146 #define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
147 #define PU_CONTRAST_AUTO_CONTROL 0x13
149 /* A.9.7 VideoStreaming Interface Control Selectors */
150 #define VS_CONTROL_UNDEFINED 0x00
151 #define VS_PROBE_CONTROL 0x01
152 #define VS_COMMIT_CONTROL 0x02
153 #define VS_STILL_PROBE_CONTROL 0x03
154 #define VS_STILL_COMMIT_CONTROL 0x04
155 #define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
156 #define VS_STREAM_ERROR_CODE_CONTROL 0x06
157 #define VS_GENERATE_KEY_FRAME_CONTROL 0x07
158 #define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
159 #define VS_SYNCH_DELAY_CONTROL 0x09
161 /* Appendix B Terminal Types */
162 #define TT_VENDOR_SPECIFIC 0x100
163 #define TT_STREAMING 0x101
164 #define ITT_VENDOR_SPECIFIC 0x200
165 #define ITT_CAMERA 0x201
166 #define ITT_MEDIA_TRANSPORT_INPUT 0x202
167 #define OTT_VENDOR_SPECIFIC 0x300
168 #define OTT_DISPLAY 0x301
169 #define OTT_MEDIA_TRANSPORT_OUTPUT 0x302
170 #define EXTERNAL_VENDOR_SPECIFIC 0x400
171 #define COMPOSITE_CONNECTOR 0x401
172 #define SVIDEO_CONNECTOR 0x402
173 #define COMPONENT_CONNECTOR 0x403
175 /* Table 2-2 Status Packet Format (VideoControl Interface as the Originator) */
176 #define CONTROL_INTERRUPT_EVENT_CONTROL_CHANGE 0
178 /* Table 4-7 Request Error Code Control bRequestErrorCode */
179 #define UVC_ERROR_NONE 0
180 #define UVC_ERROR_NOT_READY 1
181 #define UVC_ERROR_WRONG_STATE 2
182 #define UVC_ERROR_POWER 3
183 #define UVC_ERROR_OUT_OF_RANGE 4
184 #define UVC_ERROR_INVALID_UNIT 5
185 #define UVC_ERROR_INVALID_CONTROL 6
186 #define UVC_ERROR_INVALID_REQUEST 7
187 #define UVC_ERROR_INVALID_VALUE 8
188 #define UVC_ERROR_UNKNOWN 255
190 /* A.8 Video Class-Specific Request Codes */
191 #define USB_SETUP_SET_CUR 0x01
192 #define USB_SETUP_SET_CUR_ALL 0x11 /* UVC 1.5 */
193 #define USB_SETUP_GET_CUR 0x81
194 #define USB_SETUP_GET_MIN 0x82
195 #define USB_SETUP_GET_MAX 0x83
196 #define USB_SETUP_GET_RES 0x84
197 #define USB_SETUP_GET_LEN 0x85
198 #define USB_SETUP_GET_INFO 0x86
199 #define USB_SETUP_GET_DEF 0x87
200 #define USB_SETUP_GET_CUR_ALL 0x91 /* UVC 1.5 */
201 #define USB_SETUP_GET_MIN_ALL 0x92 /* UVC 1.5 */
202 #define USB_SETUP_GET_MAX_ALL 0x93 /* UVC 1.5 */
203 #define USB_SETUP_GET_RES_ALL 0x94 /* UVC 1.5 */
204 #define USB_SETUP_GET_DEF_ALL 0x97 /* UVC 1.5 */
206 /* dissector handles */
207 static dissector_handle_t usb_vid_control_handle
;
208 static dissector_handle_t usb_vid_descriptor_handle
;
209 static dissector_handle_t usb_vid_interrupt_handle
;
211 /* protocols and header fields */
212 static int proto_usb_vid
;
214 static int hf_usb_vid_control_entity
;
215 static int hf_usb_vid_control_interface
;
216 static int hf_usb_vid_control_selector
;
217 static int hf_usb_vid_epdesc_subtype
;
218 static int hf_usb_vid_epdesc_max_transfer_sz
;
219 static int hf_usb_vid_control_ifdesc_subtype
;
220 static int hf_usb_vid_control_ifdesc_terminal_id
;
221 static int hf_usb_vid_control_ifdesc_terminal_type
;
222 static int hf_usb_vid_control_ifdesc_assoc_terminal
;
223 static int hf_usb_vid_streaming_ifdesc_subtype
;
224 static int hf_usb_vid_streaming_ifdesc_bNumFormats
;
225 static int hf_usb_vid_control_ifdesc_unit_id
;
226 static int hf_usb_vid_request
;
227 static int hf_usb_vid_length
;
228 static int hf_usb_vid_interrupt_bStatusType
;
229 static int hf_usb_vid_interrupt_bOriginator
;
230 static int hf_usb_vid_interrupt_bAttribute
;
231 static int hf_usb_vid_control_interrupt_bEvent
;
232 static int hf_usb_vid_control_ifdesc_bcdUVC
;
233 static int hf_usb_vid_ifdesc_wTotalLength
;
234 static int hf_usb_vid_control_ifdesc_dwClockFrequency
;
235 static int hf_usb_vid_control_ifdesc_bInCollection
;
236 static int hf_usb_vid_control_ifdesc_baInterfaceNr
;
237 static int hf_usb_vid_control_ifdesc_iTerminal
;
238 static int hf_usb_vid_control_ifdesc_src_id
;
239 static int hf_usb_vid_cam_objective_focal_len_min
;
240 static int hf_usb_vid_cam_objective_focal_len_max
;
241 static int hf_usb_vid_cam_ocular_focal_len
;
242 static int hf_usb_vid_bControlSize
;
243 static int hf_usb_vid_bmControl
;
244 static int hf_usb_vid_bmControl_bytes
;
245 static int hf_usb_vid_control_default
;
246 static int hf_usb_vid_control_min
;
247 static int hf_usb_vid_control_max
;
248 static int hf_usb_vid_control_res
;
249 static int hf_usb_vid_control_cur
;
250 static int hf_usb_vid_control_info
;
251 static int hf_usb_vid_control_info_D
[7];
252 static int hf_usb_vid_control_length
;
253 static int hf_usb_vid_cam_control_D
[22];
254 static int hf_usb_vid_proc_control_D
[19];
255 static int hf_usb_vid_proc_standards_D
[6];
256 static int hf_usb_vid_exten_guid
;
257 static int hf_usb_vid_exten_num_controls
;
258 static int hf_usb_vid_num_inputs
;
259 static int hf_usb_vid_sources
;
260 static int hf_usb_vid_streaming_bmInfo
;
261 static int hf_usb_vid_streaming_info_D
[1];
262 static int hf_usb_vid_streaming_terminal_link
;
263 static int hf_usb_vid_streaming_still_capture_method
;
264 static int hf_usb_vid_streaming_trigger_support
;
265 static int hf_usb_vid_streaming_trigger_usage
;
266 static int hf_usb_vid_streaming_control_D
[6];
267 static int hf_usb_vid_format_index
;
268 static int hf_usb_vid_format_num_frame_descriptors
;
269 static int hf_usb_vid_format_guid
;
270 static int hf_usb_vid_format_bits_per_pixel
;
271 static int hf_usb_vid_default_frame_index
;
272 static int hf_usb_vid_aspect_ratio_x
;
273 static int hf_usb_vid_aspect_ratio_y
;
274 static int hf_usb_vid_interlace_flags
;
275 static int hf_usb_vid_is_interlaced
;
276 static int hf_usb_vid_interlaced_fields
;
277 static int hf_usb_vid_field_1_first
;
278 static int hf_usb_vid_field_pattern
;
279 static int hf_usb_vid_copy_protect
;
280 static int hf_usb_vid_variable_size
;
281 static int hf_usb_vid_frame_index
;
282 static int hf_usb_vid_frame_capabilities
;
283 static int hf_usb_vid_frame_stills_supported
;
284 static int hf_usb_vid_frame_fixed_frame_rate
;
285 static int hf_usb_vid_frame_width
;
286 static int hf_usb_vid_frame_height
;
287 static int hf_usb_vid_frame_min_bit_rate
;
288 static int hf_usb_vid_frame_max_bit_rate
;
289 static int hf_usb_vid_frame_max_frame_sz
;
290 static int hf_usb_vid_frame_default_interval
;
291 static int hf_usb_vid_frame_bytes_per_line
;
292 static int hf_usb_vid_mjpeg_flags
;
293 static int hf_usb_vid_mjpeg_fixed_samples
;
294 static int hf_usb_vid_probe_hint
;
295 static int hf_usb_vid_probe_hint_D
[5];
296 static int hf_usb_vid_frame_interval
;
297 static int hf_usb_vid_probe_key_frame_rate
;
298 static int hf_usb_vid_probe_p_frame_rate
;
299 static int hf_usb_vid_probe_comp_quality
;
300 static int hf_usb_vid_probe_comp_window
;
301 static int hf_usb_vid_probe_delay
;
302 static int hf_usb_vid_probe_max_frame_sz
;
303 static int hf_usb_vid_probe_max_payload_sz
;
304 static int hf_usb_vid_probe_clock_freq
;
305 static int hf_usb_vid_probe_framing
;
306 static int hf_usb_vid_probe_framing_D
[2];
307 static int hf_usb_vid_probe_preferred_ver
;
308 static int hf_usb_vid_probe_min_ver
;
309 static int hf_usb_vid_probe_max_ver
;
310 static int hf_usb_vid_frame_interval_type
;
311 static int hf_usb_vid_frame_min_interval
;
312 static int hf_usb_vid_frame_max_interval
;
313 static int hf_usb_vid_frame_step_interval
;
314 static int hf_usb_vid_color_primaries
;
315 static int hf_usb_vid_transfer_characteristics
;
316 static int hf_usb_vid_matrix_coefficients
;
317 static int hf_usb_vid_max_multiplier
;
318 static int hf_usb_vid_iProcessing
;
319 static int hf_usb_vid_iExtension
;
320 static int hf_usb_vid_iSelector
;
321 static int hf_usb_vid_proc_standards
;
322 static int hf_usb_vid_request_error
;
323 static int hf_usb_vid_descriptor_data
;
324 static int hf_usb_vid_control_data
;
325 static int hf_usb_vid_control_value
;
326 static int hf_usb_vid_value_data
;
330 static int ett_usb_vid
;
331 static int ett_descriptor_video_endpoint
;
332 static int ett_descriptor_video_control
;
333 static int ett_descriptor_video_streaming
;
334 static int ett_camera_controls
;
335 static int ett_processing_controls
;
336 static int ett_streaming_controls
;
337 static int ett_streaming_info
;
338 static int ett_interlace_flags
;
339 static int ett_frame_capability_flags
;
340 static int ett_mjpeg_flags
;
341 static int ett_video_probe
;
342 static int ett_probe_hint
;
343 static int ett_probe_framing
;
344 static int ett_video_standards
;
345 static int ett_control_capabilities
;
347 static expert_field ei_usb_vid_subtype_unknown
;
348 static expert_field ei_usb_vid_bitmask_len
;
351 static const value_string vc_ep_descriptor_subtypes
[] = {
352 { EP_INTERRUPT
, "Interrupt" },
356 static const value_string vid_descriptor_type_vals
[] = {
357 {CS_INTERFACE
, "video class interface"},
358 {CS_ENDPOINT
, "video class endpoint"},
361 static value_string_ext vid_descriptor_type_vals_ext
=
362 VALUE_STRING_EXT_INIT(vid_descriptor_type_vals
);
364 static const value_string vc_if_descriptor_subtypes
[] = {
365 { VC_HEADER
, "Header" },
366 { VC_INPUT_TERMINAL
, "Input Terminal" },
367 { VC_OUTPUT_TERMINAL
, "Output Terminal" },
368 { VC_SELECTOR_UNIT
, "Selector Unit" },
369 { VC_PROCESSING_UNIT
, "Processing Unit" },
370 { VC_EXTENSION_UNIT
, "Extension Unit" },
371 { VC_ENCODING_UNIT
, "Encoding Unit" },
374 static value_string_ext vc_if_descriptor_subtypes_ext
=
375 VALUE_STRING_EXT_INIT(vc_if_descriptor_subtypes
);
377 static const value_string cs_control_interface
[] = {
378 { VC_CONTROL_UNDEFINED
, "Undefined" },
379 { VC_VIDEO_POWER_MODE_CONTROL
, "Video Power Mode" },
380 { VC_REQUEST_ERROR_CODE_CONTROL
, "Request Error Code" },
381 { VC_REQUEST_INDICATE_HOST_CLOCK_CONTROL
, "Request Indicate Host Clock" },
384 static value_string_ext cs_control_interface_ext
=
385 VALUE_STRING_EXT_INIT(cs_control_interface
);
387 static const value_string cs_streaming_interface
[] = {
388 { VS_CONTROL_UNDEFINED
, "Undefined" },
389 { VS_PROBE_CONTROL
, "Probe" },
390 { VS_COMMIT_CONTROL
, "Commit" },
391 { VS_STILL_PROBE_CONTROL
, "Still Probe" },
392 { VS_STILL_COMMIT_CONTROL
, "Still Commit" },
393 { VS_STILL_IMAGE_TRIGGER_CONTROL
, "Still Image Trigger" },
394 { VS_STREAM_ERROR_CODE_CONTROL
, "Stream Error Code" },
395 { VS_GENERATE_KEY_FRAME_CONTROL
, "Generate Key Frame" },
396 { VS_UPDATE_FRAME_SEGMENT_CONTROL
, "Update Frame Segment" },
397 { VS_SYNCH_DELAY_CONTROL
, "Synch Delay" },
400 static value_string_ext cs_streaming_interface_ext
=
401 VALUE_STRING_EXT_INIT(cs_streaming_interface
);
403 static const value_string cs_selector_unit
[] = {
404 { SU_CONTROL_UNDEFINED
, "Undefined" },
405 { SU_INPUT_SELECT_CONTROL
, "Input Select" },
408 static value_string_ext cs_selector_unit_ext
=
409 VALUE_STRING_EXT_INIT(cs_selector_unit
);
411 static const value_string cs_camera_terminal
[] = {
412 { CT_CONTROL_UNDEFINED
, "Undefined" },
413 { CT_SCANNING_MODE_CONTROL
, "Scanning Mode" },
414 { CT_AE_MODE_CONTROL
, "Auto-Exposure Mode" },
415 { CT_AE_PRIORITY_CONTROL
, "Auto-Exposure Priority" },
416 { CT_EXPOSURE_TIME_ABSOLUTE_CONTROL
, "Exposure Time (Absolute)" },
417 { CT_EXPOSURE_TIME_RELATIVE_CONTROL
, "Exposure Time (Relative)" },
418 { CT_FOCUS_ABSOLUTE_CONTROL
, "Focus (Absolute)" },
419 { CT_FOCUS_RELATIVE_CONTROL
, "Focus (Relative)" },
420 { CT_FOCUS_AUTO_CONTROL
, "Focus, Auto" },
421 { CT_IRIS_ABSOLUTE_CONTROL
, "Iris (Absolute)" },
422 { CT_IRIS_RELATIVE_CONTROL
, "Iris (Relative)" },
423 { CT_ZOOM_ABSOLUTE_CONTROL
, "Zoom (Absolute)" },
424 { CT_ZOOM_RELATIVE_CONTROL
, "Zoom (Relative)" },
425 { CT_PANTILT_ABSOLUTE_CONTROL
, "PanTilt (Absolute)" },
426 { CT_PANTILT_RELATIVE_CONTROL
, "PanTilt (Relative)" },
427 { CT_ROLL_ABSOLUTE_CONTROL
, "Roll (Absolute)" },
428 { CT_ROLL_RELATIVE_CONTROL
, "Roll (Relative)" },
429 { CT_PRIVACY_CONTROL
, "Privacy" },
430 { CT_FOCUS_SIMPLE_CONTROL
, "Focus (Simple)" },
431 { CT_WINDOW_CONTROL
, "Window" },
432 { CT_REGION_OF_INTEREST_CONTROL
, "Region of Interest" },
435 static value_string_ext cs_camera_terminal_ext
=
436 VALUE_STRING_EXT_INIT(cs_camera_terminal
);
438 static const value_string cs_processing_unit
[] = {
439 { PU_CONTROL_UNDEFINED
, "Undefined" },
440 { PU_BACKLIGHT_COMPENSATION_CONTROL
, "Backlight Compensation" },
441 { PU_BRIGHTNESS_CONTROL
, "Brightness" },
442 { PU_CONTRAST_CONTROL
, "Contrast" },
443 { PU_GAIN_CONTROL
, "Gain" },
444 { PU_POWER_LINE_FREQUENCY_CONTROL
, "Power Line Frequency" },
445 { PU_HUE_CONTROL
, "Hue" },
446 { PU_SATURATION_CONTROL
, "Saturation" },
447 { PU_SHARPNESS_CONTROL
, "Sharpness" },
448 { PU_GAMMA_CONTROL
, "Gamma" },
449 { PU_WHITE_BALANCE_TEMPERATURE_CONTROL
, "White Balance Temperature" },
450 { PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL
,"White Balance Temperature Auto" },
451 { PU_WHITE_BALANCE_COMPONENT_CONTROL
, "White Balance Component" },
452 { PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL
, "White Balance Component Auto" },
453 { PU_DIGITAL_MULTIPLIER_CONTROL
, "Digital Multiplier" },
454 { PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL
, "Digital Multiplier Limit" },
455 { PU_HUE_AUTO_CONTROL
, "Hue Auto" },
456 { PU_ANALOG_VIDEO_STANDARD_CONTROL
, "Video Standard" },
457 { PU_ANALOG_LOCK_STATUS_CONTROL
, "Analog Lock Status" },
458 { PU_CONTRAST_AUTO_CONTROL
, "Contrast Auto" },
461 static value_string_ext cs_processing_unit_ext
=
462 VALUE_STRING_EXT_INIT(cs_processing_unit
);
464 static const value_string vc_terminal_types
[] = {
465 { TT_VENDOR_SPECIFIC
, "Vendor Specific", },
466 { TT_STREAMING
, "Streaming" },
467 { ITT_VENDOR_SPECIFIC
, "Vendor Specific Input" },
468 { ITT_CAMERA
, "Camera Input" },
469 { ITT_MEDIA_TRANSPORT_INPUT
, "Media Transport Input" },
470 { OTT_VENDOR_SPECIFIC
, "Vendor Specific Output" },
471 { OTT_DISPLAY
, "Display Output" },
472 { OTT_MEDIA_TRANSPORT_OUTPUT
, "Media Transport Output" },
473 { EXTERNAL_VENDOR_SPECIFIC
, "Vendor Specific External" },
474 { COMPOSITE_CONNECTOR
, "Composite Connector" },
475 { SVIDEO_CONNECTOR
, "SVideo Connector" },
476 { COMPONENT_CONNECTOR
, "Component Connector" },
479 static value_string_ext vc_terminal_types_ext
=
480 VALUE_STRING_EXT_INIT(vc_terminal_types
);
482 static const value_string vs_if_descriptor_subtypes
[] = {
483 { VS_UNDEFINED
, "Undefined" },
484 { VS_INPUT_HEADER
, "Input Header" },
485 { VS_OUTPUT_HEADER
, "Output Header" },
486 { VS_STILL_IMAGE_FRAME
, "Still Image Frame" },
487 { VS_FORMAT_UNCOMPRESSED
, "Format Uncompressed" },
488 { VS_FRAME_UNCOMPRESSED
, "Frame Uncompressed" },
489 { VS_FORMAT_MJPEG
, "Format MJPEG" },
490 { VS_FRAME_MJPEG
, "Frame MJPEG" },
491 { VS_FORMAT_MPEG1
, "Format MPEG1" },
492 { VS_FORMAT_MPEG2PS
, "Format MPEG2-PS" },
493 { VS_FORMAT_MPEG2TS
, "Format MPEG2-TS" },
494 { VS_FORMAT_MPEG4SL
, "Format MPEG4-SL" },
495 { VS_FORMAT_DV
, "Format DV" },
496 { VS_COLORFORMAT
, "Colorformat" },
497 { VS_FORMAT_VENDOR
, "Format Vendor" },
498 { VS_FRAME_VENDOR
, "Frame Vendor" },
499 { VS_FORMAT_FRAME_BASED
, "Format Frame-Based" },
500 { VS_FRAME_FRAME_BASED
, "Frame Frame-Based" },
501 { VS_FORMAT_STREAM_BASED
, "Format Stream Based" },
502 { VS_FORMAT_H264
, "Format H.264" },
503 { VS_FRAME_H264
, "Frame H.264" },
504 { VS_FORMAT_H264_SIMULCAST
, "Format H.264 Simulcast" },
505 { VS_FORMAT_VP8
, "Format VP8" },
506 { VS_FRAME_VP8
, "Frame VP8" },
507 { VS_FORMAT_VP8_SIMULCAST
, "Format VP8 Simulcast" },
510 static value_string_ext vs_if_descriptor_subtypes_ext
=
511 VALUE_STRING_EXT_INIT(vs_if_descriptor_subtypes
);
513 static const value_string interrupt_status_types
[] = {
514 { INT_VIDEOCONTROL
, "VideoControl Interface" },
515 { INT_VIDEOSTREAMING
, "VideoStreaming Interface" },
519 static const value_string control_change_types
[] = {
520 { CONTROL_CHANGE_VALUE
, "Value" },
521 { CONTROL_CHANGE_INFO
, "Info" },
522 { CONTROL_CHANGE_FAILURE
, "Failure" },
523 { CONTROL_CHANGE_MIN
, "Min" },
524 { CONTROL_CHANGE_MAX
, "Max" },
527 static value_string_ext control_change_types_ext
=
528 VALUE_STRING_EXT_INIT(control_change_types
);
530 static const value_string control_interrupt_events
[] = {
531 { CONTROL_INTERRUPT_EVENT_CONTROL_CHANGE
, "Control Change" },
535 /* Table 3-13 VS Interface Input Header Descriptor - bStillCaptureMethod field */
536 static const value_string vs_still_capture_methods
[] = {
538 { 1, "Uninterrupted streaming" },
539 { 2, "Suspended streaming" },
540 { 3, "Dedicated pipe" },
543 static value_string_ext vs_still_capture_methods_ext
=
544 VALUE_STRING_EXT_INIT(vs_still_capture_methods
);
546 /* Table 3-13 VS Interface Input Header Descriptor - bTriggerUsage field */
547 static const value_string vs_trigger_usage
[] = {
548 { 0, "Initiate still image capture" },
549 { 1, "General purpose button event" },
553 /* bmInterlaceFlags for format descriptors */
554 static const true_false_string is_interlaced_meaning
= {
559 /* bmInterlaceFlags for format descriptors */
560 static const true_false_string interlaced_fields_meaning
= {
565 /* bmInterlaceFlags for format descriptors */
566 static const value_string field_pattern_meaning
[] = {
567 { 0, "Field 1 only" },
568 { 1, "Field 2 only" },
569 { 2, "Regular pattern of fields 1 and 2" },
570 { 3, "Random pattern of fields 1 and 2" },
573 static value_string_ext field_pattern_meaning_ext
=
574 VALUE_STRING_EXT_INIT(field_pattern_meaning
);
576 /* bCopyProtect for format descriptors */
577 static const value_string copy_protect_meaning
[] = {
578 { 0, "No restrictions" },
579 { 1, "Restrict duplication" },
583 /* Table 4-46 Video Probe and Commit Controls - bmHint field */
584 static const true_false_string probe_hint_meaning
= {
589 /* Table 3-19 Color Matching Descriptor - bColorPrimaries field */
590 static const value_string color_primaries_meaning
[] = {
591 { 0, "Unspecified" },
592 { 1, "BT.709, sRGB" },
593 { 2, "BT.470-2 (M)" },
594 { 3, "BT.470-2 (B,G)" },
599 static value_string_ext color_primaries_meaning_ext
=
600 VALUE_STRING_EXT_INIT(color_primaries_meaning
);
602 /* Table 3-19 Color Matching Descriptor - bTransferCharacteristics field */
603 static const value_string color_transfer_characteristics
[] = {
604 { 0, "Unspecified" },
606 { 2, "BT.470-2 (M)" },
607 { 3, "BT.470-2 (B,G)" },
610 { 6, "Linear (V=Lc)" },
614 static value_string_ext color_transfer_characteristics_ext
=
615 VALUE_STRING_EXT_INIT(color_transfer_characteristics
);
617 /* Table 3-19 Color Matching Descriptor - bMatrixCoefficients field */
618 static const value_string matrix_coefficients_meaning
[] = {
619 { 0, "Unspecified" },
622 { 3, "BT.470-2 (B,G)" },
623 { 4, "SMPTE 170M (BT.601)" },
627 static value_string_ext matrix_coefficients_meaning_ext
=
628 VALUE_STRING_EXT_INIT(matrix_coefficients_meaning
);
630 static const value_string request_error_codes
[] = {
631 { UVC_ERROR_NONE
, "No error" },
632 { UVC_ERROR_NOT_READY
, "Not ready" },
633 { UVC_ERROR_WRONG_STATE
, "Wrong state" },
634 { UVC_ERROR_POWER
, "Insufficient power" } ,
635 { UVC_ERROR_OUT_OF_RANGE
, "Out of range" },
636 { UVC_ERROR_INVALID_UNIT
, "Invalid unit" },
637 { UVC_ERROR_INVALID_CONTROL
, "Invalid control" },
638 { UVC_ERROR_INVALID_REQUEST
, "Invalid request" },
639 { UVC_ERROR_INVALID_VALUE
, "Invalid value within range" },
640 { UVC_ERROR_UNKNOWN
, "Unknown" },
643 static value_string_ext request_error_codes_ext
=
644 VALUE_STRING_EXT_INIT(request_error_codes
);
646 /* There is one such structure per terminal or unit per interface */
651 uint16_t terminalType
;
654 /* video_entity_t's (units/terminals) associated with each video interface */
655 /* There is one such structure for each video conversation (interface) */
656 typedef struct _video_conv_info_t
{
657 wmem_tree_t
* entities
; /* indexed by entity ID */
660 /*****************************************************************************/
661 /* UTILITY FUNCTIONS */
662 /*****************************************************************************/
665 * Dissector for variable-length bmControl bitmask / bControlSize pair.
667 * Creates an item for bControlSize, and a subtree for the bmControl bitmask.
669 * @param tree protocol tree to be the parent of the bitmask subtree
670 * @param tvb the tv_buff with the (remaining) packet data
671 * @param offset where in tvb to find bControlSize field
672 * @param ett_subtree index of the subtree to use for this bitmask
673 * @param bm_items NULL-terminated array of pointers that lists all the fields
676 * @return offset within tvb at which dissection should continue
679 dissect_bmControl(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
,
680 int ett_subtree
, int * const *bm_items
)
684 bm_size
= tvb_get_uint8(tvb
, offset
);
685 proto_tree_add_item(tree
, hf_usb_vid_bControlSize
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
690 proto_tree_add_bitmask_len(tree
, tvb
, offset
, bm_size
, hf_usb_vid_bmControl
,
691 ett_subtree
, bm_items
, &ei_usb_vid_bitmask_len
, ENC_LITTLE_ENDIAN
);
698 /*****************************************************************************/
699 /* VIDEO CONTROL DESCRIPTORS */
700 /*****************************************************************************/
702 /* Dissect a Camera Terminal descriptor */
704 dissect_usb_video_camera_terminal(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
706 static int * const control_bits
[] = {
707 &hf_usb_vid_cam_control_D
[0],
708 &hf_usb_vid_cam_control_D
[1],
709 &hf_usb_vid_cam_control_D
[2],
710 &hf_usb_vid_cam_control_D
[3],
711 &hf_usb_vid_cam_control_D
[4],
712 &hf_usb_vid_cam_control_D
[5],
713 &hf_usb_vid_cam_control_D
[6],
714 &hf_usb_vid_cam_control_D
[7],
715 &hf_usb_vid_cam_control_D
[8],
716 &hf_usb_vid_cam_control_D
[9],
717 &hf_usb_vid_cam_control_D
[10],
718 &hf_usb_vid_cam_control_D
[11],
719 &hf_usb_vid_cam_control_D
[12],
720 &hf_usb_vid_cam_control_D
[13],
721 &hf_usb_vid_cam_control_D
[14],
722 &hf_usb_vid_cam_control_D
[15],
723 &hf_usb_vid_cam_control_D
[16],
724 &hf_usb_vid_cam_control_D
[17],
725 &hf_usb_vid_cam_control_D
[18],
726 &hf_usb_vid_cam_control_D
[19],
727 &hf_usb_vid_cam_control_D
[20],
728 &hf_usb_vid_cam_control_D
[21],
732 DISSECTOR_ASSERT(array_length(control_bits
) == (1+array_length(hf_usb_vid_cam_control_D
)));
734 proto_tree_add_item(tree
, hf_usb_vid_cam_objective_focal_len_min
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
736 proto_tree_add_item(tree
, hf_usb_vid_cam_objective_focal_len_max
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
738 proto_tree_add_item(tree
, hf_usb_vid_cam_ocular_focal_len
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
741 offset
= dissect_bmControl(tree
, tvb
, offset
, ett_camera_controls
, control_bits
);
746 /* Dissect a Processing Unit descriptor */
748 dissect_usb_video_processing_unit(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
750 static int * const control_bits
[] = {
751 &hf_usb_vid_proc_control_D
[0],
752 &hf_usb_vid_proc_control_D
[1],
753 &hf_usb_vid_proc_control_D
[2],
754 &hf_usb_vid_proc_control_D
[3],
755 &hf_usb_vid_proc_control_D
[4],
756 &hf_usb_vid_proc_control_D
[5],
757 &hf_usb_vid_proc_control_D
[6],
758 &hf_usb_vid_proc_control_D
[7],
759 &hf_usb_vid_proc_control_D
[8],
760 &hf_usb_vid_proc_control_D
[9],
761 &hf_usb_vid_proc_control_D
[10],
762 &hf_usb_vid_proc_control_D
[11],
763 &hf_usb_vid_proc_control_D
[12],
764 &hf_usb_vid_proc_control_D
[13],
765 &hf_usb_vid_proc_control_D
[14],
766 &hf_usb_vid_proc_control_D
[15],
767 &hf_usb_vid_proc_control_D
[16],
768 &hf_usb_vid_proc_control_D
[17],
769 &hf_usb_vid_proc_control_D
[18],
773 DISSECTOR_ASSERT(array_length(control_bits
) == (1+array_length(hf_usb_vid_proc_control_D
)));
775 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_src_id
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
776 proto_tree_add_item(tree
, hf_usb_vid_max_multiplier
, tvb
, offset
+1, 2, ENC_LITTLE_ENDIAN
);
779 offset
= dissect_bmControl(tree
, tvb
, offset
, ett_processing_controls
, control_bits
);
781 proto_tree_add_item(tree
, hf_usb_vid_iProcessing
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
784 /* UVC 1.1 added bmVideoStandards */
785 if (tvb_reported_length_remaining(tvb
, offset
) > 0)
787 static int * const standard_bits
[] = {
788 &hf_usb_vid_proc_standards_D
[0],
789 &hf_usb_vid_proc_standards_D
[1],
790 &hf_usb_vid_proc_standards_D
[2],
791 &hf_usb_vid_proc_standards_D
[3],
792 &hf_usb_vid_proc_standards_D
[4],
793 &hf_usb_vid_proc_standards_D
[5],
797 DISSECTOR_ASSERT(array_length(standard_bits
) == (1+array_length(hf_usb_vid_proc_standards_D
)));
799 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_proc_standards
,
800 ett_video_standards
, standard_bits
, ENC_NA
);
807 /* Dissect a Selector Unit descriptor */
809 dissect_usb_video_selector_unit(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
813 num_inputs
= tvb_get_uint8(tvb
, offset
);
814 proto_tree_add_item(tree
, hf_usb_vid_num_inputs
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
819 proto_tree_add_item(tree
, hf_usb_vid_sources
, tvb
, offset
, num_inputs
, ENC_NA
);
820 offset
+= num_inputs
;
823 proto_tree_add_item(tree
, hf_usb_vid_iSelector
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
829 /* Dissect an Extension Unit descriptor */
831 dissect_usb_video_extension_unit(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
834 uint8_t control_size
;
836 proto_tree_add_item(tree
, hf_usb_vid_exten_guid
, tvb
, offset
, 16, ENC_LITTLE_ENDIAN
);
837 proto_tree_add_item(tree
, hf_usb_vid_exten_num_controls
, tvb
, offset
+16, 1, ENC_LITTLE_ENDIAN
);
840 num_inputs
= tvb_get_uint8(tvb
, offset
);
841 proto_tree_add_item(tree
, hf_usb_vid_num_inputs
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
846 proto_tree_add_item(tree
, hf_usb_vid_sources
, tvb
, offset
, num_inputs
, ENC_NA
);
847 offset
+= num_inputs
;
850 control_size
= tvb_get_uint8(tvb
, offset
);
851 proto_tree_add_item(tree
, hf_usb_vid_bControlSize
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
854 if (control_size
> 0)
856 if (control_size
<= proto_registrar_get_length(hf_usb_vid_bmControl
))
858 proto_tree_add_item(tree
, hf_usb_vid_bmControl
, tvb
, offset
, control_size
,
863 /* Too big to display as integer */
864 /* @todo Display as FT_BYTES with a big-endian disclaimer?
865 * See https://gitlab.com/wireshark/wireshark/-/issues/7933
867 proto_tree_add_bytes_format(tree
, hf_usb_vid_bmControl_bytes
, tvb
, offset
, control_size
, NULL
, "bmControl");
869 offset
+= control_size
;
872 proto_tree_add_item(tree
, hf_usb_vid_iExtension
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
879 * Dissector for video class control interface descriptors
881 * @param parent_tree the protocol tree to be the parent of the descriptor subtree
882 * @param tvb the tv_buff with the (remaining) packet data
883 * On entry the gaze is set to the descriptor length field.
884 * @param descriptor_len Length of the descriptor to dissect
885 * @param pinfo Information associated with the packet being dissected
887 * @return offset within tvb at which dissection should continue
890 dissect_usb_video_control_interface_descriptor(proto_tree
*parent_tree
, tvbuff_t
*tvb
,
891 uint8_t descriptor_len
, packet_info
*pinfo
, urb_info_t
*urb
)
893 video_conv_info_t
*video_conv_info
= NULL
;
894 video_entity_t
*entity
= NULL
;
895 proto_item
*item
= NULL
;
896 proto_item
*subtype_item
= NULL
;
897 proto_tree
*tree
= NULL
;
898 uint8_t entity_id
= 0;
899 uint16_t terminal_type
= 0;
903 subtype
= tvb_get_uint8(tvb
, offset
+2);
907 const char *subtype_str
;
909 subtype_str
= val_to_str_ext(subtype
, &vc_if_descriptor_subtypes_ext
, "Unknown (0x%x)");
911 tree
= proto_tree_add_subtree_format(parent_tree
, tvb
, offset
, descriptor_len
,
912 ett_descriptor_video_control
, &item
, "VIDEO CONTROL INTERFACE DESCRIPTOR [%s]",
917 dissect_usb_descriptor_header(tree
, tvb
, offset
, &vid_descriptor_type_vals_ext
);
918 subtype_item
= proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_subtype
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
921 if (subtype
== VC_HEADER
)
923 uint8_t num_vs_interfaces
;
925 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_bcdUVC
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
926 proto_tree_add_item(tree
, hf_usb_vid_ifdesc_wTotalLength
, tvb
, offset
+2, 2, ENC_LITTLE_ENDIAN
);
927 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_dwClockFrequency
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
929 num_vs_interfaces
= tvb_get_uint8(tvb
, offset
+8);
930 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_bInCollection
, tvb
, offset
+8, 1, ENC_LITTLE_ENDIAN
);
932 if (num_vs_interfaces
> 0)
934 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_baInterfaceNr
, tvb
, offset
+9, num_vs_interfaces
, ENC_NA
);
937 offset
+= 9 + num_vs_interfaces
;
939 else if ((subtype
== VC_INPUT_TERMINAL
) || (subtype
== VC_OUTPUT_TERMINAL
))
941 /* Fields common to input and output terminals */
942 entity_id
= tvb_get_uint8(tvb
, offset
);
943 terminal_type
= tvb_get_letohs(tvb
, offset
+1);
945 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_terminal_id
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
946 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_terminal_type
, tvb
, offset
+1, 2, ENC_LITTLE_ENDIAN
);
947 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_assoc_terminal
, tvb
, offset
+3, 1, ENC_LITTLE_ENDIAN
);
950 if (subtype
== VC_OUTPUT_TERMINAL
)
952 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_src_id
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
956 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_iTerminal
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
959 if (subtype
== VC_INPUT_TERMINAL
)
961 if (terminal_type
== ITT_CAMERA
)
963 offset
= dissect_usb_video_camera_terminal(tree
, tvb
, offset
);
965 else if (terminal_type
== ITT_MEDIA_TRANSPORT_INPUT
)
971 if (subtype
== VC_OUTPUT_TERMINAL
)
973 if (terminal_type
== OTT_MEDIA_TRANSPORT_OUTPUT
)
981 /* Field common to extension / processing / selector / encoding units */
982 entity_id
= tvb_get_uint8(tvb
, offset
);
983 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_unit_id
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
986 if (subtype
== VC_PROCESSING_UNIT
)
988 offset
= dissect_usb_video_processing_unit(tree
, tvb
, offset
);
990 else if (subtype
== VC_SELECTOR_UNIT
)
992 offset
= dissect_usb_video_selector_unit(tree
, tvb
, offset
);
994 else if (subtype
== VC_EXTENSION_UNIT
)
996 offset
= dissect_usb_video_extension_unit(tree
, tvb
, offset
);
998 else if (subtype
== VC_ENCODING_UNIT
)
1004 expert_add_info_format(pinfo
, subtype_item
, &ei_usb_vid_subtype_unknown
,
1005 "Unknown VC subtype %u", subtype
);
1009 /* Soak up descriptor bytes beyond those we know how to dissect */
1010 if (offset
< descriptor_len
)
1012 proto_tree_add_item(tree
, hf_usb_vid_descriptor_data
, tvb
, offset
, descriptor_len
-offset
, ENC_NA
);
1013 /* offset = descriptor_len; */
1017 proto_item_append_text(item
, " (Entity %d)", entity_id
);
1019 if (subtype
!= VC_HEADER
&& urb
&& urb
->conv
)
1021 /* Switch to the usb_conv_info of the Video Control interface */
1022 usb_conv_info_t
*conv
= get_usb_iface_conv_info(pinfo
, urb
->conv
->interfaceNum
);
1023 video_conv_info
= (video_conv_info_t
*)conv
->class_data
;
1025 if (!video_conv_info
)
1027 video_conv_info
= wmem_new(wmem_file_scope(), video_conv_info_t
);
1028 video_conv_info
->entities
= wmem_tree_new(wmem_file_scope());
1029 conv
->class_data
= video_conv_info
;
1030 conv
->class_data_type
= USB_CONV_VIDEO
;
1031 } else if (conv
->class_data_type
!= USB_CONV_VIDEO
) {
1032 /* Stop dissection if another USB type is in the conversation */
1033 return descriptor_len
;
1036 entity
= (video_entity_t
*) wmem_tree_lookup32(video_conv_info
->entities
, entity_id
);
1039 entity
= wmem_new(wmem_file_scope(), video_entity_t
);
1040 entity
->entityID
= entity_id
;
1041 entity
->subtype
= subtype
;
1042 entity
->terminalType
= terminal_type
;
1044 wmem_tree_insert32(video_conv_info
->entities
, entity_id
, entity
);
1048 return descriptor_len
;
1051 /*****************************************************************************/
1052 /* VIDEO STREAMING DESCRIPTORS */
1053 /*****************************************************************************/
1055 /* Dissect a Video Streaming Input Header descriptor */
1057 dissect_usb_video_streaming_input_header(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
1059 uint8_t num_formats
;
1062 static int * const info_bits
[] = {
1063 &hf_usb_vid_streaming_info_D
[0],
1066 static int * const control_bits
[] = {
1067 &hf_usb_vid_streaming_control_D
[0],
1068 &hf_usb_vid_streaming_control_D
[1],
1069 &hf_usb_vid_streaming_control_D
[2],
1070 &hf_usb_vid_streaming_control_D
[3],
1071 &hf_usb_vid_streaming_control_D
[4],
1072 &hf_usb_vid_streaming_control_D
[5],
1076 DISSECTOR_ASSERT(array_length(control_bits
) == (1+array_length(hf_usb_vid_streaming_control_D
)));
1078 num_formats
= tvb_get_uint8(tvb
, offset
);
1079 proto_tree_add_item(tree
, hf_usb_vid_streaming_ifdesc_bNumFormats
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1080 proto_tree_add_item(tree
, hf_usb_vid_ifdesc_wTotalLength
, tvb
, offset
+1, 2, ENC_LITTLE_ENDIAN
);
1083 dissect_usb_endpoint_address(tree
, tvb
, offset
);
1086 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_streaming_bmInfo
,
1087 ett_streaming_info
, info_bits
, ENC_NA
);
1089 proto_tree_add_item(tree
, hf_usb_vid_streaming_terminal_link
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
1090 proto_tree_add_item(tree
, hf_usb_vid_streaming_still_capture_method
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
1093 proto_tree_add_item(tree
, hf_usb_vid_streaming_trigger_support
, tvb
, offset
, 1, ENC_NA
);
1094 if (tvb_get_uint8(tvb
, offset
) > 0)
1096 proto_tree_add_item(tree
, hf_usb_vid_streaming_trigger_usage
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
1100 proto_tree_add_uint_format_value(tree
, hf_usb_vid_streaming_trigger_usage
, tvb
, offset
+1, 1, 0, "Not applicable");
1105 /* NOTE: Can't use dissect_bmControl here because there's only one size
1106 * field for (potentially) multiple bmControl fields
1108 bm_size
= tvb_get_uint8(tvb
, offset
);
1109 proto_tree_add_item(tree
, hf_usb_vid_bControlSize
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1115 for (i
=0; i
<num_formats
; ++i
)
1117 proto_tree_add_bitmask_len(tree
, tvb
, offset
, bm_size
, hf_usb_vid_bmControl
,
1118 ett_streaming_controls
, control_bits
, &ei_usb_vid_bitmask_len
,
1128 * Dissect a known Video Payload Format descriptor.
1130 * @param tree protocol tree to which fields should be added
1131 * @param tvb the tv_buff with the (remaining) packet data
1132 * @param offset where in tvb to begin dissection.
1133 * On entry this refers to the bFormatIndex field.
1134 * @param subtype Type of format descriptor, from the
1135 * bDescriptorSubtype field
1137 * @return offset within tvb at which dissection should continue
1140 dissect_usb_video_format(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
,
1143 static int * const interlace_bits
[] = {
1144 &hf_usb_vid_is_interlaced
,
1145 &hf_usb_vid_interlaced_fields
,
1146 &hf_usb_vid_field_1_first
,
1147 &hf_usb_vid_field_pattern
,
1151 proto_item
*desc_item
;
1152 uint8_t format_index
;
1154 /* Augment the descriptor root item with the index of this descriptor */
1155 format_index
= tvb_get_uint8(tvb
, offset
);
1156 desc_item
= proto_tree_get_parent(tree
);
1157 proto_item_append_text(desc_item
, " (Format %u)", format_index
);
1159 proto_tree_add_item(tree
, hf_usb_vid_format_index
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1160 proto_tree_add_item(tree
, hf_usb_vid_format_num_frame_descriptors
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
1163 if ((subtype
== VS_FORMAT_UNCOMPRESSED
) || (subtype
== VS_FORMAT_FRAME_BASED
))
1165 /* Augment the descriptor root item with the format's four-character-code */
1166 proto_item_append_text(desc_item
, ": %s", tvb_format_text(wmem_packet_scope(), tvb
, offset
, 4));
1168 proto_tree_add_item(tree
, hf_usb_vid_format_guid
, tvb
, offset
, 16, ENC_LITTLE_ENDIAN
);
1169 proto_tree_add_item(tree
, hf_usb_vid_format_bits_per_pixel
, tvb
, offset
+16, 1, ENC_LITTLE_ENDIAN
);
1172 else if (subtype
== VS_FORMAT_MJPEG
)
1174 static int * const flags
[] = {
1175 &hf_usb_vid_mjpeg_fixed_samples
,
1179 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_mjpeg_flags
, ett_mjpeg_flags
, flags
, ENC_NA
);
1184 /* We should only be called for known format descriptor subtypes */
1185 DISSECTOR_ASSERT_NOT_REACHED();
1188 proto_tree_add_item(tree
, hf_usb_vid_default_frame_index
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1189 proto_tree_add_item(tree
, hf_usb_vid_aspect_ratio_x
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
1190 proto_tree_add_item(tree
, hf_usb_vid_aspect_ratio_y
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
1194 /* @todo Display "N/A" if Camera Terminal does not support scanning mode control */
1196 proto_tree_add_uint_format_value(tree
, hf_usb_vid_interlace_flags
, tvb
, offset
, 1, tvb_get_uint8(tvb
, offset
), "Not applicable");
1199 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_interlace_flags
,
1200 ett_interlace_flags
, interlace_bits
, ENC_NA
);
1203 proto_tree_add_item(tree
, hf_usb_vid_copy_protect
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1206 if (subtype
== VS_FORMAT_FRAME_BASED
)
1208 proto_tree_add_item(tree
, hf_usb_vid_variable_size
, tvb
, offset
, 1, ENC_NA
);
1216 * Dissect a known Video Frame descriptor.
1218 * @param tree protocol tree to which fields should be added
1219 * @param tvb the tv_buff with the (remaining) packet data
1220 * @param offset where in tvb to begin dissection.
1221 * On entry this refers to the bFrameIndex field.
1222 * @param subtype Type of frame descriptor, from the
1223 * bDescriptorSubtype field
1225 * @return offset within tvb at which dissection should continue
1228 dissect_usb_video_frame(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
,
1231 static int * const capability_bits
[] = {
1232 &hf_usb_vid_frame_stills_supported
,
1233 &hf_usb_vid_frame_fixed_frame_rate
,
1236 proto_item
*desc_item
;
1237 uint8_t bFrameIntervalType
;
1238 uint8_t frame_index
;
1239 uint16_t frame_width
;
1240 uint16_t frame_height
;
1242 frame_index
= tvb_get_uint8(tvb
, offset
);
1243 proto_tree_add_item(tree
, hf_usb_vid_frame_index
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1246 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_frame_capabilities
,
1247 ett_frame_capability_flags
, capability_bits
, ENC_NA
);
1250 proto_tree_add_item(tree
, hf_usb_vid_frame_width
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1251 proto_tree_add_item(tree
, hf_usb_vid_frame_height
, tvb
, offset
+2, 2, ENC_LITTLE_ENDIAN
);
1253 /* Augment the descriptor root item with useful information */
1254 frame_width
= tvb_get_letohs(tvb
, offset
);
1255 frame_height
= tvb_get_letohs(tvb
, offset
+2);
1256 desc_item
= proto_tree_get_parent(tree
);
1257 proto_item_append_text(desc_item
, " (Index %2u): %4u x %4u", frame_index
, frame_width
, frame_height
);
1259 proto_tree_add_item(tree
, hf_usb_vid_frame_min_bit_rate
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
1260 proto_tree_add_item(tree
, hf_usb_vid_frame_max_bit_rate
, tvb
, offset
+8, 4, ENC_LITTLE_ENDIAN
);
1263 if (subtype
!= VS_FRAME_FRAME_BASED
)
1265 proto_tree_add_item(tree
, hf_usb_vid_frame_max_frame_sz
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1269 proto_tree_add_item(tree
, hf_usb_vid_frame_default_interval
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1272 bFrameIntervalType
= tvb_get_uint8(tvb
, offset
);
1273 if (bFrameIntervalType
== 0)
1275 proto_tree_add_uint_format_value(tree
, hf_usb_vid_frame_interval_type
, tvb
, offset
, 1,
1276 bFrameIntervalType
, "Continuous (0)");
1279 if (subtype
== VS_FRAME_FRAME_BASED
)
1281 proto_tree_add_item(tree
, hf_usb_vid_frame_bytes_per_line
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1285 proto_tree_add_item(tree
, hf_usb_vid_frame_min_interval
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1286 proto_tree_add_item(tree
, hf_usb_vid_frame_max_interval
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
1287 proto_tree_add_item(tree
, hf_usb_vid_frame_step_interval
, tvb
, offset
+8, 4, ENC_LITTLE_ENDIAN
);
1293 proto_tree_add_uint_format_value(tree
, hf_usb_vid_frame_interval_type
, tvb
, offset
, 1,
1294 bFrameIntervalType
, "Discrete (%u choice%s)",
1295 bFrameIntervalType
, (bFrameIntervalType
> 1) ? "s" : "");
1298 if (subtype
== VS_FRAME_FRAME_BASED
)
1300 proto_tree_add_item(tree
, hf_usb_vid_frame_bytes_per_line
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1304 for (i
=0; i
<bFrameIntervalType
; ++i
)
1306 proto_tree_add_item(tree
, hf_usb_vid_frame_interval
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1314 /* Dissect a Color Matching descriptor */
1316 dissect_usb_video_colorformat(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
1318 proto_tree_add_item(tree
, hf_usb_vid_color_primaries
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1319 proto_tree_add_item(tree
, hf_usb_vid_transfer_characteristics
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
1320 proto_tree_add_item(tree
, hf_usb_vid_matrix_coefficients
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
1327 * Dissector for video class streaming interface descriptors.
1329 * @param parent_tree the protocol tree to be the parent of the descriptor subtree
1330 * @param tvb the tv_buff with the (remaining) packet data
1331 * On entry the gaze is set to the descriptor length field.
1332 * @param descriptor_len Length of the descriptor to dissect
1334 * @return offset within tvb at which dissection should continue
1337 dissect_usb_video_streaming_interface_descriptor(proto_tree
*parent_tree
, tvbuff_t
*tvb
,
1338 uint8_t descriptor_len
)
1342 const char *subtype_str
;
1345 subtype
= tvb_get_uint8(tvb
, offset
+2);
1347 subtype_str
= val_to_str_ext(subtype
, &vs_if_descriptor_subtypes_ext
, "Unknown (0x%x)");
1348 tree
= proto_tree_add_subtree_format(parent_tree
, tvb
, offset
, descriptor_len
,
1349 ett_descriptor_video_streaming
, NULL
, "VIDEO STREAMING INTERFACE DESCRIPTOR [%s]",
1352 dissect_usb_descriptor_header(tree
, tvb
, offset
, &vid_descriptor_type_vals_ext
);
1353 proto_tree_add_item(tree
, hf_usb_vid_streaming_ifdesc_subtype
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
1358 case VS_INPUT_HEADER
:
1359 offset
= dissect_usb_video_streaming_input_header(tree
, tvb
, offset
);
1362 case VS_FORMAT_UNCOMPRESSED
:
1363 case VS_FORMAT_MJPEG
:
1364 case VS_FORMAT_FRAME_BASED
:
1365 offset
= dissect_usb_video_format(tree
, tvb
, offset
, subtype
);
1368 /* @todo MPEG2, H.264, VP8, Still Image Frame */
1369 /* @todo Obsolete UVC-1.0 descriptors? */
1371 case VS_FRAME_UNCOMPRESSED
:
1372 case VS_FRAME_MJPEG
:
1373 case VS_FRAME_FRAME_BASED
:
1374 offset
= dissect_usb_video_frame(tree
, tvb
, offset
, subtype
);
1377 case VS_COLORFORMAT
:
1378 offset
= dissect_usb_video_colorformat(tree
, tvb
, offset
);
1385 /* Soak up descriptor bytes beyond those we know how to dissect */
1386 if (offset
< descriptor_len
)
1387 proto_tree_add_item(tree
, hf_usb_vid_descriptor_data
, tvb
, offset
, descriptor_len
-offset
, ENC_NA
);
1389 return descriptor_len
;
1392 /*****************************************************************************/
1395 * Dissector for video class-specific endpoint descriptor.
1397 * @param parent_tree the protocol tree to be the parent of the descriptor subtree
1398 * @param tvb the tv_buff with the (remaining) packet data
1399 * On entry the gaze is set to the descriptor length field.
1400 * @param descriptor_len Length of the descriptor to dissect
1402 * @return offset within tvb at which dissection should continue
1405 dissect_usb_video_endpoint_descriptor(proto_tree
*parent_tree
, tvbuff_t
*tvb
,
1406 uint8_t descriptor_len
)
1408 proto_tree
*tree
= NULL
;
1412 subtype
= tvb_get_uint8(tvb
, offset
+2);
1416 const char* subtype_str
;
1418 subtype_str
= val_to_str(subtype
, vc_ep_descriptor_subtypes
, "Unknown (0x%x)");
1419 tree
= proto_tree_add_subtree_format(parent_tree
, tvb
, offset
, descriptor_len
,
1420 ett_descriptor_video_endpoint
, NULL
, "VIDEO CONTROL ENDPOINT DESCRIPTOR [%s]",
1424 dissect_usb_descriptor_header(tree
, tvb
, offset
, &vid_descriptor_type_vals_ext
);
1425 proto_tree_add_item(tree
, hf_usb_vid_epdesc_subtype
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
1428 if (subtype
== EP_INTERRUPT
)
1430 proto_tree_add_item(tree
, hf_usb_vid_epdesc_max_transfer_sz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1434 /* Soak up descriptor bytes beyond those we know how to dissect */
1435 if (offset
< descriptor_len
)
1436 proto_tree_add_item(tree
, hf_usb_vid_descriptor_data
, tvb
, offset
, descriptor_len
-offset
, ENC_NA
);
1438 return descriptor_len
;
1442 * Registered dissector for video class-specific descriptors
1444 * @param tvb the tv_buff with the (remaining) packet data
1445 * On entry the gaze is set to the descriptor length field.
1446 * @param pinfo the packet info of this packet (additional info)
1447 * @param tree the protocol tree to be built or NULL
1448 * @param data Not used
1450 * @return 0 no class specific dissector was found
1451 * @return <0 not enough data
1452 * @return >0 amount of data in the descriptor
1455 dissect_usb_vid_descriptor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1458 uint8_t descriptor_len
;
1459 uint8_t descriptor_type
;
1460 int bytes_available
;
1461 urb_info_t
*urb
= (urb_info_t
*)data
;
1465 descriptor_len
= tvb_get_uint8(tvb
, offset
);
1466 descriptor_type
= tvb_get_uint8(tvb
, offset
+1);
1468 bytes_available
= tvb_captured_length_remaining(tvb
, offset
);
1469 desc_tvb
= tvb_new_subset_length_caplen(tvb
, 0, bytes_available
, descriptor_len
);
1471 if (descriptor_type
== CS_ENDPOINT
)
1473 offset
= dissect_usb_video_endpoint_descriptor(tree
, desc_tvb
,
1476 else if (descriptor_type
== CS_INTERFACE
)
1478 if (urb
&& urb
->conv
&& urb
->conv
->interfaceSubclass
== SC_VIDEOCONTROL
)
1480 offset
= dissect_usb_video_control_interface_descriptor(tree
, desc_tvb
,
1484 else if (urb
&& urb
->conv
&& urb
->conv
->interfaceSubclass
== SC_VIDEOSTREAMING
)
1486 offset
= dissect_usb_video_streaming_interface_descriptor(tree
, desc_tvb
,
1490 /* else not something we recognize, just return offset = 0 */
1495 /*****************************************************************************/
1496 /* CONTROL TRANSFERS */
1497 /*****************************************************************************/
1500 * Dissect GET/SET transactions on the Video Probe and Commit controls.
1502 * @param parent_tree protocol tree to which the probe/commit subtree should be added
1503 * @param tvb the tv_buff with the (remaining) packet data
1504 * @param offset where in tvb to begin dissection.
1505 * On entry this refers to the probe/commit bmHint field.
1507 * @return offset within tvb at which dissection should continue
1510 dissect_usb_vid_probe(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
)
1514 static int * const hint_bits
[] = {
1515 &hf_usb_vid_probe_hint_D
[0],
1516 &hf_usb_vid_probe_hint_D
[1],
1517 &hf_usb_vid_probe_hint_D
[2],
1518 &hf_usb_vid_probe_hint_D
[3],
1519 &hf_usb_vid_probe_hint_D
[4],
1523 DISSECTOR_ASSERT(array_length(hint_bits
) == (1+array_length(hf_usb_vid_probe_hint_D
)));
1525 tree
= proto_tree_add_subtree(parent_tree
, tvb
, offset
, -1, ett_video_probe
, NULL
, "Probe/Commit Info");
1527 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_probe_hint
,
1528 ett_probe_hint
, hint_bits
, ENC_LITTLE_ENDIAN
);
1530 proto_tree_add_item(tree
, hf_usb_vid_format_index
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
1531 proto_tree_add_item(tree
, hf_usb_vid_frame_index
, tvb
, offset
+3, 1, ENC_LITTLE_ENDIAN
);
1532 proto_tree_add_item(tree
, hf_usb_vid_frame_interval
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
1533 proto_tree_add_item(tree
, hf_usb_vid_probe_key_frame_rate
, tvb
, offset
+8, 2, ENC_LITTLE_ENDIAN
);
1534 proto_tree_add_item(tree
, hf_usb_vid_probe_p_frame_rate
, tvb
, offset
+10, 2, ENC_LITTLE_ENDIAN
);
1535 proto_tree_add_item(tree
, hf_usb_vid_probe_comp_quality
, tvb
, offset
+12, 2, ENC_LITTLE_ENDIAN
);
1536 proto_tree_add_item(tree
, hf_usb_vid_probe_comp_window
, tvb
, offset
+14, 2, ENC_LITTLE_ENDIAN
);
1537 proto_tree_add_item(tree
, hf_usb_vid_probe_delay
, tvb
, offset
+16, 2, ENC_LITTLE_ENDIAN
);
1538 proto_tree_add_item(tree
, hf_usb_vid_probe_max_frame_sz
, tvb
, offset
+18, 4, ENC_LITTLE_ENDIAN
);
1539 proto_tree_add_item(tree
, hf_usb_vid_probe_max_payload_sz
, tvb
, offset
+22, 4, ENC_LITTLE_ENDIAN
);
1542 /* UVC 1.1 fields */
1543 if (tvb_reported_length_remaining(tvb
, offset
) > 0)
1545 static int * const framing_bits
[] = {
1546 &hf_usb_vid_probe_framing_D
[0],
1547 &hf_usb_vid_probe_framing_D
[1],
1551 DISSECTOR_ASSERT(array_length(framing_bits
) == (1+array_length(hf_usb_vid_probe_framing_D
)));
1553 proto_tree_add_item(tree
, hf_usb_vid_probe_clock_freq
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1556 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_probe_framing
,
1557 ett_probe_framing
, framing_bits
, ENC_NA
);
1560 proto_tree_add_item(tree
, hf_usb_vid_probe_preferred_ver
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1561 proto_tree_add_item(tree
, hf_usb_vid_probe_min_ver
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
1562 proto_tree_add_item(tree
, hf_usb_vid_probe_max_ver
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
1570 * Fetch the table that describes known control selectors for the specified unit/terminal.
1572 * @param entity_id Unit or terminal of interest
1573 * @param usb_conv_info Information about the interface the entity is part of
1575 * @return Table describing control selectors for the specified entity (may be NULL)
1577 static value_string_ext
*
1578 get_control_selector_values(uint8_t entity_id
, usb_conv_info_t
*usb_conv_info
)
1580 video_conv_info_t
*video_conv_info
;
1581 video_entity_t
*entity
= NULL
;
1582 value_string_ext
*selectors
= NULL
;
1584 if (usb_conv_info
== NULL
|| usb_conv_info
->class_data_type
!= USB_CONV_VIDEO
) {
1588 video_conv_info
= (video_conv_info_t
*)usb_conv_info
->class_data
;
1589 if (video_conv_info
)
1590 entity
= (video_entity_t
*) wmem_tree_lookup32(video_conv_info
->entities
, entity_id
);
1594 /* Interface Request*/
1595 switch (usb_conv_info
->interfaceSubclass
)
1597 case SC_VIDEOCONTROL
:
1598 selectors
= &cs_control_interface_ext
;
1601 case SC_VIDEOSTREAMING
:
1602 selectors
= &cs_streaming_interface_ext
;
1611 switch (entity
->subtype
)
1613 case VC_INPUT_TERMINAL
:
1614 if (entity
->terminalType
== ITT_CAMERA
)
1616 selectors
= &cs_camera_terminal_ext
;
1620 case VC_PROCESSING_UNIT
:
1621 selectors
= &cs_processing_unit_ext
;
1624 case VC_SELECTOR_UNIT
:
1625 selectors
= &cs_selector_unit_ext
;
1637 * Fetch the name of an entity's control.
1639 * @param entity_id Unit or terminal of interest
1640 * @param control_sel Control of interest
1641 * @param usb_conv_info Information about the interface the entity is part of
1643 * @return Table describing control selectors for the specified entity (may be NULL)
1646 get_control_selector_name(uint8_t entity_id
, uint8_t control_sel
, usb_conv_info_t
*usb_conv_info
)
1648 const char *control_name
= NULL
;
1649 value_string_ext
*selectors
= NULL
;
1651 selectors
= get_control_selector_values(entity_id
, usb_conv_info
);
1654 control_name
= try_val_to_str_ext(control_sel
, selectors
);
1656 return control_name
;
1659 /* Dissect the response to a GET INFO request */
1661 dissect_usb_vid_control_info(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
1663 static int * const capability_bits
[] = {
1664 &hf_usb_vid_control_info_D
[0],
1665 &hf_usb_vid_control_info_D
[1],
1666 &hf_usb_vid_control_info_D
[2],
1667 &hf_usb_vid_control_info_D
[3],
1668 &hf_usb_vid_control_info_D
[4],
1669 &hf_usb_vid_control_info_D
[5],
1670 &hf_usb_vid_control_info_D
[6],
1674 DISSECTOR_ASSERT(array_length(capability_bits
) == (1+array_length(hf_usb_vid_control_info_D
)));
1676 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_control_info
,
1677 ett_control_capabilities
, capability_bits
, ENC_NA
);
1682 /* Dissect all remaining bytes in the tvb as a specified type of UVC value.
1683 * These are displayed as an unsigned integer where possible, otherwise just as
1686 * @param tree the protocol tree to which an item will be added
1687 * @param tvb the tv_buff with the (remaining) packet data
1688 * @param offset How far into tvb the value data begins
1689 * @param request Identifies type of value - either bRequest from a CONTROL
1690 * transfer (i.e., USB_SETUP_GET_MAX), or bValue from an
1691 * INTERRUPT transfer (i.e., CONTROL_CHANGE_MAX).
1694 dissect_usb_vid_control_value(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, uint8_t request
)
1697 const char *fallback_name
;
1702 case USB_SETUP_GET_DEF
:
1703 hf
= hf_usb_vid_control_default
;
1704 fallback_name
= "Default Value";
1707 case USB_SETUP_GET_MIN
:
1708 case CONTROL_CHANGE_MIN
:
1709 hf
= hf_usb_vid_control_min
;
1710 fallback_name
= "Min Value";
1713 case USB_SETUP_GET_MAX
:
1714 case CONTROL_CHANGE_MAX
:
1715 hf
= hf_usb_vid_control_max
;
1716 fallback_name
= "Max Value";
1719 case USB_SETUP_GET_RES
:
1720 hf
= hf_usb_vid_control_res
;
1721 fallback_name
= "Resolution";
1724 case USB_SETUP_GET_CUR
:
1725 case USB_SETUP_SET_CUR
:
1726 case CONTROL_CHANGE_VALUE
:
1727 hf
= hf_usb_vid_control_cur
;
1728 fallback_name
= "Current Value";
1731 /* @todo UVC 1.5 USB_SETUP_x_ALL?
1732 * They are poorly specified.
1737 fallback_name
= "Value";
1741 value_size
= tvb_reported_length_remaining(tvb
, offset
);
1745 header_field_info
*hfinfo
;
1746 hfinfo
= proto_registrar_get_nth(hf
);
1747 DISSECTOR_ASSERT(FT_IS_INT(hfinfo
->type
) || FT_IS_UINT(hfinfo
->type
));
1750 if ((hf
!= -1) && (value_size
<= 4))
1752 proto_tree_add_item(tree
, hf
, tvb
, offset
, value_size
, ENC_LITTLE_ENDIAN
);
1756 /* @todo Display as FT_BYTES with a big-endian disclaimer?
1757 * See https://gitlab.com/wireshark/wireshark/-/issues/7933
1759 proto_tree_add_bytes_format(tree
, hf_usb_vid_control_value
, tvb
, offset
, value_size
, NULL
, "%s", fallback_name
);
1764 * Dissect video class GET/SET transactions.
1766 * @param pinfo Information associated with the packet being dissected
1767 * @param tree protocol tree to which fields should be added
1768 * @param tvb the tv_buff with the (remaining) packet data
1769 * @param offset where in tvb to begin dissection.
1770 * On entry this refers to the bRequest field of the SETUP
1772 * @param is_request true if the packet is host-to-device,
1773 * false if device-to-host
1774 * @param usb_trans_info Information specific to this request/response pair
1775 * @param urb Information about the conversation with the host
1778 dissect_usb_vid_get_set(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
,
1779 int offset
, bool is_request
,
1780 usb_trans_info_t
*usb_trans_info
,
1783 const char *short_name
= NULL
;
1784 uint8_t control_sel
;
1787 entity_id
= usb_trans_info
->setup
.wIndex
>> 8;
1788 control_sel
= usb_trans_info
->setup
.wValue
>> 8;
1790 /* Display something informative in the INFO column */
1791 col_append_str(pinfo
->cinfo
, COL_INFO
, " [");
1792 short_name
= get_control_selector_name(entity_id
, control_sel
, urb
->conv
);
1795 col_append_str(pinfo
->cinfo
, COL_INFO
, short_name
);
1798 short_name
= "Unknown";
1802 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Interface %u control 0x%x",
1803 urb
->conv
->interfaceNum
, control_sel
);
1807 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Unit %u control 0x%x",
1808 entity_id
, control_sel
);
1812 col_append_str(pinfo
->cinfo
, COL_INFO
, "]");
1813 col_set_fence(pinfo
->cinfo
, COL_INFO
);
1815 /* Add information on request context,
1816 * as GENERATED fields if not directly available (for filtering)
1820 /* Move gaze to control selector (MSB of wValue) */
1822 proto_tree_add_uint_format_value(tree
, hf_usb_vid_control_selector
, tvb
,
1823 offset
, 1, control_sel
, "%s (0x%02x)", short_name
, control_sel
);
1826 proto_tree_add_item(tree
, hf_usb_vid_control_interface
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1829 proto_tree_add_item(tree
, hf_usb_vid_control_entity
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1832 proto_tree_add_item(tree
, hf_usb_vid_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1839 ti
= proto_tree_add_uint(tree
, hf_usb_vid_control_interface
, tvb
, 0, 0,
1840 usb_trans_info
->setup
.wIndex
& 0xFF);
1841 proto_item_set_generated(ti
);
1843 ti
= proto_tree_add_uint(tree
, hf_usb_vid_control_entity
, tvb
, 0, 0, entity_id
);
1844 proto_item_set_generated(ti
);
1846 ti
= proto_tree_add_uint_format_value(tree
, hf_usb_vid_control_selector
, tvb
,
1847 0, 0, control_sel
, "%s (0x%02x)", short_name
, control_sel
);
1848 proto_item_set_generated(ti
);
1851 if (!is_request
|| (usb_trans_info
->setup
.request
== USB_SETUP_SET_CUR
))
1853 int value_size
= tvb_reported_length_remaining(tvb
, offset
);
1855 if (value_size
!= 0)
1857 if ((entity_id
== 0) && (urb
->conv
->interfaceSubclass
== SC_VIDEOSTREAMING
))
1859 if ((control_sel
== VS_PROBE_CONTROL
) || (control_sel
== VS_COMMIT_CONTROL
))
1861 int old_offset
= offset
;
1862 offset
= dissect_usb_vid_probe(tree
, tvb
, offset
);
1863 value_size
-= (offset
- old_offset
);
1868 if (usb_trans_info
->setup
.request
== USB_SETUP_GET_INFO
)
1870 dissect_usb_vid_control_info(tree
, tvb
, offset
);
1874 else if (usb_trans_info
->setup
.request
== USB_SETUP_GET_LEN
)
1876 proto_tree_add_item(tree
, hf_usb_vid_control_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1880 else if ( (usb_trans_info
->setup
.request
== USB_SETUP_GET_CUR
)
1882 && (urb
->conv
->interfaceSubclass
== SC_VIDEOCONTROL
)
1883 && (control_sel
== VC_REQUEST_ERROR_CODE_CONTROL
))
1885 proto_tree_add_item(tree
, hf_usb_vid_request_error
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1891 dissect_usb_vid_control_value(tree
, tvb
, offset
, usb_trans_info
->setup
.request
);
1892 offset
+= value_size
;
1899 proto_tree_add_item(tree
, hf_usb_vid_control_data
, tvb
, offset
, -1, ENC_NA
);
1900 offset
+= value_size
;
1908 /* Table for dispatch of video class SETUP transactions based on bRequest.
1909 * At the moment this is overkill since the same function handles all defined
1912 typedef int (*usb_setup_dissector
)(packet_info
*pinfo
, proto_tree
*tree
,
1913 tvbuff_t
*tvb
, int offset
,
1915 usb_trans_info_t
*usb_trans_info
,
1918 typedef struct _usb_setup_dissector_table_t
1921 usb_setup_dissector dissector
;
1922 } usb_setup_dissector_table_t
;
1924 static const usb_setup_dissector_table_t setup_dissectors
[] = {
1925 {USB_SETUP_SET_CUR
, dissect_usb_vid_get_set
},
1926 {USB_SETUP_SET_CUR_ALL
, dissect_usb_vid_get_set
},
1927 {USB_SETUP_GET_CUR
, dissect_usb_vid_get_set
},
1928 {USB_SETUP_GET_MIN
, dissect_usb_vid_get_set
},
1929 {USB_SETUP_GET_MAX
, dissect_usb_vid_get_set
},
1930 {USB_SETUP_GET_RES
, dissect_usb_vid_get_set
},
1931 {USB_SETUP_GET_LEN
, dissect_usb_vid_get_set
},
1932 {USB_SETUP_GET_INFO
, dissect_usb_vid_get_set
},
1933 {USB_SETUP_GET_DEF
, dissect_usb_vid_get_set
},
1934 {USB_SETUP_GET_CUR_ALL
, dissect_usb_vid_get_set
},
1935 {USB_SETUP_GET_MIN_ALL
, dissect_usb_vid_get_set
},
1936 {USB_SETUP_GET_MAX_ALL
, dissect_usb_vid_get_set
},
1937 {USB_SETUP_GET_RES_ALL
, dissect_usb_vid_get_set
},
1941 static const value_string setup_request_names_vals
[] = {
1942 {USB_SETUP_SET_CUR
, "SET CUR"},
1943 {USB_SETUP_SET_CUR_ALL
, "SET CUR ALL"},
1944 {USB_SETUP_GET_CUR
, "GET CUR"},
1945 {USB_SETUP_GET_MIN
, "GET MIN"},
1946 {USB_SETUP_GET_MAX
, "GET MAX"},
1947 {USB_SETUP_GET_RES
, "GET RES"},
1948 {USB_SETUP_GET_LEN
, "GET LEN"},
1949 {USB_SETUP_GET_INFO
, "GET INFO"},
1950 {USB_SETUP_GET_DEF
, "GET DEF"},
1951 {USB_SETUP_GET_CUR_ALL
, "GET CUR ALL"},
1952 {USB_SETUP_GET_MIN_ALL
, "GET MIN ALL"},
1953 {USB_SETUP_GET_MAX_ALL
, "GET MAX ALL"},
1954 {USB_SETUP_GET_RES_ALL
, "GET RES ALL"},
1955 {USB_SETUP_GET_DEF_ALL
, "GET DEF ALL"},
1959 /* Registered dissector for video class-specific control requests.
1960 * Dispatch to an appropriate dissector function.
1962 * @param tvb the tv_buff with the (remaining) packet data.
1963 * On entry, the gaze is set to SETUP bRequest field.
1964 * @param pinfo the packet info of this packet (additional info)
1965 * @param tree the protocol tree to be built or NULL
1966 * @param data Not used
1968 * @return 0 no class specific dissector was found
1969 * @return <0 not enough data
1970 * @return >0 amount of data in the descriptor
1973 dissect_usb_vid_control(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1975 bool is_request
= (pinfo
->srcport
== NO_ENDPOINT
);
1976 urb_info_t
*urb
= (urb_info_t
*)data
;
1977 usb_trans_info_t
*usb_trans_info
;
1979 usb_setup_dissector dissector
= NULL
;
1980 const usb_setup_dissector_table_t
*tmp
;
1982 /* Reject the packet if data or usb_trans_info are NULL */
1983 if (urb
== NULL
|| urb
->conv
== NULL
|| urb
->usb_trans_info
== NULL
)
1985 usb_trans_info
= urb
->usb_trans_info
;
1987 /* See if we can find a class specific dissector for this request */
1988 for (tmp
=setup_dissectors
; tmp
->dissector
; tmp
++)
1990 if (tmp
->request
== usb_trans_info
->setup
.request
)
1992 dissector
= tmp
->dissector
;
1996 /* No we could not find any class specific dissector for this request
1997 * return false and let USB try any of the standard requests.
2002 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "USBVIDEO");
2003 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s %s",
2004 val_to_str(usb_trans_info
->setup
.request
, setup_request_names_vals
, "Unknown type %x"),
2005 is_request
?"Request ":"Response");
2009 proto_tree_add_item(tree
, hf_usb_vid_request
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2013 offset
= dissector(pinfo
, tree
, tvb
, offset
, is_request
, usb_trans_info
, urb
);
2017 /* Registered dissector for video class-specific URB_INTERRUPT
2019 * @param tvb the tv_buff with the (remaining) packet data
2020 * @param pinfo the packet info of this packet (additional info)
2021 * @param tree the protocol tree to be built or NULL
2022 * @param data Unused API parameter
2024 * @return 0 no class specific dissector was found
2025 * @return <0 not enough data
2026 * @return >0 amount of data in the descriptor
2029 dissect_usb_vid_interrupt(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
2032 int bytes_available
;
2035 urb
= (urb_info_t
*)data
;
2036 bytes_available
= tvb_reported_length_remaining(tvb
, offset
);
2038 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "USBVIDEO");
2040 if (bytes_available
> 0)
2042 uint8_t originating_interface
;
2043 uint8_t originating_entity
;
2045 originating_interface
= tvb_get_uint8(tvb
, offset
) & INT_ORIGINATOR_MASK
;
2046 proto_tree_add_item(tree
, hf_usb_vid_interrupt_bStatusType
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2049 originating_entity
= tvb_get_uint8(tvb
, offset
);
2050 proto_tree_add_item(tree
, hf_usb_vid_interrupt_bOriginator
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2053 if (originating_interface
== INT_VIDEOCONTROL
)
2055 uint8_t control_sel
;
2057 const char *control_name
;
2059 proto_tree_add_item(tree
, hf_usb_vid_control_interrupt_bEvent
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2062 control_sel
= tvb_get_uint8(tvb
, offset
);
2063 control_name
= get_control_selector_name(originating_entity
, control_sel
, urb
->conv
);
2065 control_name
= "Unknown";
2067 proto_tree_add_uint_format_value(tree
, hf_usb_vid_control_selector
, tvb
,
2068 offset
, 1, control_sel
, "%s (0x%02x)",
2069 control_name
, control_sel
);
2072 attribute
= tvb_get_uint8(tvb
, offset
);
2073 proto_tree_add_item(tree
, hf_usb_vid_interrupt_bAttribute
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2078 case CONTROL_CHANGE_FAILURE
:
2079 proto_tree_add_item(tree
, hf_usb_vid_request_error
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2083 case CONTROL_CHANGE_INFO
:
2084 offset
= dissect_usb_vid_control_info(tree
, tvb
, offset
);
2087 case CONTROL_CHANGE_VALUE
:
2088 case CONTROL_CHANGE_MIN
:
2089 case CONTROL_CHANGE_MAX
:
2090 dissect_usb_vid_control_value(tree
, tvb
, offset
, attribute
);
2091 offset
+= tvb_reported_length_remaining(tvb
, offset
);
2095 proto_tree_add_item(tree
, hf_usb_vid_value_data
, tvb
, offset
, -1, ENC_NA
);
2096 offset
+= tvb_reported_length_remaining(tvb
, offset
);
2100 else if (originating_interface
== INT_VIDEOSTREAMING
)
2112 proto_register_usb_vid(void)
2114 static hf_register_info hf
[] = {
2116 { &hf_usb_vid_request
,
2117 { "bRequest", "usbvideo.setup.bRequest", FT_UINT8
, BASE_HEX
, VALS(setup_request_names_vals
), 0x0,
2121 { &hf_usb_vid_length
,
2122 { "wLength", "usbvideo.setup.wLength", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2126 /***** Request Error Control *****/
2127 { &hf_usb_vid_request_error
,
2128 { "bRequestErrorCode", "usbvideo.reqerror.code",
2129 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
2130 &request_error_codes_ext
, 0,
2131 "Request Error Code", HFILL
}
2134 /***** Unit/Terminal Controls *****/
2135 { &hf_usb_vid_control_selector
,
2136 { "Control Selector", "usbvideo.control.selector", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2137 "ID of the control within its entity", HFILL
}
2140 { &hf_usb_vid_control_entity
,
2141 { "Entity", "usbvideo.control.entity", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2142 "Unit or terminal to which the control belongs", HFILL
}
2145 { &hf_usb_vid_control_interface
,
2146 { "Interface", "usbvideo.control.interface", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2147 "Interface to which the control belongs", HFILL
}
2150 { &hf_usb_vid_control_info
,
2151 { "Info (Capabilities/State)", "usbvideo.control.info",
2152 FT_UINT8
, BASE_HEX
, NULL
, 0,
2153 "Control capabilities and current state", HFILL
}
2156 { &hf_usb_vid_control_info_D
[0],
2157 { "Supports GET", "usbvideo.control.info.D0",
2158 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<0),
2162 { &hf_usb_vid_control_info_D
[1],
2163 { "Supports SET", "usbvideo.control.info.D1",
2164 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<1),
2168 { &hf_usb_vid_control_info_D
[2],
2169 { "Disabled due to automatic mode", "usbvideo.control.info.D2",
2170 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<2),
2174 { &hf_usb_vid_control_info_D
[3],
2175 { "Autoupdate", "usbvideo.control.info.D3",
2176 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<3),
2180 { &hf_usb_vid_control_info_D
[4],
2181 { "Asynchronous", "usbvideo.control.info.D4",
2182 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<4),
2186 { &hf_usb_vid_control_info_D
[5],
2187 { "Disabled due to incompatibility with Commit state", "usbvideo.control.info.D5",
2188 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<5),
2192 { &hf_usb_vid_control_info_D
[6],
2193 { "Reserved", "usbvideo.control.info.D6",
2194 FT_UINT8
, BASE_HEX
, NULL
, (3<<6),
2198 { &hf_usb_vid_control_length
,
2199 { "Control Length", "usbvideo.control.len",
2200 FT_UINT16
, BASE_DEC
, NULL
, 0,
2201 "Control size in bytes", HFILL
}
2204 { &hf_usb_vid_control_default
,
2205 { "Default value", "usbvideo.control.value.default",
2206 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0,
2210 { &hf_usb_vid_control_min
,
2211 { "Minimum value", "usbvideo.control.value.min",
2212 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0,
2216 { &hf_usb_vid_control_max
,
2217 { "Maximum value", "usbvideo.control.value.max",
2218 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0,
2222 { &hf_usb_vid_control_res
,
2223 { "Resolution", "usbvideo.control.value.res",
2224 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0,
2228 { &hf_usb_vid_control_cur
,
2229 { "Current value", "usbvideo.control.value.cur",
2230 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0,
2234 /***** Terminal Descriptors *****/
2236 /* @todo Decide whether to unify .name fields */
2237 { &hf_usb_vid_control_ifdesc_iTerminal
,
2238 { "iTerminal", "usbvideo.terminal.name", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2239 "String Descriptor describing this terminal", HFILL
}
2242 /* @todo Decide whether to unify .terminal.id and .unit.id under .entityID */
2243 { &hf_usb_vid_control_ifdesc_terminal_id
,
2244 { "bTerminalID", "usbvideo.terminal.id", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2248 { &hf_usb_vid_control_ifdesc_terminal_type
,
2249 { "wTerminalType", "usbvideo.terminal.type",
2250 FT_UINT16
, BASE_HEX
| BASE_EXT_STRING
, &vc_terminal_types_ext
, 0,
2254 { &hf_usb_vid_control_ifdesc_assoc_terminal
,
2255 { "bAssocTerminal", "usbvideo.terminal.assocTerminal", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2256 "Associated Terminal", HFILL
}
2259 /***** Camera Terminal Descriptor *****/
2261 { &hf_usb_vid_cam_objective_focal_len_min
,
2262 { "wObjectiveFocalLengthMin", "usbvideo.camera.objectiveFocalLengthMin",
2263 FT_UINT16
, BASE_DEC
, NULL
, 0,
2264 "Minimum Focal Length for Optical Zoom", HFILL
}
2267 { &hf_usb_vid_cam_objective_focal_len_max
,
2268 { "wObjectiveFocalLengthMax", "usbvideo.camera.objectiveFocalLengthMax",
2269 FT_UINT16
, BASE_DEC
, NULL
, 0,
2270 "Minimum Focal Length for Optical Zoom", HFILL
}
2273 { &hf_usb_vid_cam_ocular_focal_len
,
2274 { "wOcularFocalLength", "usbvideo.camera.ocularFocalLength",
2275 FT_UINT16
, BASE_DEC
, NULL
, 0,
2276 "Ocular Focal Length for Optical Zoom", HFILL
}
2279 { &hf_usb_vid_cam_control_D
[0],
2280 { "Scanning Mode", "usbvideo.camera.control.D0",
2282 array_length(hf_usb_vid_cam_control_D
),
2283 TFS(&tfs_yes_no
), (1<<0),
2287 { &hf_usb_vid_cam_control_D
[1],
2288 { "Auto Exposure Mode", "usbvideo.camera.control.D1",
2290 array_length(hf_usb_vid_cam_control_D
),
2291 TFS(&tfs_yes_no
), (1<<1),
2295 { &hf_usb_vid_cam_control_D
[2],
2296 { "Auto Exposure Priority", "usbvideo.camera.control.D2",
2298 array_length(hf_usb_vid_cam_control_D
),
2299 TFS(&tfs_yes_no
), (1<<2),
2303 { &hf_usb_vid_cam_control_D
[3],
2304 { "Exposure Time (Absolute)", "usbvideo.camera.control.D3",
2306 array_length(hf_usb_vid_cam_control_D
),
2307 TFS(&tfs_yes_no
), (1<<3),
2311 { &hf_usb_vid_cam_control_D
[4],
2312 { "Exposure Time (Relative)", "usbvideo.camera.control.D4",
2314 array_length(hf_usb_vid_cam_control_D
),
2315 TFS(&tfs_yes_no
), (1<<4),
2319 { &hf_usb_vid_cam_control_D
[5],
2320 { "Focus (Absolute)", "usbvideo.camera.control.D5",
2322 array_length(hf_usb_vid_cam_control_D
),
2323 TFS(&tfs_yes_no
), (1<<5),
2327 { &hf_usb_vid_cam_control_D
[6],
2328 { "Focus (Relative)", "usbvideo.camera.control.D6",
2330 array_length(hf_usb_vid_cam_control_D
),
2331 TFS(&tfs_yes_no
), (1<<6),
2335 { &hf_usb_vid_cam_control_D
[7],
2336 { "Iris (Absolute)", "usbvideo.camera.control.D7",
2338 array_length(hf_usb_vid_cam_control_D
),
2339 TFS(&tfs_yes_no
), (1<<7),
2343 { &hf_usb_vid_cam_control_D
[8],
2344 { "Iris (Relative)", "usbvideo.camera.control.D8",
2346 array_length(hf_usb_vid_cam_control_D
),
2347 TFS(&tfs_yes_no
), (1<<8),
2351 { &hf_usb_vid_cam_control_D
[9],
2352 { "Zoom (Absolute)", "usbvideo.camera.control.D9",
2354 array_length(hf_usb_vid_cam_control_D
),
2355 TFS(&tfs_yes_no
), (1<<9),
2359 { &hf_usb_vid_cam_control_D
[10],
2360 { "Zoom (Relative)", "usbvideo.camera.control.D10",
2362 array_length(hf_usb_vid_cam_control_D
),
2363 TFS(&tfs_yes_no
), (1<<10),
2367 { &hf_usb_vid_cam_control_D
[11],
2368 { "PanTilt (Absolute)", "usbvideo.camera.control.D11",
2370 array_length(hf_usb_vid_cam_control_D
),
2371 TFS(&tfs_yes_no
), (1<<11),
2375 { &hf_usb_vid_cam_control_D
[12],
2376 { "PanTilt (Relative)", "usbvideo.camera.control.D12",
2378 array_length(hf_usb_vid_cam_control_D
),
2379 TFS(&tfs_yes_no
), (1<<12),
2383 { &hf_usb_vid_cam_control_D
[13],
2384 { "Roll (Absolute)", "usbvideo.camera.control.D13",
2386 array_length(hf_usb_vid_cam_control_D
),
2387 TFS(&tfs_yes_no
), (1<<13),
2391 { &hf_usb_vid_cam_control_D
[14],
2392 { "Roll (Relative)", "usbvideo.camera.control.D14",
2394 array_length(hf_usb_vid_cam_control_D
),
2395 TFS(&tfs_yes_no
), (1<<14),
2399 { &hf_usb_vid_cam_control_D
[15],
2400 { "D15", "usbvideo.camera.control.D15",
2402 array_length(hf_usb_vid_cam_control_D
),
2403 TFS(&tfs_yes_no
), (1<<15),
2407 { &hf_usb_vid_cam_control_D
[16],
2408 { "D16", "usbvideo.camera.control.D16",
2410 array_length(hf_usb_vid_cam_control_D
),
2411 TFS(&tfs_yes_no
), (1<<16),
2415 { &hf_usb_vid_cam_control_D
[17],
2416 { "Auto Focus", "usbvideo.camera.control.D17",
2418 array_length(hf_usb_vid_cam_control_D
),
2419 TFS(&tfs_yes_no
), (1<<17),
2423 { &hf_usb_vid_cam_control_D
[18],
2424 { "Privacy", "usbvideo.camera.control.D18",
2426 array_length(hf_usb_vid_cam_control_D
),
2427 TFS(&tfs_yes_no
), (1<<18),
2431 { &hf_usb_vid_cam_control_D
[19],
2432 { "Focus (Simple)", "usbvideo.camera.control.D19",
2434 array_length(hf_usb_vid_cam_control_D
),
2435 TFS(&tfs_yes_no
), (1<<19),
2439 { &hf_usb_vid_cam_control_D
[20],
2440 { "Window", "usbvideo.camera.control.D20",
2442 array_length(hf_usb_vid_cam_control_D
),
2443 TFS(&tfs_yes_no
), (1<<20),
2447 { &hf_usb_vid_cam_control_D
[21],
2448 { "Region of Interest", "usbvideo.camera.control.D21",
2450 array_length(hf_usb_vid_cam_control_D
),
2451 TFS(&tfs_yes_no
), (1<<21),
2455 /***** Unit Descriptors *****/
2457 { &hf_usb_vid_control_ifdesc_unit_id
,
2458 { "bUnitID", "usbvideo.unit.id", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2462 { &hf_usb_vid_num_inputs
,
2463 { "bNrInPins", "usbvideo.unit.numInputs",
2464 FT_UINT8
, BASE_DEC
, NULL
, 0,
2465 "Number of input pins", HFILL
}
2468 { &hf_usb_vid_sources
,
2469 { "baSourceID", "usbvideo.unit.sources",
2470 FT_BYTES
, BASE_NONE
, NULL
, 0,
2471 "Input entity IDs", HFILL
}
2475 /***** Processing Unit Descriptor *****/
2477 { &hf_usb_vid_iProcessing
,
2478 { "iProcessing", "usbvideo.processor.name", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2479 "String Descriptor describing this terminal", HFILL
}
2482 { &hf_usb_vid_proc_control_D
[0],
2483 { "Brightness", "usbvideo.processor.control.D0",
2484 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<0),
2488 { &hf_usb_vid_proc_control_D
[1],
2489 { "Contrast", "usbvideo.processor.control.D1",
2490 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<1),
2494 { &hf_usb_vid_proc_control_D
[2],
2495 { "Hue", "usbvideo.processor.control.D2",
2496 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<2),
2500 { &hf_usb_vid_proc_control_D
[3],
2501 { "Saturation", "usbvideo.processor.control.D3",
2502 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<3),
2506 { &hf_usb_vid_proc_control_D
[4],
2507 { "Sharpness", "usbvideo.processor.control.D4",
2508 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<4),
2512 { &hf_usb_vid_proc_control_D
[5],
2513 { "Gamma", "usbvideo.processor.control.D5",
2514 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<5),
2518 { &hf_usb_vid_proc_control_D
[6],
2519 { "White Balance Temperature", "usbvideo.processor.control.D6",
2520 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<6),
2524 { &hf_usb_vid_proc_control_D
[7],
2525 { "White Balance Component", "usbvideo.processor.control.D7",
2526 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<7),
2530 { &hf_usb_vid_proc_control_D
[8],
2531 { "Backlight Compensation", "usbvideo.processor.control.D8",
2532 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<8),
2536 { &hf_usb_vid_proc_control_D
[9],
2537 { "Gain", "usbvideo.processor.control.D9",
2538 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<9),
2542 { &hf_usb_vid_proc_control_D
[10],
2543 { "Power Line Frequency", "usbvideo.processor.control.D10",
2544 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<10),
2548 { &hf_usb_vid_proc_control_D
[11],
2549 { "Hue, Auto", "usbvideo.processor.control.D11",
2550 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<11),
2554 { &hf_usb_vid_proc_control_D
[12],
2555 { "White Balance Temperature, Auto", "usbvideo.processor.control.D12",
2556 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<12),
2560 { &hf_usb_vid_proc_control_D
[13],
2561 { "White Balance Component, Auto", "usbvideo.processor.control.D13",
2562 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<13),
2566 { &hf_usb_vid_proc_control_D
[14],
2567 { "Digital Multiplier", "usbvideo.processor.control.D14",
2568 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<14),
2572 { &hf_usb_vid_proc_control_D
[15],
2573 { "Digital Multiplier Limit", "usbvideo.processor.control.D15",
2574 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<15),
2578 { &hf_usb_vid_proc_control_D
[16],
2579 { "Analog Video Standard", "usbvideo.processor.control.D16",
2580 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<16),
2584 { &hf_usb_vid_proc_control_D
[17],
2585 { "Analog Video Lock Status", "usbvideo.processor.control.D17",
2586 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<17),
2590 { &hf_usb_vid_proc_control_D
[18],
2591 { "Contrast, Auto", "usbvideo.processor.control.D18",
2592 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<18),
2596 { &hf_usb_vid_proc_standards
,
2597 { "bmVideoStandards", "usbvideo.processor.standards",
2598 FT_UINT8
, BASE_HEX
, NULL
, 0,
2599 "Supported analog video standards", HFILL
}
2602 { &hf_usb_vid_proc_standards_D
[0],
2603 { "None", "usbvideo.processor.standards.D0",
2604 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<0),
2608 { &hf_usb_vid_proc_standards_D
[1],
2609 { "NTSC - 525/60", "usbvideo.processor.standards.D1",
2610 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<1),
2614 { &hf_usb_vid_proc_standards_D
[2],
2615 { "PAL - 625/50", "usbvideo.processor.standards.D2",
2616 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<2),
2620 { &hf_usb_vid_proc_standards_D
[3],
2621 { "SECAM - 625/50", "usbvideo.processor.standards.D3",
2622 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<3),
2626 { &hf_usb_vid_proc_standards_D
[4],
2627 { "NTSC - 625/50", "usbvideo.processor.standards.D4",
2628 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<4),
2632 { &hf_usb_vid_proc_standards_D
[5],
2633 { "PAL - 525/60", "usbvideo.processor.standards.D5",
2634 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<5),
2638 { &hf_usb_vid_max_multiplier
,
2639 { "wMaxMultiplier", "usbvideo.processor.maxMultiplier",
2640 FT_UINT16
, BASE_DEC
, NULL
, 0,
2641 "100 x max digital multiplication", HFILL
}
2644 /***** Selector Unit Descriptor *****/
2646 { &hf_usb_vid_iSelector
,
2647 { "iSelector", "usbvideo.selector.name", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2648 "String Descriptor describing this terminal", HFILL
}
2651 /***** Extension Unit Descriptor *****/
2653 { &hf_usb_vid_iExtension
,
2654 { "iExtension", "usbvideo.extension.name", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2655 "String Descriptor describing this terminal", HFILL
}
2658 { &hf_usb_vid_exten_guid
,
2659 { "guid", "usbvideo.extension.guid",
2660 FT_GUID
, BASE_NONE
, NULL
, 0,
2661 "Identifier", HFILL
}
2664 { &hf_usb_vid_exten_num_controls
,
2665 { "bNumControls", "usbvideo.extension.numControls",
2666 FT_UINT8
, BASE_DEC
, NULL
, 0,
2667 "Number of controls", HFILL
}
2670 /***** Probe/Commit *****/
2672 { &hf_usb_vid_probe_hint
,
2673 { "bmHint", "usbvideo.probe.hint",
2674 FT_UINT16
, BASE_HEX
, NULL
, 0,
2675 "Fields to hold constant during negotiation", HFILL
}
2678 { &hf_usb_vid_probe_hint_D
[0],
2679 { "dwFrameInterval", "usbvideo.probe.hint.D0",
2680 FT_BOOLEAN
, 5, TFS(&probe_hint_meaning
), (1<<0),
2681 "Frame Rate", HFILL
}
2683 { &hf_usb_vid_probe_hint_D
[1],
2684 { "wKeyFrameRate", "usbvideo.probe.hint.D1",
2685 FT_BOOLEAN
, 5, TFS(&probe_hint_meaning
), (1<<1),
2686 "Key Frame Rate", HFILL
}
2688 { &hf_usb_vid_probe_hint_D
[2],
2689 { "wPFrameRate", "usbvideo.probe.hint.D2",
2690 FT_BOOLEAN
, 5, TFS(&probe_hint_meaning
), (1<<2),
2691 "P-Frame Rate", HFILL
}
2693 { &hf_usb_vid_probe_hint_D
[3],
2694 { "wCompQuality", "usbvideo.probe.hint.D3",
2695 FT_BOOLEAN
, 5, TFS(&probe_hint_meaning
), (1<<3),
2696 "Compression Quality", HFILL
}
2698 { &hf_usb_vid_probe_hint_D
[4],
2699 { "wCompWindowSize", "usbvideo.probe.hint.D4",
2700 FT_BOOLEAN
, 5, TFS(&probe_hint_meaning
), (1<<4),
2701 "Compression Window Size", HFILL
}
2704 { &hf_usb_vid_probe_key_frame_rate
,
2705 { "wKeyFrameRate", "usbvideo.probe.keyFrameRate",
2706 FT_UINT16
, BASE_DEC
, NULL
, 0,
2707 "Key frame rate", HFILL
}
2710 { &hf_usb_vid_probe_p_frame_rate
,
2711 { "wPFrameRate", "usbvideo.probe.pFrameRate",
2712 FT_UINT16
, BASE_DEC
, NULL
, 0,
2713 "P frame rate", HFILL
}
2716 { &hf_usb_vid_probe_comp_quality
,
2717 { "wCompQuality", "usbvideo.probe.compQuality",
2718 FT_UINT16
, BASE_DEC
, NULL
, 0,
2719 "Compression quality [0-10000]", HFILL
}
2722 { &hf_usb_vid_probe_comp_window
,
2723 { "wCompWindow", "usbvideo.probe.compWindow",
2724 FT_UINT16
, BASE_DEC
, NULL
, 0,
2725 "Window size for average bit rate control", HFILL
}
2727 { &hf_usb_vid_probe_delay
,
2728 { "wDelay", "usbvideo.probe.delay",
2729 FT_UINT16
, BASE_DEC
, NULL
, 0,
2730 "Latency in ms from capture to USB", HFILL
}
2732 { &hf_usb_vid_probe_max_frame_sz
,
2733 { "dwMaxVideoFrameSize", "usbvideo.probe.maxVideoFrameSize",
2734 FT_UINT32
, BASE_DEC
, NULL
, 0,
2737 { &hf_usb_vid_probe_max_payload_sz
,
2738 { "dwMaxPayloadTransferSize", "usbvideo.probe.maxPayloadTransferSize",
2739 FT_UINT32
, BASE_DEC
, NULL
, 0,
2742 { &hf_usb_vid_probe_clock_freq
,
2743 { "dwClockFrequency", "usbvideo.probe.clockFrequency",
2744 FT_UINT32
, BASE_DEC
, NULL
, 0,
2745 "Device clock frequency in Hz", HFILL
}
2748 { &hf_usb_vid_probe_framing
,
2749 { "bmFramingInfo", "usbvideo.probe.framing",
2750 FT_UINT8
, BASE_HEX
, NULL
, 0,
2754 { &hf_usb_vid_probe_framing_D
[0],
2755 { "Frame ID required", "usbvideo.probe.framing.D0",
2756 FT_BOOLEAN
, 2, TFS(&tfs_yes_no
), (1<<0),
2759 { &hf_usb_vid_probe_framing_D
[1],
2760 { "EOF utilized", "usbvideo.probe.framing.D1",
2761 FT_BOOLEAN
, 2, TFS(&tfs_yes_no
), (1<<1),
2765 { &hf_usb_vid_probe_preferred_ver
,
2766 { "bPreferredVersion", "usbvideo.probe.preferredVersion",
2767 FT_UINT8
, BASE_DEC
, NULL
, 0,
2768 "Preferred payload format version", HFILL
}
2770 { &hf_usb_vid_probe_min_ver
,
2771 { "bMinVersion", "usbvideo.probe.minVersion",
2772 FT_UINT8
, BASE_DEC
, NULL
, 0,
2773 "Min supported payload format version", HFILL
}
2775 { &hf_usb_vid_probe_max_ver
,
2776 { "bMaxVersion", "usbvideo.probe.maxVer",
2777 FT_UINT8
, BASE_DEC
, NULL
, 0,
2778 "Max supported payload format version", HFILL
}
2781 { &hf_usb_vid_control_ifdesc_dwClockFrequency
,
2782 { "dwClockFrequency", "usbvideo.probe.clockFrequency",
2783 FT_UINT32
, BASE_DEC
, NULL
, 0,
2784 "Device clock frequency (Hz) for selected format", HFILL
}
2787 /***** Format Descriptors *****/
2789 { &hf_usb_vid_format_index
,
2790 { "bFormatIndex", "usbvideo.format.index",
2791 FT_UINT8
, BASE_DEC
, NULL
, 0,
2792 "Index of this format descriptor", HFILL
}
2795 { &hf_usb_vid_format_num_frame_descriptors
,
2796 { "bNumFrameDescriptors", "usbvideo.format.numFrameDescriptors",
2797 FT_UINT8
, BASE_DEC
, NULL
, 0,
2798 "Number of frame descriptors for this format", HFILL
}
2801 { &hf_usb_vid_format_guid
,
2802 { "guidFormat", "usbvideo.format.guid",
2803 FT_GUID
, BASE_NONE
, NULL
, 0,
2804 "Stream encoding format", HFILL
}
2807 { &hf_usb_vid_format_bits_per_pixel
,
2808 { "bBitsPerPixel", "usbvideo.format.bitsPerPixel",
2809 FT_UINT8
, BASE_DEC
, NULL
, 0,
2810 "Bits per pixel", HFILL
}
2813 { &hf_usb_vid_default_frame_index
,
2814 { "bDefaultFrameIndex", "usbvideo.format.defaultFrameIndex",
2815 FT_UINT8
, BASE_DEC
, NULL
, 0,
2816 "Optimum frame index for this stream", HFILL
}
2819 { &hf_usb_vid_aspect_ratio_x
,
2820 { "bAspectRatioX", "usbvideo.format.aspectRatioX",
2821 FT_UINT8
, BASE_DEC
, NULL
, 0,
2822 "X dimension of picture aspect ratio", HFILL
}
2825 { &hf_usb_vid_aspect_ratio_y
,
2826 { "bAspectRatioY", "usbvideo.format.aspectRatioY",
2827 FT_UINT8
, BASE_DEC
, NULL
, 0,
2828 "Y dimension of picture aspect ratio", HFILL
}
2831 { &hf_usb_vid_interlace_flags
,
2832 { "bmInterlaceFlags", "usbvideo.format.interlace",
2833 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2837 { &hf_usb_vid_is_interlaced
,
2838 { "Interlaced stream", "usbvideo.format.interlace.D0",
2839 FT_BOOLEAN
, 8, TFS(&is_interlaced_meaning
), (1<<0),
2843 { &hf_usb_vid_interlaced_fields
,
2844 { "Fields per frame", "usbvideo.format.interlace.D1",
2845 FT_BOOLEAN
, 8, TFS(&interlaced_fields_meaning
), (1<<1),
2849 { &hf_usb_vid_field_1_first
,
2850 { "Field 1 first", "usbvideo.format.interlace.D2",
2851 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<2),
2855 { &hf_usb_vid_field_pattern
,
2856 { "Field pattern", "usbvideo.format.interlace.pattern",
2857 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
2858 &field_pattern_meaning_ext
, (3<<4),
2862 { &hf_usb_vid_copy_protect
,
2863 { "bCopyProtect", "usbvideo.format.copyProtect",
2864 FT_UINT8
, BASE_DEC
, VALS(copy_protect_meaning
), 0,
2868 { &hf_usb_vid_variable_size
,
2869 { "Variable size", "usbvideo.format.variableSize",
2870 FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
2874 /***** MJPEG Format Descriptor *****/
2876 { &hf_usb_vid_mjpeg_flags
,
2877 { "bmFlags", "usbvideo.mjpeg.flags",
2878 FT_UINT8
, BASE_HEX
, NULL
, 0,
2879 "Characteristics", HFILL
}
2882 { &hf_usb_vid_mjpeg_fixed_samples
,
2883 { "Fixed size samples", "usbvideo.mjpeg.fixed_size",
2884 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<0),
2888 /***** Frame Descriptors *****/
2890 { &hf_usb_vid_frame_index
,
2891 { "bFrameIndex", "usbvideo.frame.index",
2892 FT_UINT8
, BASE_DEC
, NULL
, 0,
2893 "Index of this frame descriptor", HFILL
}
2896 { &hf_usb_vid_frame_capabilities
,
2897 { "bmCapabilities", "usbvideo.frame.capabilities",
2898 FT_UINT8
, BASE_HEX
, NULL
, 0,
2899 "Capabilities", HFILL
}
2902 { &hf_usb_vid_frame_stills_supported
,
2903 { "Still image", "usbvideo.frame.stills",
2904 FT_BOOLEAN
, 8, TFS(&tfs_supported_not_supported
), (1<<0),
2908 { &hf_usb_vid_frame_interval
,
2909 { "dwFrameInterval", "usbvideo.frame.interval",
2910 FT_UINT32
, BASE_DEC
, NULL
, 0,
2911 "Frame interval multiple of 100 ns", HFILL
}
2914 { &hf_usb_vid_frame_fixed_frame_rate
,
2915 { "Fixed frame rate", "usbvideo.frame.fixedRate",
2916 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<1),
2919 { &hf_usb_vid_frame_width
,
2920 { "wWidth", "usbvideo.frame.width",
2921 FT_UINT16
, BASE_DEC
, NULL
, 0,
2922 "Width of frame in pixels", HFILL
}
2924 { &hf_usb_vid_frame_height
,
2925 { "wHeight", "usbvideo.frame.height",
2926 FT_UINT16
, BASE_DEC
, NULL
, 0,
2927 "Height of frame in pixels", HFILL
}
2929 { &hf_usb_vid_frame_min_bit_rate
,
2930 { "dwMinBitRate", "usbvideo.frame.minBitRate",
2931 FT_UINT32
, BASE_DEC
, NULL
, 0,
2932 "Minimum bit rate in bps", HFILL
}
2934 { &hf_usb_vid_frame_max_bit_rate
,
2935 { "dwMaxBitRate", "usbvideo.frame.maxBitRate",
2936 FT_UINT32
, BASE_DEC
, NULL
, 0,
2937 "Maximum bit rate in bps", HFILL
}
2940 { &hf_usb_vid_frame_max_frame_sz
,
2941 { "dwMaxVideoFrameBufferSize", "usbvideo.frame.maxBuffer",
2942 FT_UINT32
, BASE_DEC
, NULL
, 0,
2943 "Maximum bytes per frame", HFILL
}
2945 { &hf_usb_vid_frame_default_interval
,
2946 { "dwDefaultFrameInterval", "usbvideo.frame.interval.default",
2947 FT_UINT32
, BASE_DEC
, NULL
, 0,
2948 "Suggested default", HFILL
}
2951 { &hf_usb_vid_frame_interval_type
,
2952 { "bFrameIntervalType", "usbvideo.frame.interval.type",
2953 FT_UINT8
, BASE_DEC
, NULL
, 0,
2954 "Frame rate control (continuous/discrete)", HFILL
}
2957 { &hf_usb_vid_frame_min_interval
,
2958 { "dwMinFrameInterval", "usbvideo.frame.interval.min",
2959 FT_UINT32
, BASE_DEC
, NULL
, 0,
2960 "Shortest frame interval (* 100 ns)", HFILL
}
2963 { &hf_usb_vid_frame_max_interval
,
2964 { "dwMaxFrameInterval", "usbvideo.frame.interval.max",
2965 FT_UINT32
, BASE_DEC
, NULL
, 0,
2966 "Longest frame interval (* 100 ns)", HFILL
}
2968 { &hf_usb_vid_frame_step_interval
,
2969 { "dwMinFrameInterval", "usbvideo.frame.interval.step",
2970 FT_UINT32
, BASE_DEC
, NULL
, 0,
2971 "Granularity of frame interval (* 100 ns)", HFILL
}
2974 { &hf_usb_vid_frame_bytes_per_line
,
2975 { "dwBytesPerLine", "usbvideo.frame.bytesPerLine",
2976 FT_UINT32
, BASE_DEC
, NULL
, 0,
2977 "Fixed number of bytes per video line", HFILL
}
2980 /***** Colorformat Descriptor *****/
2982 { &hf_usb_vid_color_primaries
,
2983 { "bColorPrimaries", "usbvideo.color.primaries",
2984 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
2985 &color_primaries_meaning_ext
, 0,
2989 { &hf_usb_vid_transfer_characteristics
,
2990 { "bTransferCharacteristics", "usbvideo.color.transferCharacteristics",
2991 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
2992 &color_transfer_characteristics_ext
, 0,
2996 { &hf_usb_vid_matrix_coefficients
,
2997 { "bMatrixCoefficients", "usbvideo.color.matrixCoefficients",
2998 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
2999 &matrix_coefficients_meaning_ext
, 0,
3003 /***** Video Control Header Descriptor *****/
3005 { &hf_usb_vid_control_ifdesc_bcdUVC
,
3006 { "bcdUVC", "usbvideo.bcdUVC",
3007 FT_UINT16
, BASE_HEX
, NULL
, 0,
3008 "Video Device Class Specification release number", HFILL
}
3011 { &hf_usb_vid_control_ifdesc_bInCollection
,
3012 { "bInCollection", "usbvideo.numStreamingInterfaces",
3013 FT_UINT8
, BASE_DEC
, NULL
, 0,
3014 "Number of VideoStreaming interfaces", HFILL
}
3017 { &hf_usb_vid_control_ifdesc_baInterfaceNr
,
3018 { "baInterfaceNr", "usbvideo.streamingInterfaceNumbers",
3019 FT_BYTES
, BASE_NONE
, NULL
, 0,
3020 "Interface numbers of VideoStreaming interfaces", HFILL
}},
3022 /***** Video Streaming Input Header Descriptor *****/
3024 { &hf_usb_vid_streaming_ifdesc_bNumFormats
,
3025 { "bNumFormats", "usbvideo.streaming.numFormats",
3026 FT_UINT8
, BASE_DEC
, NULL
, 0,
3027 "Number of video payload format descriptors", HFILL
}
3030 { &hf_usb_vid_streaming_bmInfo
,
3031 { "bmInfo", "usbvideo.streaming.info",
3032 FT_UINT8
, BASE_HEX
, NULL
, 0,
3033 "Capabilities", HFILL
}
3036 { &hf_usb_vid_streaming_info_D
[0],
3037 { "Dynamic Format Change", "usbvideo.streaming.info.D0",
3038 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<0),
3039 "Dynamic Format Change", HFILL
}
3042 { &hf_usb_vid_streaming_control_D
[0],
3043 { "wKeyFrameRate", "usbvideo.streaming.control.D0",
3044 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<0),
3045 "Probe and Commit support", HFILL
}
3048 { &hf_usb_vid_streaming_control_D
[1],
3049 { "wPFrameRate", "usbvideo.streaming.control.D1",
3050 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<1),
3051 "Probe and Commit support", HFILL
}
3054 { &hf_usb_vid_streaming_control_D
[2],
3055 { "wCompQuality", "usbvideo.streaming.control.D2",
3056 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<2),
3057 "Probe and Commit support", HFILL
}
3060 { &hf_usb_vid_streaming_control_D
[3],
3061 { "wCompWindowSize", "usbvideo.streaming.control.D3",
3062 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<3),
3063 "Probe and Commit support", HFILL
}
3066 { &hf_usb_vid_streaming_control_D
[4],
3067 { "Generate Key Frame", "usbvideo.streaming.control.D4",
3068 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<4),
3069 "Probe and Commit support", HFILL
}
3072 { &hf_usb_vid_streaming_control_D
[5],
3073 { "Update Frame Segment", "usbvideo.streaming.control.D5",
3074 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<5),
3075 "Probe and Commit support", HFILL
}
3078 { &hf_usb_vid_streaming_terminal_link
,
3079 { "bTerminalLink", "usbvideo.streaming.terminalLink", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3080 "Output terminal ID", HFILL
}
3083 { &hf_usb_vid_streaming_still_capture_method
,
3084 { "bStillCaptureMethod", "usbvideo.streaming.stillCaptureMethod",
3085 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
3086 &vs_still_capture_methods_ext
, 0,
3087 "Method of Still Image Capture", HFILL
}
3090 { &hf_usb_vid_streaming_trigger_support
,
3091 { "HW Triggering", "usbvideo.streaming.triggerSupport",
3092 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_supported_not_supported
), 0,
3093 "Is HW triggering supported", HFILL
}
3096 { &hf_usb_vid_streaming_trigger_usage
,
3097 { "bTriggerUsage", "usbvideo.streaming.triggerUsage",
3098 FT_UINT8
, BASE_DEC
, VALS(vs_trigger_usage
), 0,
3099 "How host SW should respond to trigger", HFILL
}
3102 /***** Interrupt URB *****/
3104 { &hf_usb_vid_interrupt_bStatusType
,
3105 { "Status Type", "usbvideo.interrupt.statusType",
3106 FT_UINT8
, BASE_HEX
, VALS(interrupt_status_types
), 0xF,
3110 { &hf_usb_vid_interrupt_bAttribute
,
3111 { "Change Type", "usbvideo.interrupt.attribute",
3112 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
,
3113 &control_change_types_ext
, 0,
3114 "Type of control change", HFILL
}
3117 { &hf_usb_vid_interrupt_bOriginator
,
3118 { "Originator", "usbvideo.interrupt.originator",
3119 FT_UINT8
, BASE_DEC
, NULL
, 0,
3120 "ID of the entity that reports this interrupt", HFILL
}
3123 { &hf_usb_vid_control_interrupt_bEvent
,
3124 { "Event", "usbvideo.interrupt.controlEvent",
3125 FT_UINT8
, BASE_HEX
, VALS(control_interrupt_events
), 0,
3126 "Type of event", HFILL
}
3129 /***** Video Control Endpoint Descriptor *****/
3131 { &hf_usb_vid_epdesc_subtype
,
3132 { "Subtype", "usbvideo.ep.descriptorSubType",
3133 FT_UINT8
, BASE_DEC
, VALS(vc_ep_descriptor_subtypes
), 0,
3134 "Descriptor Subtype", HFILL
}
3137 { &hf_usb_vid_epdesc_max_transfer_sz
,
3138 { "wMaxTransferSize", "usbvideo.ep.maxInterruptSize", FT_UINT16
,
3139 BASE_DEC
, NULL
, 0x0, "Max interrupt structure size", HFILL
}
3142 /***** Fields used in multiple contexts *****/
3144 { &hf_usb_vid_ifdesc_wTotalLength
,
3145 { "wTotalLength", "usbvideo.totalLength",
3146 FT_UINT16
, BASE_DEC
, NULL
, 0,
3147 "Video interface descriptor size", HFILL
}
3150 { &hf_usb_vid_bControlSize
,
3151 { "bControlSize", "usbvideo.bmcontrolSize",
3152 FT_UINT8
, BASE_DEC
, NULL
, 0,
3153 "Size of bmControls field", HFILL
}
3156 { &hf_usb_vid_bmControl
,
3157 { "bmControl", "usbvideo.availableControls",
3158 FT_UINT32
, BASE_HEX
, NULL
, 0,
3159 "Available controls", HFILL
}
3162 { &hf_usb_vid_bmControl_bytes
,
3163 { "bmControl", "usbvideo.availableControls.bytes",
3164 FT_BYTES
, BASE_NONE
, NULL
, 0,
3165 "Available controls", HFILL
}
3168 { &hf_usb_vid_control_ifdesc_src_id
,
3169 { "bSourceID", "usbvideo.sourceID", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3170 "Entity to which this terminal/unit is connected", HFILL
}
3175 { &hf_usb_vid_control_ifdesc_subtype
,
3176 { "Subtype", "usbvideo.control.descriptorSubType",
3177 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
3178 &vc_if_descriptor_subtypes_ext
, 0,
3179 "Descriptor Subtype", HFILL
}
3182 { &hf_usb_vid_streaming_ifdesc_subtype
,
3183 { "Subtype", "usbvideo.streaming.descriptorSubType",
3184 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
3185 &vs_if_descriptor_subtypes_ext
, 0,
3186 "Descriptor Subtype", HFILL
}
3189 { &hf_usb_vid_descriptor_data
,
3190 { "Descriptor data", "usbvideo.descriptor_data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3194 { &hf_usb_vid_control_data
,
3195 { "Control data", "usbvideo.control_data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3199 { &hf_usb_vid_control_value
,
3200 { "Control value", "usbvideo.control_value", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3204 { &hf_usb_vid_value_data
,
3205 { "Value data", "usbvideo.value_data", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3210 static int *usb_vid_ett
[] = {
3212 &ett_descriptor_video_endpoint
,
3213 &ett_descriptor_video_control
,
3214 &ett_descriptor_video_streaming
,
3215 &ett_camera_controls
,
3216 &ett_processing_controls
,
3217 &ett_streaming_controls
,
3218 &ett_streaming_info
,
3219 &ett_interlace_flags
,
3220 &ett_frame_capability_flags
,
3225 &ett_video_standards
,
3226 &ett_control_capabilities
3229 static ei_register_info ei
[] = {
3230 { &ei_usb_vid_subtype_unknown
, { "usbvideo.subtype.unknown", PI_UNDECODED
, PI_WARN
, "Unknown VC subtype", EXPFILL
}},
3231 { &ei_usb_vid_bitmask_len
, { "usbvideo.bitmask_len_error", PI_UNDECODED
, PI_WARN
, "Only least-significant bytes decoded", EXPFILL
}},
3234 expert_module_t
* expert_usb_vid
;
3236 proto_usb_vid
= proto_register_protocol("USB Video", "USBVIDEO", "usbvideo");
3237 proto_register_field_array(proto_usb_vid
, hf
, array_length(hf
));
3238 proto_register_subtree_array(usb_vid_ett
, array_length(usb_vid_ett
));
3239 expert_usb_vid
= expert_register_protocol(proto_usb_vid
);
3240 expert_register_field_array(expert_usb_vid
, ei
, array_length(ei
));
3242 usb_vid_control_handle
= register_dissector("usbvideo.control", dissect_usb_vid_control
, proto_usb_vid
);
3243 usb_vid_descriptor_handle
= register_dissector("usbvideo.descriptor", dissect_usb_vid_descriptor
, proto_usb_vid
);
3244 usb_vid_interrupt_handle
= register_dissector("usbvideo.interrupt", dissect_usb_vid_interrupt
, proto_usb_vid
);
3248 proto_reg_handoff_usb_vid(void)
3250 dissector_add_uint("usb.control", IF_CLASS_VIDEO
, usb_vid_control_handle
);
3251 dissector_add_uint("usb.descriptor", IF_CLASS_VIDEO
, usb_vid_descriptor_handle
);
3252 dissector_add_uint("usb.interrupt", IF_CLASS_VIDEO
, usb_vid_interrupt_handle
);
3255 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3260 * indent-tabs-mode: nil
3263 * vi: set shiftwidth=4 tabstop=8 expandtab:
3264 * :indentSize=4:tabSize=8:noTabs=true: