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>
16 #include "packet-usb.h"
18 void proto_register_usb_vid(void);
19 void proto_reg_handoff_usb_vid(void);
21 /* References are to sections in USB Video Class specifications -
22 * specifically V1.5, but versions have tended to keep
23 * the same numbering (as of this writing).
25 * http://www.usb.org/developers/devclass_docs/USB_Video_Class_1_5.zip
28 /* Table 2-1. Interrupt originators */
29 #define INT_VIDEOCONTROL 1
30 #define INT_VIDEOSTREAMING 2
32 #define INT_ORIGINATOR_MASK 0xF
34 /* Table 2-2. Video Control Status Packet bAttribute */
35 #define CONTROL_CHANGE_VALUE 0x00
36 #define CONTROL_CHANGE_INFO 0x01
37 #define CONTROL_CHANGE_FAILURE 0x02
38 #define CONTROL_CHANGE_MIN 0x03 /* UVC 1.5+ */
39 #define CONTROL_CHANGE_MAX 0x04 /* UVC 1.5+ */
42 /* A.2 Video Interface Subclass Codes */
43 #define SC_UNDEFINED 0
44 #define SC_VIDEOCONTROL 1
45 #define SC_VIDEOSTREAMING 2
46 #define SC_VIDEO_INTERFACE_COLLECTION 3
48 /* A.4. Video Class-Specific Descriptor Types */
49 #define CS_INTERFACE 0x24
50 #define CS_ENDPOINT 0x25
52 /* A.5 Video Class-Specific VC Interface Descriptor Subtypes */
54 #define VC_INPUT_TERMINAL 2
55 #define VC_OUTPUT_TERMINAL 3
56 #define VC_SELECTOR_UNIT 4
57 #define VC_PROCESSING_UNIT 5
58 #define VC_EXTENSION_UNIT 6
59 #define VC_ENCODING_UNIT 7
61 /* A.6 Video Class-Specific VS Interface Descriptor Subtypes */
62 #define VS_UNDEFINED 0x00
63 #define VS_INPUT_HEADER 0x01
64 #define VS_OUTPUT_HEADER 0x02
65 #define VS_STILL_IMAGE_FRAME 0x03
66 #define VS_FORMAT_UNCOMPRESSED 0x04
67 #define VS_FRAME_UNCOMPRESSED 0x05
68 #define VS_FORMAT_MJPEG 0x06
69 #define VS_FRAME_MJPEG 0x07
70 #define VS_FORMAT_MPEG1 0x08 /* Pre-UVC 1.1 */
71 #define VS_FORMAT_MPEG2PS 0x09 /* Pre-UVC 1.1 */
72 #define VS_FORMAT_MPEG2TS 0x0A
73 #define VS_FORMAT_MPEG4SL 0x0B /* Pre-UVC 1.1 */
74 #define VS_FORMAT_DV 0x0C
75 #define VS_COLORFORMAT 0x0D
76 #define VS_FORMAT_VENDOR 0x0E /* Pre-UVC 1.1 */
77 #define VS_FRAME_VENDOR 0x0F /* Pre-UVC 1.1 */
78 #define VS_FORMAT_FRAME_BASED 0x10
79 #define VS_FRAME_FRAME_BASED 0x11
80 #define VS_FORMAT_STREAM_BASED 0x12
81 #define VS_FORMAT_H264 0x13 /* UVC 1.5 */
82 #define VS_FRAME_H264 0x14 /* UVC 1.5 */
83 #define VS_FORMAT_H264_SIMULCAST 0x15 /* UVC 1.5 */
84 #define VS_FORMAT_VP8 0x16 /* UVC 1.5 */
85 #define VS_FRAME_VP8 0x17 /* UVC 1.5 */
86 #define VS_FORMAT_VP8_SIMULCAST 0x18 /* UVC 1.5 */
88 /* A.7 Video Class-Specific Endpoint Descriptor Subtypes */
89 #define EP_INTERRUPT 0x03
91 /* A.9.1 Video Control Interface Control Selectors */
92 #define VC_CONTROL_UNDEFINED 0x00
93 #define VC_VIDEO_POWER_MODE_CONTROL 0x01
94 #define VC_REQUEST_ERROR_CODE_CONTROL 0x02
95 #define VC_REQUEST_INDICATE_HOST_CLOCK_CONTROL 0x03 /* Pre-UVC 1.1 */
97 /* A.9.3 Selector Unit Control Selectors */
98 #define SU_CONTROL_UNDEFINED 0x00
99 #define SU_INPUT_SELECT_CONTROL 0x01
101 /* A.9.4 Camera Terminal Control Selectors */
102 #define CT_CONTROL_UNDEFINED 0x00
103 #define CT_SCANNING_MODE_CONTROL 0x01
104 #define CT_AE_MODE_CONTROL 0x02
105 #define CT_AE_PRIORITY_CONTROL 0x03
106 #define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
107 #define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
108 #define CT_FOCUS_ABSOLUTE_CONTROL 0x06
109 #define CT_FOCUS_RELATIVE_CONTROL 0x07
110 #define CT_FOCUS_AUTO_CONTROL 0x08
111 #define CT_IRIS_ABSOLUTE_CONTROL 0x09
112 #define CT_IRIS_RELATIVE_CONTROL 0x0A
113 #define CT_ZOOM_ABSOLUTE_CONTROL 0x0B
114 #define CT_ZOOM_RELATIVE_CONTROL 0x0C
115 #define CT_PANTILT_ABSOLUTE_CONTROL 0x0D
116 #define CT_PANTILT_RELATIVE_CONTROL 0x0E
117 #define CT_ROLL_ABSOLUTE_CONTROL 0x0F
118 #define CT_ROLL_RELATIVE_CONTROL 0x10
119 #define CT_PRIVACY_CONTROL 0x11
120 #define CT_FOCUS_SIMPLE_CONTROL 0x12 /* UVC 1.5 */
121 #define CT_WINDOW_CONTROL 0x13 /* UVC 1.5 */
122 #define CT_REGION_OF_INTEREST_CONTROL 0x14 /* UVC 1.5 */
124 /* A.9.5 Processing Unit Control Selectors */
125 #define PU_CONTROL_UNDEFINED 0x00
126 #define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
127 #define PU_BRIGHTNESS_CONTROL 0x02
128 #define PU_CONTRAST_CONTROL 0x03
129 #define PU_GAIN_CONTROL 0x04
130 #define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
131 #define PU_HUE_CONTROL 0x06
132 #define PU_SATURATION_CONTROL 0x07
133 #define PU_SHARPNESS_CONTROL 0x08
134 #define PU_GAMMA_CONTROL 0x09
135 #define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0A
136 #define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0B
137 #define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0C
138 #define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0D
139 #define PU_DIGITAL_MULTIPLIER_CONTROL 0x0E
140 #define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0F
141 #define PU_HUE_AUTO_CONTROL 0x10
142 #define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
143 #define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
144 #define PU_CONTRAST_AUTO_CONTROL 0x13
146 /* A.9.7 VideoStreaming Interface Control Selectors */
147 #define VS_CONTROL_UNDEFINED 0x00
148 #define VS_PROBE_CONTROL 0x01
149 #define VS_COMMIT_CONTROL 0x02
150 #define VS_STILL_PROBE_CONTROL 0x03
151 #define VS_STILL_COMMIT_CONTROL 0x04
152 #define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
153 #define VS_STREAM_ERROR_CODE_CONTROL 0x06
154 #define VS_GENERATE_KEY_FRAME_CONTROL 0x07
155 #define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
156 #define VS_SYNCH_DELAY_CONTROL 0x09
158 /* Appendix B Terminal Types */
159 #define TT_VENDOR_SPECIFIC 0x100
160 #define TT_STREAMING 0x101
161 #define ITT_VENDOR_SPECIFIC 0x200
162 #define ITT_CAMERA 0x201
163 #define ITT_MEDIA_TRANSPORT_INPUT 0x202
164 #define OTT_VENDOR_SPECIFIC 0x300
165 #define OTT_DISPLAY 0x301
166 #define OTT_MEDIA_TRANSPORT_OUTPUT 0x302
167 #define EXTERNAL_VENDOR_SPECIFIC 0x400
168 #define COMPOSITE_CONNECTOR 0x401
169 #define SVIDEO_CONNECTOR 0x402
170 #define COMPONENT_CONNECTOR 0x403
172 /* Table 2-2 Status Packet Format (VideoControl Interface as the Originator) */
173 #define CONTROL_INTERRUPT_EVENT_CONTROL_CHANGE 0
175 /* Table 4-7 Request Error Code Control bRequestErrorCode */
176 #define UVC_ERROR_NONE 0
177 #define UVC_ERROR_NOT_READY 1
178 #define UVC_ERROR_WRONG_STATE 2
179 #define UVC_ERROR_POWER 3
180 #define UVC_ERROR_OUT_OF_RANGE 4
181 #define UVC_ERROR_INVALID_UNIT 5
182 #define UVC_ERROR_INVALID_CONTROL 6
183 #define UVC_ERROR_INVALID_REQUEST 7
184 #define UVC_ERROR_INVALID_VALUE 8
185 #define UVC_ERROR_UNKNOWN 255
187 /* A.8 Video Class-Specific Request Codes */
188 #define USB_SETUP_SET_CUR 0x01
189 #define USB_SETUP_SET_CUR_ALL 0x11 /* UVC 1.5 */
190 #define USB_SETUP_GET_CUR 0x81
191 #define USB_SETUP_GET_MIN 0x82
192 #define USB_SETUP_GET_MAX 0x83
193 #define USB_SETUP_GET_RES 0x84
194 #define USB_SETUP_GET_LEN 0x85
195 #define USB_SETUP_GET_INFO 0x86
196 #define USB_SETUP_GET_DEF 0x87
197 #define USB_SETUP_GET_CUR_ALL 0x91 /* UVC 1.5 */
198 #define USB_SETUP_GET_MIN_ALL 0x92 /* UVC 1.5 */
199 #define USB_SETUP_GET_MAX_ALL 0x93 /* UVC 1.5 */
200 #define USB_SETUP_GET_RES_ALL 0x94 /* UVC 1.5 */
201 #define USB_SETUP_GET_DEF_ALL 0x97 /* UVC 1.5 */
203 /* protocols and header fields */
204 static int proto_usb_vid = -1;
206 static int hf_usb_vid_control_entity = -1;
207 static int hf_usb_vid_control_interface = -1;
208 static int hf_usb_vid_control_selector = -1;
209 static int hf_usb_vid_epdesc_subtype = -1;
210 static int hf_usb_vid_epdesc_max_transfer_sz = -1;
211 static int hf_usb_vid_control_ifdesc_subtype = -1;
212 static int hf_usb_vid_control_ifdesc_terminal_id = -1;
213 static int hf_usb_vid_control_ifdesc_terminal_type = -1;
214 static int hf_usb_vid_control_ifdesc_assoc_terminal = -1;
215 static int hf_usb_vid_streaming_ifdesc_subtype = -1;
216 static int hf_usb_vid_streaming_ifdesc_bNumFormats = -1;
217 static int hf_usb_vid_control_ifdesc_unit_id = -1;
218 static int hf_usb_vid_request = -1;
219 static int hf_usb_vid_length = -1;
220 static int hf_usb_vid_interrupt_bStatusType = -1;
221 static int hf_usb_vid_interrupt_bOriginator = -1;
222 static int hf_usb_vid_interrupt_bAttribute = -1;
223 static int hf_usb_vid_control_interrupt_bEvent = -1;
224 static int hf_usb_vid_control_ifdesc_bcdUVC = -1;
225 static int hf_usb_vid_ifdesc_wTotalLength = -1;
226 static int hf_usb_vid_control_ifdesc_dwClockFrequency = -1;
227 static int hf_usb_vid_control_ifdesc_bInCollection = -1;
228 static int hf_usb_vid_control_ifdesc_baInterfaceNr = -1;
229 static int hf_usb_vid_control_ifdesc_iTerminal = -1;
230 static int hf_usb_vid_control_ifdesc_src_id = -1;
231 static int hf_usb_vid_cam_objective_focal_len_min = -1;
232 static int hf_usb_vid_cam_objective_focal_len_max = -1;
233 static int hf_usb_vid_cam_ocular_focal_len = -1;
234 static int hf_usb_vid_bControlSize = -1;
235 static int hf_usb_vid_bmControl = -1;
236 static int hf_usb_vid_bmControl_bytes = -1;
237 static int hf_usb_vid_control_default = -1;
238 static int hf_usb_vid_control_min = -1;
239 static int hf_usb_vid_control_max = -1;
240 static int hf_usb_vid_control_res = -1;
241 static int hf_usb_vid_control_cur = -1;
242 static int hf_usb_vid_control_info = -1;
243 static int hf_usb_vid_control_info_D[7] = { -1, -1, -1, -1, -1, -1, -1 };
244 static int hf_usb_vid_control_length = -1;
245 static int hf_usb_vid_cam_control_D[22] = { -1, -1, -1, -1, -1, -1, -1, -1,
246 -1, -1, -1, -1, -1, -1, -1, -1,
247 -1, -1, -1, -1, -1, -1 };
248 static int hf_usb_vid_proc_control_D[19] = { -1, -1, -1, -1, -1, -1, -1, -1,
249 -1, -1, -1, -1, -1, -1, -1, -1,
251 static int hf_usb_vid_proc_standards_D[6] = { -1, -1, -1, -1, -1, -1 };
252 static int hf_usb_vid_exten_guid = -1;
253 static int hf_usb_vid_exten_num_controls = -1;
254 static int hf_usb_vid_num_inputs = -1;
255 static int hf_usb_vid_sources = -1;
256 static int hf_usb_vid_streaming_bmInfo = -1;
257 static int hf_usb_vid_streaming_info_D[1] = { -1 };
258 static int hf_usb_vid_streaming_terminal_link = -1;
259 static int hf_usb_vid_streaming_still_capture_method = -1;
260 static int hf_usb_vid_streaming_trigger_support = -1;
261 static int hf_usb_vid_streaming_trigger_usage = -1;
262 static int hf_usb_vid_streaming_control_D[6] = { -1, -1, -1, -1, -1, -1 };
263 static int hf_usb_vid_format_index = -1;
264 static int hf_usb_vid_format_num_frame_descriptors = -1;
265 static int hf_usb_vid_format_guid = -1;
266 static int hf_usb_vid_format_bits_per_pixel = -1;
267 static int hf_usb_vid_default_frame_index = -1;
268 static int hf_usb_vid_aspect_ratio_x = -1;
269 static int hf_usb_vid_aspect_ratio_y = -1;
270 static int hf_usb_vid_interlace_flags = -1;
271 static int hf_usb_vid_is_interlaced = -1;
272 static int hf_usb_vid_interlaced_fields = -1;
273 static int hf_usb_vid_field_1_first = -1;
274 static int hf_usb_vid_field_pattern = -1;
275 static int hf_usb_vid_copy_protect = -1;
276 static int hf_usb_vid_variable_size = -1;
277 static int hf_usb_vid_frame_index = -1;
278 static int hf_usb_vid_frame_capabilities = -1;
279 static int hf_usb_vid_frame_stills_supported = -1;
280 static int hf_usb_vid_frame_fixed_frame_rate = -1;
281 static int hf_usb_vid_frame_width = -1;
282 static int hf_usb_vid_frame_height = -1;
283 static int hf_usb_vid_frame_min_bit_rate = -1;
284 static int hf_usb_vid_frame_max_bit_rate = -1;
285 static int hf_usb_vid_frame_max_frame_sz = -1;
286 static int hf_usb_vid_frame_default_interval = -1;
287 static int hf_usb_vid_frame_bytes_per_line = -1;
288 static int hf_usb_vid_mjpeg_flags = -1;
289 static int hf_usb_vid_mjpeg_fixed_samples = -1;
290 static int hf_usb_vid_probe_hint = -1;
291 static int hf_usb_vid_probe_hint_D[5] = { -1, -1, -1, -1, -1 };
292 static int hf_usb_vid_frame_interval = -1;
293 static int hf_usb_vid_probe_key_frame_rate = -1;
294 static int hf_usb_vid_probe_p_frame_rate = -1;
295 static int hf_usb_vid_probe_comp_quality = -1;
296 static int hf_usb_vid_probe_comp_window = -1;
297 static int hf_usb_vid_probe_delay = -1;
298 static int hf_usb_vid_probe_max_frame_sz = -1;
299 static int hf_usb_vid_probe_max_payload_sz = -1;
300 static int hf_usb_vid_probe_clock_freq = -1;
301 static int hf_usb_vid_probe_framing = -1;
302 static int hf_usb_vid_probe_framing_D[2] = { -1, -1 };
303 static int hf_usb_vid_probe_preferred_ver = -1;
304 static int hf_usb_vid_probe_min_ver = -1;
305 static int hf_usb_vid_probe_max_ver = -1;
306 static int hf_usb_vid_frame_interval_type = -1;
307 static int hf_usb_vid_frame_min_interval = -1;
308 static int hf_usb_vid_frame_max_interval = -1;
309 static int hf_usb_vid_frame_step_interval = -1;
310 static int hf_usb_vid_color_primaries = -1;
311 static int hf_usb_vid_transfer_characteristics = -1;
312 static int hf_usb_vid_matrix_coefficients = -1;
313 static int hf_usb_vid_max_multiplier = -1;
314 static int hf_usb_vid_iProcessing = -1;
315 static int hf_usb_vid_iExtension = -1;
316 static int hf_usb_vid_iSelector = -1;
317 static int hf_usb_vid_proc_standards = -1;
318 static int hf_usb_vid_request_error = -1;
319 static int hf_usb_vid_descriptor_data = -1;
320 static int hf_usb_vid_control_data = -1;
321 static int hf_usb_vid_control_value = -1;
322 static int hf_usb_vid_value_data = -1;
326 static gint ett_usb_vid = -1;
327 static gint ett_descriptor_video_endpoint = -1;
328 static gint ett_descriptor_video_control = -1;
329 static gint ett_descriptor_video_streaming = -1;
330 static gint ett_camera_controls = -1;
331 static gint ett_processing_controls = -1;
332 static gint ett_streaming_controls = -1;
333 static gint ett_streaming_info = -1;
334 static gint ett_interlace_flags = -1;
335 static gint ett_frame_capability_flags = -1;
336 static gint ett_mjpeg_flags = -1;
337 static gint ett_video_probe = -1;
338 static gint ett_probe_hint = -1;
339 static gint ett_probe_framing = -1;
340 static gint ett_video_standards = -1;
341 static gint ett_control_capabilities = -1;
343 static expert_field ei_usb_vid_subtype_unknown = EI_INIT;
344 static expert_field ei_usb_vid_bitmask_len = EI_INIT;
347 static const value_string vc_ep_descriptor_subtypes[] = {
348 { EP_INTERRUPT, "Interrupt" },
352 static const value_string vid_descriptor_type_vals[] = {
353 {CS_INTERFACE, "video class interface"},
354 {CS_ENDPOINT, "video class endpoint"},
357 static value_string_ext vid_descriptor_type_vals_ext =
358 VALUE_STRING_EXT_INIT(vid_descriptor_type_vals);
360 static const value_string vc_if_descriptor_subtypes[] = {
361 { VC_HEADER, "Header" },
362 { VC_INPUT_TERMINAL, "Input Terminal" },
363 { VC_OUTPUT_TERMINAL, "Output Terminal" },
364 { VC_SELECTOR_UNIT, "Selector Unit" },
365 { VC_PROCESSING_UNIT, "Processing Unit" },
366 { VC_EXTENSION_UNIT, "Extension Unit" },
367 { VC_ENCODING_UNIT, "Encoding Unit" },
370 static value_string_ext vc_if_descriptor_subtypes_ext =
371 VALUE_STRING_EXT_INIT(vc_if_descriptor_subtypes);
373 static const value_string cs_control_interface[] = {
374 { VC_CONTROL_UNDEFINED, "Undefined" },
375 { VC_VIDEO_POWER_MODE_CONTROL, "Video Power Mode" },
376 { VC_REQUEST_ERROR_CODE_CONTROL, "Request Error Code" },
377 { VC_REQUEST_INDICATE_HOST_CLOCK_CONTROL, "Request Indicate Host Clock" },
380 static value_string_ext cs_control_interface_ext =
381 VALUE_STRING_EXT_INIT(cs_control_interface);
383 static const value_string cs_streaming_interface[] = {
384 { VS_CONTROL_UNDEFINED, "Undefined" },
385 { VS_PROBE_CONTROL, "Probe" },
386 { VS_COMMIT_CONTROL, "Commit" },
387 { VS_STILL_PROBE_CONTROL, "Still Probe" },
388 { VS_STILL_COMMIT_CONTROL, "Still Commit" },
389 { VS_STILL_IMAGE_TRIGGER_CONTROL, "Still Image Trigger" },
390 { VS_STREAM_ERROR_CODE_CONTROL, "Stream Error Code" },
391 { VS_GENERATE_KEY_FRAME_CONTROL, "Generate Key Frame" },
392 { VS_UPDATE_FRAME_SEGMENT_CONTROL, "Update Frame Segment" },
393 { VS_SYNCH_DELAY_CONTROL, "Synch Delay" },
396 static value_string_ext cs_streaming_interface_ext =
397 VALUE_STRING_EXT_INIT(cs_streaming_interface);
399 static const value_string cs_selector_unit[] = {
400 { SU_CONTROL_UNDEFINED, "Undefined" },
401 { SU_INPUT_SELECT_CONTROL, "Input Select" },
404 static value_string_ext cs_selector_unit_ext =
405 VALUE_STRING_EXT_INIT(cs_selector_unit);
407 static const value_string cs_camera_terminal[] = {
408 { CT_CONTROL_UNDEFINED, "Undefined" },
409 { CT_SCANNING_MODE_CONTROL, "Scanning Mode" },
410 { CT_AE_MODE_CONTROL, "Auto-Exposure Mode" },
411 { CT_AE_PRIORITY_CONTROL, "Auto-Exposure Priority" },
412 { CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, "Exposure Time (Absolute)" },
413 { CT_EXPOSURE_TIME_RELATIVE_CONTROL, "Exposure Time (Relative)" },
414 { CT_FOCUS_ABSOLUTE_CONTROL, "Focus (Absolute)" },
415 { CT_FOCUS_RELATIVE_CONTROL, "Focus (Relative)" },
416 { CT_FOCUS_AUTO_CONTROL, "Focus, Auto" },
417 { CT_IRIS_ABSOLUTE_CONTROL, "Iris (Absolute)" },
418 { CT_IRIS_RELATIVE_CONTROL, "Iris (Relative)" },
419 { CT_ZOOM_ABSOLUTE_CONTROL, "Zoom (Absolute)" },
420 { CT_ZOOM_RELATIVE_CONTROL, "Zoom (Relative)" },
421 { CT_PANTILT_ABSOLUTE_CONTROL, "PanTilt (Absolute)" },
422 { CT_PANTILT_RELATIVE_CONTROL, "PanTilt (Relative)" },
423 { CT_ROLL_ABSOLUTE_CONTROL, "Roll (Absolute)" },
424 { CT_ROLL_RELATIVE_CONTROL, "Roll (Relative)" },
425 { CT_PRIVACY_CONTROL, "Privacy" },
426 { CT_FOCUS_SIMPLE_CONTROL, "Focus (Simple)" },
427 { CT_WINDOW_CONTROL, "Window" },
428 { CT_REGION_OF_INTEREST_CONTROL, "Region of Interest" },
431 static value_string_ext cs_camera_terminal_ext =
432 VALUE_STRING_EXT_INIT(cs_camera_terminal);
434 static const value_string cs_processing_unit[] = {
435 { PU_CONTROL_UNDEFINED, "Undefined" },
436 { PU_BACKLIGHT_COMPENSATION_CONTROL, "Backlight Compensation" },
437 { PU_BRIGHTNESS_CONTROL, "Brightness" },
438 { PU_CONTRAST_CONTROL, "Contrast" },
439 { PU_GAIN_CONTROL, "Gain" },
440 { PU_POWER_LINE_FREQUENCY_CONTROL, "Power Line Frequency" },
441 { PU_HUE_CONTROL, "Hue" },
442 { PU_SATURATION_CONTROL, "Saturation" },
443 { PU_SHARPNESS_CONTROL, "Sharpness" },
444 { PU_GAMMA_CONTROL, "Gamma" },
445 { PU_WHITE_BALANCE_TEMPERATURE_CONTROL, "White Balance Temperature" },
446 { PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,"White Balance Temperature Auto" },
447 { PU_WHITE_BALANCE_COMPONENT_CONTROL, "White Balance Component" },
448 { PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, "White Balance Component Auto" },
449 { PU_DIGITAL_MULTIPLIER_CONTROL, "Digital Multiplier" },
450 { PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL, "Digital Multiplier Limit" },
451 { PU_HUE_AUTO_CONTROL, "Hue Auto" },
452 { PU_ANALOG_VIDEO_STANDARD_CONTROL, "Video Standard" },
453 { PU_ANALOG_LOCK_STATUS_CONTROL, "Analog Lock Status" },
454 { PU_CONTRAST_AUTO_CONTROL, "Contrast Auto" },
457 static value_string_ext cs_processing_unit_ext =
458 VALUE_STRING_EXT_INIT(cs_processing_unit);
460 static const value_string vc_terminal_types[] = {
461 { TT_VENDOR_SPECIFIC, "Vendor Specific", },
462 { TT_STREAMING, "Streaming" },
463 { ITT_VENDOR_SPECIFIC, "Vendor Specific Input" },
464 { ITT_CAMERA, "Camera Input" },
465 { ITT_MEDIA_TRANSPORT_INPUT, "Media Transport Input" },
466 { OTT_VENDOR_SPECIFIC, "Vendor Specific Output" },
467 { OTT_DISPLAY, "Display Output" },
468 { OTT_MEDIA_TRANSPORT_OUTPUT, "Media Transport Output" },
469 { EXTERNAL_VENDOR_SPECIFIC, "Vendor Specific External" },
470 { COMPOSITE_CONNECTOR, "Composite Connector" },
471 { SVIDEO_CONNECTOR, "SVideo Connector" },
472 { COMPONENT_CONNECTOR, "Component Connector" },
475 static value_string_ext vc_terminal_types_ext =
476 VALUE_STRING_EXT_INIT(vc_terminal_types);
478 static const value_string vs_if_descriptor_subtypes[] = {
479 { VS_UNDEFINED, "Undefined" },
480 { VS_INPUT_HEADER, "Input Header" },
481 { VS_OUTPUT_HEADER, "Output Header" },
482 { VS_STILL_IMAGE_FRAME, "Still Image Frame" },
483 { VS_FORMAT_UNCOMPRESSED, "Format Uncompressed" },
484 { VS_FRAME_UNCOMPRESSED, "Frame Uncompressed" },
485 { VS_FORMAT_MJPEG, "Format MJPEG" },
486 { VS_FRAME_MJPEG, "Frame MJPEG" },
487 { VS_FORMAT_MPEG1, "Format MPEG1" },
488 { VS_FORMAT_MPEG2PS, "Format MPEG2-PS" },
489 { VS_FORMAT_MPEG2TS, "Format MPEG2-TS" },
490 { VS_FORMAT_MPEG4SL, "Format MPEG4-SL" },
491 { VS_FORMAT_DV, "Format DV" },
492 { VS_COLORFORMAT, "Colorformat" },
493 { VS_FORMAT_VENDOR, "Format Vendor" },
494 { VS_FRAME_VENDOR, "Frame Vendor" },
495 { VS_FORMAT_FRAME_BASED, "Format Frame-Based" },
496 { VS_FRAME_FRAME_BASED, "Frame Frame-Based" },
497 { VS_FORMAT_STREAM_BASED, "Format Stream Based" },
498 { VS_FORMAT_H264, "Format H.264" },
499 { VS_FRAME_H264, "Frame H.264" },
500 { VS_FORMAT_H264_SIMULCAST, "Format H.264 Simulcast" },
501 { VS_FORMAT_VP8, "Format VP8" },
502 { VS_FRAME_VP8, "Frame VP8" },
503 { VS_FORMAT_VP8_SIMULCAST, "Format VP8 Simulcast" },
506 static value_string_ext vs_if_descriptor_subtypes_ext =
507 VALUE_STRING_EXT_INIT(vs_if_descriptor_subtypes);
509 static const value_string interrupt_status_types[] = {
510 { INT_VIDEOCONTROL, "VideoControl Interface" },
511 { INT_VIDEOSTREAMING, "VideoStreaming Interface" },
515 static const value_string control_change_types[] = {
516 { CONTROL_CHANGE_VALUE, "Value" },
517 { CONTROL_CHANGE_INFO, "Info" },
518 { CONTROL_CHANGE_FAILURE, "Failure" },
519 { CONTROL_CHANGE_MIN, "Min" },
520 { CONTROL_CHANGE_MAX, "Max" },
523 static value_string_ext control_change_types_ext =
524 VALUE_STRING_EXT_INIT(control_change_types);
526 static const value_string control_interrupt_events[] = {
527 { CONTROL_INTERRUPT_EVENT_CONTROL_CHANGE, "Control Change" },
531 /* Table 3-13 VS Interface Input Header Descriptor - bStillCaptureMethod field */
532 static const value_string vs_still_capture_methods[] = {
534 { 1, "Uninterrupted streaming" },
535 { 2, "Suspended streaming" },
536 { 3, "Dedicated pipe" },
539 static value_string_ext vs_still_capture_methods_ext =
540 VALUE_STRING_EXT_INIT(vs_still_capture_methods);
542 /* Table 3-13 VS Interface Input Header Descriptor - bTriggerUsage field */
543 static const value_string vs_trigger_usage[] = {
544 { 0, "Initiate still image capture" },
545 { 1, "General purpose button event" },
549 /* bmInterlaceFlags for format descriptors */
550 static const true_false_string is_interlaced_meaning = {
555 /* bmInterlaceFlags for format descriptors */
556 static const true_false_string interlaced_fields_meaning = {
561 /* bmInterlaceFlags for format descriptors */
562 static const value_string field_pattern_meaning[] = {
563 { 0, "Field 1 only" },
564 { 1, "Field 2 only" },
565 { 2, "Regular pattern of fields 1 and 2" },
566 { 3, "Random pattern of fields 1 and 2" },
569 static value_string_ext field_pattern_meaning_ext =
570 VALUE_STRING_EXT_INIT(field_pattern_meaning);
572 /* bCopyProtect for format descriptors */
573 static const value_string copy_protect_meaning[] = {
574 { 0, "No restrictions" },
575 { 1, "Restrict duplication" },
579 /* Table 4-46 Video Probe and Commit Controls - bmHint field */
580 static const true_false_string probe_hint_meaning = {
585 /* Table 3-19 Color Matching Descriptor - bColorPrimaries field */
586 static const value_string color_primaries_meaning[] = {
587 { 0, "Unspecified" },
588 { 1, "BT.709, sRGB" },
589 { 2, "BT.470-2 (M)" },
590 { 3, "BT.470-2 (B,G)" },
595 static value_string_ext color_primaries_meaning_ext =
596 VALUE_STRING_EXT_INIT(color_primaries_meaning);
598 /* Table 3-19 Color Matching Descriptor - bTransferCharacteristics field */
599 static const value_string color_transfer_characteristics[] = {
600 { 0, "Unspecified" },
602 { 2, "BT.470-2 (M)" },
603 { 3, "BT.470-2 (B,G)" },
606 { 6, "Linear (V=Lc)" },
610 static value_string_ext color_transfer_characteristics_ext =
611 VALUE_STRING_EXT_INIT(color_transfer_characteristics);
613 /* Table 3-19 Color Matching Descriptor - bMatrixCoefficients field */
614 static const value_string matrix_coefficients_meaning[] = {
615 { 0, "Unspecified" },
618 { 3, "BT.470-2 (B,G)" },
619 { 4, "SMPTE 170M (BT.601)" },
623 static value_string_ext matrix_coefficients_meaning_ext =
624 VALUE_STRING_EXT_INIT(matrix_coefficients_meaning);
626 static const value_string request_error_codes[] = {
627 { UVC_ERROR_NONE, "No error" },
628 { UVC_ERROR_NOT_READY, "Not ready" },
629 { UVC_ERROR_WRONG_STATE, "Wrong state" },
630 { UVC_ERROR_POWER, "Insufficient power" } ,
631 { UVC_ERROR_OUT_OF_RANGE, "Out of range" },
632 { UVC_ERROR_INVALID_UNIT, "Invalid unit" },
633 { UVC_ERROR_INVALID_CONTROL, "Invalid control" },
634 { UVC_ERROR_INVALID_REQUEST, "Invalid request" },
635 { UVC_ERROR_INVALID_VALUE, "Invalid value within range" },
636 { UVC_ERROR_UNKNOWN, "Unknown" },
639 static value_string_ext request_error_codes_ext =
640 VALUE_STRING_EXT_INIT(request_error_codes);
642 /* There is one such structure per terminal or unit per interface */
647 guint16 terminalType;
650 /* video_entity_t's (units/terminals) associated with each video interface */
651 /* There is one such structure for each video conversation (interface) */
652 typedef struct _video_conv_info_t {
653 wmem_tree_t* entities; /* indexed by entity ID */
656 /*****************************************************************************/
657 /* UTILITY FUNCTIONS */
658 /*****************************************************************************/
661 * Dissector for variable-length bmControl bitmask / bControlSize pair.
663 * Creates an item for bControlSize, and a subtree for the bmControl bitmask.
665 * @param tree protocol tree to be the parent of the bitmask subtree
666 * @param tvb the tv_buff with the (remaining) packet data
667 * @param offset where in tvb to find bControlSize field
668 * @param ett_subtree index of the subtree to use for this bitmask
669 * @param bm_items NULL-terminated array of pointers that lists all the fields
672 * @return offset within tvb at which dissection should continue
675 dissect_bmControl(proto_tree *tree, tvbuff_t *tvb, int offset,
676 gint ett_subtree, const int** bm_items)
680 bm_size = tvb_get_guint8(tvb, offset);
681 proto_tree_add_item(tree, hf_usb_vid_bControlSize, tvb, offset, 1, ENC_LITTLE_ENDIAN);
686 proto_tree_add_bitmask_len(tree, tvb, offset, bm_size, hf_usb_vid_bmControl,
687 ett_subtree, bm_items, &ei_usb_vid_bitmask_len, ENC_LITTLE_ENDIAN);
694 /*****************************************************************************/
695 /* VIDEO CONTROL DESCRIPTORS */
696 /*****************************************************************************/
698 /* Dissect a Camera Terminal descriptor */
700 dissect_usb_video_camera_terminal(proto_tree *tree, tvbuff_t *tvb, int offset)
702 static const int *control_bits[] = {
703 &hf_usb_vid_cam_control_D[0],
704 &hf_usb_vid_cam_control_D[1],
705 &hf_usb_vid_cam_control_D[2],
706 &hf_usb_vid_cam_control_D[3],
707 &hf_usb_vid_cam_control_D[4],
708 &hf_usb_vid_cam_control_D[5],
709 &hf_usb_vid_cam_control_D[6],
710 &hf_usb_vid_cam_control_D[7],
711 &hf_usb_vid_cam_control_D[8],
712 &hf_usb_vid_cam_control_D[9],
713 &hf_usb_vid_cam_control_D[10],
714 &hf_usb_vid_cam_control_D[11],
715 &hf_usb_vid_cam_control_D[12],
716 &hf_usb_vid_cam_control_D[13],
717 &hf_usb_vid_cam_control_D[14],
718 &hf_usb_vid_cam_control_D[15],
719 &hf_usb_vid_cam_control_D[16],
720 &hf_usb_vid_cam_control_D[17],
721 &hf_usb_vid_cam_control_D[18],
722 &hf_usb_vid_cam_control_D[19],
723 &hf_usb_vid_cam_control_D[20],
724 &hf_usb_vid_cam_control_D[21],
728 DISSECTOR_ASSERT(array_length(control_bits) == (1+array_length(hf_usb_vid_cam_control_D)));
730 proto_tree_add_item(tree, hf_usb_vid_cam_objective_focal_len_min, tvb, offset, 2, ENC_LITTLE_ENDIAN);
732 proto_tree_add_item(tree, hf_usb_vid_cam_objective_focal_len_max, tvb, offset, 2, ENC_LITTLE_ENDIAN);
734 proto_tree_add_item(tree, hf_usb_vid_cam_ocular_focal_len, tvb, offset, 2, ENC_LITTLE_ENDIAN);
737 offset = dissect_bmControl(tree, tvb, offset, ett_camera_controls, control_bits);
742 /* Dissect a Processing Unit descriptor */
744 dissect_usb_video_processing_unit(proto_tree *tree, tvbuff_t *tvb, int offset)
746 static const int *control_bits[] = {
747 &hf_usb_vid_proc_control_D[0],
748 &hf_usb_vid_proc_control_D[1],
749 &hf_usb_vid_proc_control_D[2],
750 &hf_usb_vid_proc_control_D[3],
751 &hf_usb_vid_proc_control_D[4],
752 &hf_usb_vid_proc_control_D[5],
753 &hf_usb_vid_proc_control_D[6],
754 &hf_usb_vid_proc_control_D[7],
755 &hf_usb_vid_proc_control_D[8],
756 &hf_usb_vid_proc_control_D[9],
757 &hf_usb_vid_proc_control_D[10],
758 &hf_usb_vid_proc_control_D[11],
759 &hf_usb_vid_proc_control_D[12],
760 &hf_usb_vid_proc_control_D[13],
761 &hf_usb_vid_proc_control_D[14],
762 &hf_usb_vid_proc_control_D[15],
763 &hf_usb_vid_proc_control_D[16],
764 &hf_usb_vid_proc_control_D[17],
765 &hf_usb_vid_proc_control_D[18],
769 DISSECTOR_ASSERT(array_length(control_bits) == (1+array_length(hf_usb_vid_proc_control_D)));
771 proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_src_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
772 proto_tree_add_item(tree, hf_usb_vid_max_multiplier, tvb, offset+1, 2, ENC_LITTLE_ENDIAN);
775 offset = dissect_bmControl(tree, tvb, offset, ett_processing_controls, control_bits);
777 proto_tree_add_item(tree, hf_usb_vid_iProcessing, tvb, offset, 1, ENC_LITTLE_ENDIAN);
780 /* UVC 1.1 added bmVideoStandards */
781 if (tvb_reported_length_remaining(tvb, offset) > 0)
783 static const int *standard_bits[] = {
784 &hf_usb_vid_proc_standards_D[0],
785 &hf_usb_vid_proc_standards_D[1],
786 &hf_usb_vid_proc_standards_D[2],
787 &hf_usb_vid_proc_standards_D[3],
788 &hf_usb_vid_proc_standards_D[4],
789 &hf_usb_vid_proc_standards_D[5],
793 DISSECTOR_ASSERT(array_length(standard_bits) == (1+array_length(hf_usb_vid_proc_standards_D)));
795 proto_tree_add_bitmask(tree, tvb, offset, hf_usb_vid_proc_standards,
796 ett_video_standards, standard_bits, ENC_NA);
803 /* Dissect a Selector Unit descriptor */
805 dissect_usb_video_selector_unit(proto_tree *tree, tvbuff_t *tvb, int offset)
809 num_inputs = tvb_get_guint8(tvb, offset);
810 proto_tree_add_item(tree, hf_usb_vid_num_inputs, tvb, offset, 1, ENC_LITTLE_ENDIAN);
815 proto_tree_add_item(tree, hf_usb_vid_sources, tvb, offset, num_inputs, ENC_NA);
816 offset += num_inputs;
819 proto_tree_add_item(tree, hf_usb_vid_iSelector, tvb, offset, 1, ENC_LITTLE_ENDIAN);
825 /* Dissect an Extension Unit descriptor */
827 dissect_usb_video_extension_unit(proto_tree *tree, tvbuff_t *tvb, int offset)
832 proto_tree_add_item(tree, hf_usb_vid_exten_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
833 proto_tree_add_item(tree, hf_usb_vid_exten_num_controls, tvb, offset+16, 1, ENC_LITTLE_ENDIAN);
836 num_inputs = tvb_get_guint8(tvb, offset);
837 proto_tree_add_item(tree, hf_usb_vid_num_inputs, tvb, offset, 1, ENC_LITTLE_ENDIAN);
842 proto_tree_add_item(tree, hf_usb_vid_sources, tvb, offset, num_inputs, ENC_NA);
843 offset += num_inputs;
846 control_size = tvb_get_guint8(tvb, offset);
847 proto_tree_add_item(tree, hf_usb_vid_bControlSize, tvb, offset, 1, ENC_LITTLE_ENDIAN);
850 if (control_size > 0)
852 if (control_size <= proto_registrar_get_length(hf_usb_vid_bmControl))
854 proto_tree_add_item(tree, hf_usb_vid_bmControl, tvb, offset, control_size,
859 /* Too big to display as integer */
860 /* @todo Display as FT_BYTES with a big-endian disclaimer?
861 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7933
863 proto_tree_add_bytes_format(tree, hf_usb_vid_bmControl_bytes, tvb, offset, control_size, NULL, "bmControl");
865 offset += control_size;
868 proto_tree_add_item(tree, hf_usb_vid_iExtension, tvb, offset, 1, ENC_LITTLE_ENDIAN);
875 * Dissector for video class control interface descriptors
877 * @param parent_tree the protocol tree to be the parent of the descriptor subtree
878 * @param tvb the tv_buff with the (remaining) packet data
879 * On entry the gaze is set to the descriptor length field.
880 * @param descriptor_len Length of the descriptor to dissect
881 * @param pinfo Information associated with the packet being dissected
883 * @return offset within tvb at which dissection should continue
886 dissect_usb_video_control_interface_descriptor(proto_tree *parent_tree, tvbuff_t *tvb,
887 guint8 descriptor_len, packet_info *pinfo, usb_conv_info_t *usb_conv_info)
889 video_conv_info_t *video_conv_info = NULL;
890 video_entity_t *entity = NULL;
891 proto_item *item = NULL;
892 proto_item *subtype_item = NULL;
893 proto_tree *tree = NULL;
894 guint8 entity_id = 0;
895 guint16 terminal_type = 0;
899 subtype = tvb_get_guint8(tvb, offset+2);
903 const gchar *subtype_str;
905 subtype_str = val_to_str_ext(subtype, &vc_if_descriptor_subtypes_ext, "Unknown (0x%x)");
907 tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, descriptor_len,
908 ett_descriptor_video_control, &item, "VIDEO CONTROL INTERFACE DESCRIPTOR [%s]",
913 dissect_usb_descriptor_header(tree, tvb, offset, &vid_descriptor_type_vals_ext);
914 subtype_item = proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_subtype, tvb, offset+2, 1, ENC_LITTLE_ENDIAN);
917 if (subtype == VC_HEADER)
919 guint8 num_vs_interfaces;
921 proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_bcdUVC, tvb, offset, 2, ENC_LITTLE_ENDIAN);
922 proto_tree_add_item(tree, hf_usb_vid_ifdesc_wTotalLength, tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
923 proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_dwClockFrequency, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
925 num_vs_interfaces = tvb_get_guint8(tvb, offset+8);
926 proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_bInCollection, tvb, offset+8, 1, ENC_LITTLE_ENDIAN);
928 if (num_vs_interfaces > 0)
930 proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_baInterfaceNr, tvb, offset+9, num_vs_interfaces, ENC_NA);
933 offset += 9 + num_vs_interfaces;
935 else if ((subtype == VC_INPUT_TERMINAL) || (subtype == VC_OUTPUT_TERMINAL))
937 /* Fields common to input and output terminals */
938 entity_id = tvb_get_guint8(tvb, offset);
939 terminal_type = tvb_get_letohs(tvb, offset+1);
941 proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_terminal_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
942 proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_terminal_type, tvb, offset+1, 2, ENC_LITTLE_ENDIAN);
943 proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_assoc_terminal, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
946 if (subtype == VC_OUTPUT_TERMINAL)
948 proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_src_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
952 proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_iTerminal, tvb, offset, 1, ENC_LITTLE_ENDIAN);
955 if (subtype == VC_INPUT_TERMINAL)
957 if (terminal_type == ITT_CAMERA)
959 offset = dissect_usb_video_camera_terminal(tree, tvb, offset);
961 else if (terminal_type == ITT_MEDIA_TRANSPORT_INPUT)
967 if (subtype == VC_OUTPUT_TERMINAL)
969 if (terminal_type == OTT_MEDIA_TRANSPORT_OUTPUT)
977 /* Field common to extension / processing / selector / encoding units */
978 entity_id = tvb_get_guint8(tvb, offset);
979 proto_tree_add_item(tree, hf_usb_vid_control_ifdesc_unit_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
982 if (subtype == VC_PROCESSING_UNIT)
984 offset = dissect_usb_video_processing_unit(tree, tvb, offset);
986 else if (subtype == VC_SELECTOR_UNIT)
988 offset = dissect_usb_video_selector_unit(tree, tvb, offset);
990 else if (subtype == VC_EXTENSION_UNIT)
992 offset = dissect_usb_video_extension_unit(tree, tvb, offset);
994 else if (subtype == VC_ENCODING_UNIT)
1000 expert_add_info_format(pinfo, subtype_item, &ei_usb_vid_subtype_unknown,
1001 "Unknown VC subtype %u", subtype);
1005 /* Soak up descriptor bytes beyond those we know how to dissect */
1006 if (offset < descriptor_len)
1008 proto_tree_add_item(tree, hf_usb_vid_descriptor_data, tvb, offset, descriptor_len-offset, ENC_NA);
1009 /* offset = descriptor_len; */
1013 proto_item_append_text(item, " (Entity %d)", entity_id);
1015 if (subtype != VC_HEADER && usb_conv_info)
1017 /* Switch to the usb_conv_info of the Video Control interface */
1018 usb_conv_info = get_usb_iface_conv_info(pinfo, usb_conv_info->interfaceNum);
1019 video_conv_info = (video_conv_info_t *)usb_conv_info->class_data;
1021 if (!video_conv_info)
1023 video_conv_info = wmem_new(wmem_file_scope(), video_conv_info_t);
1024 video_conv_info->entities = wmem_tree_new(wmem_file_scope());
1025 usb_conv_info->class_data = video_conv_info;
1026 usb_conv_info->class_data_type = USB_CONV_VIDEO;
1027 } else if (usb_conv_info->class_data_type != USB_CONV_VIDEO) {
1028 /* Stop dissection if another USB type is in the conversation */
1029 return descriptor_len;
1032 entity = (video_entity_t*) wmem_tree_lookup32(video_conv_info->entities, entity_id);
1035 entity = wmem_new(wmem_file_scope(), video_entity_t);
1036 entity->entityID = entity_id;
1037 entity->subtype = subtype;
1038 entity->terminalType = terminal_type;
1040 wmem_tree_insert32(video_conv_info->entities, entity_id, entity);
1044 return descriptor_len;
1047 /*****************************************************************************/
1048 /* VIDEO STREAMING DESCRIPTORS */
1049 /*****************************************************************************/
1051 /* Dissect a Video Streaming Input Header descriptor */
1053 dissect_usb_video_streaming_input_header(proto_tree *tree, tvbuff_t *tvb, int offset)
1058 static const int *info_bits[] = {
1059 &hf_usb_vid_streaming_info_D[0],
1062 static const int *control_bits[] = {
1063 &hf_usb_vid_streaming_control_D[0],
1064 &hf_usb_vid_streaming_control_D[1],
1065 &hf_usb_vid_streaming_control_D[2],
1066 &hf_usb_vid_streaming_control_D[3],
1067 &hf_usb_vid_streaming_control_D[4],
1068 &hf_usb_vid_streaming_control_D[5],
1072 DISSECTOR_ASSERT(array_length(control_bits) == (1+array_length(hf_usb_vid_streaming_control_D)));
1074 num_formats = tvb_get_guint8(tvb, offset);
1075 proto_tree_add_item(tree, hf_usb_vid_streaming_ifdesc_bNumFormats, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1076 proto_tree_add_item(tree, hf_usb_vid_ifdesc_wTotalLength, tvb, offset+1, 2, ENC_LITTLE_ENDIAN);
1079 dissect_usb_endpoint_address(tree, tvb, offset);
1082 proto_tree_add_bitmask(tree, tvb, offset, hf_usb_vid_streaming_bmInfo,
1083 ett_streaming_info, info_bits, ENC_NA);
1085 proto_tree_add_item(tree, hf_usb_vid_streaming_terminal_link, tvb, offset+1, 1, ENC_LITTLE_ENDIAN);
1086 proto_tree_add_item(tree, hf_usb_vid_streaming_still_capture_method, tvb, offset+2, 1, ENC_LITTLE_ENDIAN);
1089 proto_tree_add_item(tree, hf_usb_vid_streaming_trigger_support, tvb, offset, 1, ENC_NA);
1090 if (tvb_get_guint8(tvb, offset) > 0)
1092 proto_tree_add_item(tree, hf_usb_vid_streaming_trigger_usage, tvb, offset+1, 1, ENC_LITTLE_ENDIAN);
1096 proto_tree_add_uint_format_value(tree, hf_usb_vid_streaming_trigger_usage, tvb, offset+1, 1, 0, "Not applicable");
1101 /* NOTE: Can't use dissect_bmControl here because there's only one size
1102 * field for (potentially) multiple bmControl fields
1104 bm_size = tvb_get_guint8(tvb, offset);
1105 proto_tree_add_item(tree, hf_usb_vid_bControlSize, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1111 for (i=0; i<num_formats; ++i)
1113 proto_tree_add_bitmask_len(tree, tvb, offset, bm_size, hf_usb_vid_bmControl,
1114 ett_streaming_controls, control_bits, &ei_usb_vid_bitmask_len,
1124 * Dissect a known Video Payload Format descriptor.
1126 * @param tree protocol tree to which fields should be added
1127 * @param tvb the tv_buff with the (remaining) packet data
1128 * @param offset where in tvb to begin dissection.
1129 * On entry this refers to the bFormatIndex field.
1130 * @param subtype Type of format descriptor, from the
1131 * bDescriptorSubtype field
1133 * @return offset within tvb at which dissection should continue
1136 dissect_usb_video_format(proto_tree *tree, tvbuff_t *tvb, int offset,
1139 static const int *interlace_bits[] = {
1140 &hf_usb_vid_is_interlaced,
1141 &hf_usb_vid_interlaced_fields,
1142 &hf_usb_vid_field_1_first,
1143 &hf_usb_vid_field_pattern,
1147 proto_item *desc_item;
1148 guint8 format_index;
1150 /* Augment the descriptor root item with the index of this descriptor */
1151 format_index = tvb_get_guint8(tvb, offset);
1152 desc_item = proto_tree_get_parent(tree);
1153 proto_item_append_text(desc_item, " (Format %u)", format_index);
1155 proto_tree_add_item(tree, hf_usb_vid_format_index, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1156 proto_tree_add_item(tree, hf_usb_vid_format_num_frame_descriptors, tvb, offset+1, 1, ENC_LITTLE_ENDIAN);
1159 if ((subtype == VS_FORMAT_UNCOMPRESSED) || (subtype == VS_FORMAT_FRAME_BASED))
1161 /* Augment the descriptor root item with the format's four-character-code */
1163 tvb_memcpy(tvb, (guint8 *)fourcc, offset, 4);
1165 proto_item_append_text(desc_item, ": %s", fourcc);
1167 proto_tree_add_item(tree, hf_usb_vid_format_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN);
1168 proto_tree_add_item(tree, hf_usb_vid_format_bits_per_pixel, tvb, offset+16, 1, ENC_LITTLE_ENDIAN);
1171 else if (subtype == VS_FORMAT_MJPEG)
1173 static const int * flags[] = {
1174 &hf_usb_vid_mjpeg_fixed_samples,
1178 proto_tree_add_bitmask(tree, tvb, offset, hf_usb_vid_mjpeg_flags, ett_mjpeg_flags, flags, ENC_NA);
1183 /* We should only be called for known format descriptor subtypes */
1184 DISSECTOR_ASSERT_NOT_REACHED();
1187 proto_tree_add_item(tree, hf_usb_vid_default_frame_index, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1188 proto_tree_add_item(tree, hf_usb_vid_aspect_ratio_x, tvb, offset+1, 1, ENC_LITTLE_ENDIAN);
1189 proto_tree_add_item(tree, hf_usb_vid_aspect_ratio_y, tvb, offset+2, 1, ENC_LITTLE_ENDIAN);
1193 /* @todo Display "N/A" if Camera Terminal does not support scanning mode control */
1195 proto_tree_add_uint_format_value(tree, hf_usb_vid_interlace_flags, tvb, offset, 1, tvb_get_guint8(tvb, offset), "Not applicable");
1198 proto_tree_add_bitmask(tree, tvb, offset, hf_usb_vid_interlace_flags,
1199 ett_interlace_flags, interlace_bits, ENC_NA);
1202 proto_tree_add_item(tree, hf_usb_vid_copy_protect, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1205 if (subtype == VS_FORMAT_FRAME_BASED)
1207 proto_tree_add_item(tree, hf_usb_vid_variable_size, tvb, offset, 1, ENC_NA);
1215 * Dissect a known Video Frame descriptor.
1217 * @param tree protocol tree to which fields should be added
1218 * @param tvb the tv_buff with the (remaining) packet data
1219 * @param offset where in tvb to begin dissection.
1220 * On entry this refers to the bFrameIndex field.
1221 * @param subtype Type of frame descriptor, from the
1222 * bDescriptorSubtype field
1224 * @return offset within tvb at which dissection should continue
1227 dissect_usb_video_frame(proto_tree *tree, tvbuff_t *tvb, int offset,
1230 static const int *capability_bits[] = {
1231 &hf_usb_vid_frame_stills_supported,
1232 &hf_usb_vid_frame_fixed_frame_rate,
1235 proto_item *desc_item;
1236 guint8 bFrameIntervalType;
1238 guint16 frame_width;
1239 guint16 frame_height;
1241 frame_index = tvb_get_guint8(tvb, offset);
1242 proto_tree_add_item(tree, hf_usb_vid_frame_index, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1245 proto_tree_add_bitmask(tree, tvb, offset, hf_usb_vid_frame_capabilities,
1246 ett_frame_capability_flags, capability_bits, ENC_NA);
1249 proto_tree_add_item(tree, hf_usb_vid_frame_width, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1250 proto_tree_add_item(tree, hf_usb_vid_frame_height, tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
1252 /* Augment the descriptor root item with useful information */
1253 frame_width = tvb_get_letohs(tvb, offset);
1254 frame_height = tvb_get_letohs(tvb, offset+2);
1255 desc_item = proto_tree_get_parent(tree);
1256 proto_item_append_text(desc_item, " (Index %2u): %4u x %4u", frame_index, frame_width, frame_height);
1258 proto_tree_add_item(tree, hf_usb_vid_frame_min_bit_rate, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
1259 proto_tree_add_item(tree, hf_usb_vid_frame_max_bit_rate, tvb, offset+8, 4, ENC_LITTLE_ENDIAN);
1262 if (subtype != VS_FRAME_FRAME_BASED)
1264 proto_tree_add_item(tree, hf_usb_vid_frame_max_frame_sz, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1268 proto_tree_add_item(tree, hf_usb_vid_frame_default_interval, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1271 bFrameIntervalType = tvb_get_guint8(tvb, offset);
1272 if (bFrameIntervalType == 0)
1274 proto_tree_add_uint_format_value(tree, hf_usb_vid_frame_interval_type, tvb, offset, 1,
1275 bFrameIntervalType, "Continuous (0)");
1278 if (subtype == VS_FRAME_FRAME_BASED)
1280 proto_tree_add_item(tree, hf_usb_vid_frame_bytes_per_line, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1284 proto_tree_add_item(tree, hf_usb_vid_frame_min_interval, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1285 proto_tree_add_item(tree, hf_usb_vid_frame_max_interval, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
1286 proto_tree_add_item(tree, hf_usb_vid_frame_step_interval, tvb, offset+8, 4, ENC_LITTLE_ENDIAN);
1292 proto_tree_add_uint_format_value(tree, hf_usb_vid_frame_interval_type, tvb, offset, 1,
1293 bFrameIntervalType, "Discrete (%u choice%s)",
1294 bFrameIntervalType, (bFrameIntervalType > 1) ? "s" : "");
1297 if (subtype == VS_FRAME_FRAME_BASED)
1299 proto_tree_add_item(tree, hf_usb_vid_frame_bytes_per_line, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1303 for (i=0; i<bFrameIntervalType; ++i)
1305 proto_tree_add_item(tree, hf_usb_vid_frame_interval, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1313 /* Dissect a Color Matching descriptor */
1315 dissect_usb_video_colorformat(proto_tree *tree, tvbuff_t *tvb, int offset)
1317 proto_tree_add_item(tree, hf_usb_vid_color_primaries, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1318 proto_tree_add_item(tree, hf_usb_vid_transfer_characteristics, tvb, offset+1, 1, ENC_LITTLE_ENDIAN);
1319 proto_tree_add_item(tree, hf_usb_vid_matrix_coefficients, tvb, offset+2, 1, ENC_LITTLE_ENDIAN);
1326 * Dissector for video class streaming interface descriptors.
1328 * @param parent_tree the protocol tree to be the parent of the descriptor subtree
1329 * @param tvb the tv_buff with the (remaining) packet data
1330 * On entry the gaze is set to the descriptor length field.
1331 * @param descriptor_len Length of the descriptor to dissect
1333 * @return offset within tvb at which dissection should continue
1336 dissect_usb_video_streaming_interface_descriptor(proto_tree *parent_tree, tvbuff_t *tvb,
1337 guint8 descriptor_len)
1341 const gchar *subtype_str;
1344 subtype = tvb_get_guint8(tvb, offset+2);
1346 subtype_str = val_to_str_ext(subtype, &vs_if_descriptor_subtypes_ext, "Unknown (0x%x)");
1347 tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, descriptor_len,
1348 ett_descriptor_video_streaming, NULL, "VIDEO STREAMING INTERFACE DESCRIPTOR [%s]",
1351 dissect_usb_descriptor_header(tree, tvb, offset, &vid_descriptor_type_vals_ext);
1352 proto_tree_add_item(tree, hf_usb_vid_streaming_ifdesc_subtype, tvb, offset+2, 1, ENC_LITTLE_ENDIAN);
1357 case VS_INPUT_HEADER:
1358 offset = dissect_usb_video_streaming_input_header(tree, tvb, offset);
1361 case VS_FORMAT_UNCOMPRESSED:
1362 case VS_FORMAT_MJPEG:
1363 case VS_FORMAT_FRAME_BASED:
1364 offset = dissect_usb_video_format(tree, tvb, offset, subtype);
1367 /* @todo MPEG2, H.264, VP8, Still Image Frame */
1368 /* @todo Obsolete UVC-1.0 descriptors? */
1370 case VS_FRAME_UNCOMPRESSED:
1371 case VS_FRAME_MJPEG:
1372 case VS_FRAME_FRAME_BASED:
1373 offset = dissect_usb_video_frame(tree, tvb, offset, subtype);
1376 case VS_COLORFORMAT:
1377 offset = dissect_usb_video_colorformat(tree, tvb, offset);
1384 /* Soak up descriptor bytes beyond those we know how to dissect */
1385 if (offset < descriptor_len)
1386 proto_tree_add_item(tree, hf_usb_vid_descriptor_data, tvb, offset, descriptor_len-offset, ENC_NA);
1388 return descriptor_len;
1391 /*****************************************************************************/
1394 * Dissector for video class-specific endpoint descriptor.
1396 * @param parent_tree the protocol tree to be the parent of the descriptor subtree
1397 * @param tvb the tv_buff with the (remaining) packet data
1398 * On entry the gaze is set to the descriptor length field.
1399 * @param descriptor_len Length of the descriptor to dissect
1401 * @return offset within tvb at which dissection should continue
1404 dissect_usb_video_endpoint_descriptor(proto_tree *parent_tree, tvbuff_t *tvb,
1405 guint8 descriptor_len)
1407 proto_tree *tree = NULL;
1411 subtype = tvb_get_guint8(tvb, offset+2);
1415 const gchar* subtype_str;
1417 subtype_str = val_to_str(subtype, vc_ep_descriptor_subtypes, "Unknown (0x%x)");
1418 tree = proto_tree_add_subtree_format(parent_tree, tvb, offset, descriptor_len,
1419 ett_descriptor_video_endpoint, NULL, "VIDEO CONTROL ENDPOINT DESCRIPTOR [%s]",
1423 dissect_usb_descriptor_header(tree, tvb, offset, &vid_descriptor_type_vals_ext);
1424 proto_tree_add_item(tree, hf_usb_vid_epdesc_subtype, tvb, offset+2, 1, ENC_LITTLE_ENDIAN);
1427 if (subtype == EP_INTERRUPT)
1429 proto_tree_add_item(tree, hf_usb_vid_epdesc_max_transfer_sz, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1433 /* Soak up descriptor bytes beyond those we know how to dissect */
1434 if (offset < descriptor_len)
1435 proto_tree_add_item(tree, hf_usb_vid_descriptor_data, tvb, offset, descriptor_len-offset, ENC_NA);
1437 return descriptor_len;
1441 * Registered dissector for video class-specific descriptors
1443 * @param tvb the tv_buff with the (remaining) packet data
1444 * On entry the gaze is set to the descriptor length field.
1445 * @param pinfo the packet info of this packet (additional info)
1446 * @param tree the protocol tree to be built or NULL
1447 * @param data Not used
1449 * @return 0 no class specific dissector was found
1450 * @return <0 not enough data
1451 * @return >0 amount of data in the descriptor
1454 dissect_usb_vid_descriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1457 guint8 descriptor_len;
1458 guint8 descriptor_type;
1459 gint bytes_available;
1460 usb_conv_info_t *usb_conv_info = (usb_conv_info_t *)data;
1464 descriptor_len = tvb_get_guint8(tvb, offset);
1465 descriptor_type = tvb_get_guint8(tvb, offset+1);
1467 bytes_available = tvb_captured_length_remaining(tvb, offset);
1468 desc_tvb = tvb_new_subset_length_caplen(tvb, 0, bytes_available, descriptor_len);
1470 if (descriptor_type == CS_ENDPOINT)
1472 offset = dissect_usb_video_endpoint_descriptor(tree, desc_tvb,
1475 else if (descriptor_type == CS_INTERFACE)
1477 if (usb_conv_info && usb_conv_info->interfaceSubclass == SC_VIDEOCONTROL)
1479 offset = dissect_usb_video_control_interface_descriptor(tree, desc_tvb,
1481 pinfo, usb_conv_info);
1483 else if (usb_conv_info && usb_conv_info->interfaceSubclass == SC_VIDEOSTREAMING)
1485 offset = dissect_usb_video_streaming_interface_descriptor(tree, desc_tvb,
1489 /* else not something we recognize, just return offset = 0 */
1494 /*****************************************************************************/
1495 /* CONTROL TRANSFERS */
1496 /*****************************************************************************/
1499 * Dissect GET/SET transactions on the Video Probe and Commit controls.
1501 * @param parent_tree protocol tree to which the probe/commit subtree should be added
1502 * @param tvb the tv_buff with the (remaining) packet data
1503 * @param offset where in tvb to begin dissection.
1504 * On entry this refers to the probe/commit bmHint field.
1506 * @return offset within tvb at which dissection should continue
1509 dissect_usb_vid_probe(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1513 static const int *hint_bits[] = {
1514 &hf_usb_vid_probe_hint_D[0],
1515 &hf_usb_vid_probe_hint_D[1],
1516 &hf_usb_vid_probe_hint_D[2],
1517 &hf_usb_vid_probe_hint_D[3],
1518 &hf_usb_vid_probe_hint_D[4],
1522 DISSECTOR_ASSERT(array_length(hint_bits) == (1+array_length(hf_usb_vid_probe_hint_D)));
1524 tree = proto_tree_add_subtree(parent_tree, tvb, offset, -1, ett_video_probe, NULL, "Probe/Commit Info");
1526 proto_tree_add_bitmask(tree, tvb, offset, hf_usb_vid_probe_hint,
1527 ett_probe_hint, hint_bits, ENC_LITTLE_ENDIAN);
1529 proto_tree_add_item(tree, hf_usb_vid_format_index, tvb, offset+2, 1, ENC_LITTLE_ENDIAN);
1530 proto_tree_add_item(tree, hf_usb_vid_frame_index, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
1531 proto_tree_add_item(tree, hf_usb_vid_frame_interval, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
1532 proto_tree_add_item(tree, hf_usb_vid_probe_key_frame_rate, tvb, offset+8, 2, ENC_LITTLE_ENDIAN);
1533 proto_tree_add_item(tree, hf_usb_vid_probe_p_frame_rate, tvb, offset+10, 2, ENC_LITTLE_ENDIAN);
1534 proto_tree_add_item(tree, hf_usb_vid_probe_comp_quality, tvb, offset+12, 2, ENC_LITTLE_ENDIAN);
1535 proto_tree_add_item(tree, hf_usb_vid_probe_comp_window, tvb, offset+14, 2, ENC_LITTLE_ENDIAN);
1536 proto_tree_add_item(tree, hf_usb_vid_probe_delay, tvb, offset+16, 2, ENC_LITTLE_ENDIAN);
1537 proto_tree_add_item(tree, hf_usb_vid_probe_max_frame_sz, tvb, offset+18, 4, ENC_LITTLE_ENDIAN);
1538 proto_tree_add_item(tree, hf_usb_vid_probe_max_payload_sz, tvb, offset+22, 4, ENC_LITTLE_ENDIAN);
1541 /* UVC 1.1 fields */
1542 if (tvb_reported_length_remaining(tvb, offset) > 0)
1544 static const int *framing_bits[] = {
1545 &hf_usb_vid_probe_framing_D[0],
1546 &hf_usb_vid_probe_framing_D[1],
1550 DISSECTOR_ASSERT(array_length(framing_bits) == (1+array_length(hf_usb_vid_probe_framing_D)));
1552 proto_tree_add_item(tree, hf_usb_vid_probe_clock_freq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1555 proto_tree_add_bitmask(tree, tvb, offset, hf_usb_vid_probe_framing,
1556 ett_probe_framing, framing_bits, ENC_NA);
1559 proto_tree_add_item(tree, hf_usb_vid_probe_preferred_ver, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1560 proto_tree_add_item(tree, hf_usb_vid_probe_min_ver, tvb, offset+1, 1, ENC_LITTLE_ENDIAN);
1561 proto_tree_add_item(tree, hf_usb_vid_probe_max_ver, tvb, offset+2, 1, ENC_LITTLE_ENDIAN);
1569 * Fetch the table that describes known control selectors for the specified unit/terminal.
1571 * @param entity_id Unit or terminal of interest
1572 * @param usb_conv_info Information about the interface the entity is part of
1574 * @return Table describing control selectors for the specified entity (may be NULL)
1576 static value_string_ext*
1577 get_control_selector_values(guint8 entity_id, usb_conv_info_t *usb_conv_info)
1579 video_conv_info_t *video_conv_info;
1580 video_entity_t *entity = NULL;
1581 value_string_ext *selectors = NULL;
1583 if (usb_conv_info == NULL)
1586 video_conv_info = (video_conv_info_t *)usb_conv_info->class_data;
1587 if (video_conv_info)
1588 entity = (video_entity_t*) wmem_tree_lookup32(video_conv_info->entities, entity_id);
1592 /* Interface Request*/
1593 switch (usb_conv_info->interfaceSubclass)
1595 case SC_VIDEOCONTROL:
1596 selectors = &cs_control_interface_ext;
1599 case SC_VIDEOSTREAMING:
1600 selectors = &cs_streaming_interface_ext;
1609 switch (entity->subtype)
1611 case VC_INPUT_TERMINAL:
1612 if (entity->terminalType == ITT_CAMERA)
1614 selectors = &cs_camera_terminal_ext;
1618 case VC_PROCESSING_UNIT:
1619 selectors = &cs_processing_unit_ext;
1622 case VC_SELECTOR_UNIT:
1623 selectors = &cs_selector_unit_ext;
1635 * Fetch the name of an entity's control.
1637 * @param entity_id Unit or terminal of interest
1638 * @param control_sel Control of interest
1639 * @param usb_conv_info Information about the interface the entity is part of
1641 * @return Table describing control selectors for the specified entity (may be NULL)
1644 get_control_selector_name(guint8 entity_id, guint8 control_sel, usb_conv_info_t *usb_conv_info)
1646 const gchar *control_name = NULL;
1647 value_string_ext *selectors = NULL;
1649 selectors = get_control_selector_values(entity_id, usb_conv_info);
1652 control_name = try_val_to_str_ext(control_sel, selectors);
1654 return control_name;
1657 /* Dissect the response to a GET INFO request */
1659 dissect_usb_vid_control_info(proto_tree *tree, tvbuff_t *tvb, int offset)
1661 static const int *capability_bits[] = {
1662 &hf_usb_vid_control_info_D[0],
1663 &hf_usb_vid_control_info_D[1],
1664 &hf_usb_vid_control_info_D[2],
1665 &hf_usb_vid_control_info_D[3],
1666 &hf_usb_vid_control_info_D[4],
1667 &hf_usb_vid_control_info_D[5],
1668 &hf_usb_vid_control_info_D[6],
1672 DISSECTOR_ASSERT(array_length(capability_bits) == (1+array_length(hf_usb_vid_control_info_D)));
1674 proto_tree_add_bitmask(tree, tvb, offset, hf_usb_vid_control_info,
1675 ett_control_capabilities, capability_bits, ENC_NA);
1680 /* Dissect all remaining bytes in the tvb as a specified type of UVC value.
1681 * These are displayed as an unsigned integer where possible, otherwise just as
1684 * @param tree the protocol tree to which an item will be added
1685 * @param tvb the tv_buff with the (remaining) packet data
1686 * @param offset How far into tvb the value data begins
1687 * @param request Identifies type of value - either bRequest from a CONTROL
1688 * transfer (i.e., USB_SETUP_GET_MAX), or bValue from an
1689 * INTERRUPT transfer (i.e., CONTROL_CHANGE_MAX).
1692 dissect_usb_vid_control_value(proto_tree *tree, tvbuff_t *tvb, int offset, guint8 request)
1695 const char *fallback_name;
1700 case USB_SETUP_GET_DEF:
1701 hf = hf_usb_vid_control_default;
1702 fallback_name = "Default Value";
1705 case USB_SETUP_GET_MIN:
1706 case CONTROL_CHANGE_MIN:
1707 hf = hf_usb_vid_control_min;
1708 fallback_name = "Min Value";
1711 case USB_SETUP_GET_MAX:
1712 case CONTROL_CHANGE_MAX:
1713 hf = hf_usb_vid_control_max;
1714 fallback_name = "Max Value";
1717 case USB_SETUP_GET_RES:
1718 hf = hf_usb_vid_control_res;
1719 fallback_name = "Resolution";
1722 case USB_SETUP_GET_CUR:
1723 case USB_SETUP_SET_CUR:
1724 case CONTROL_CHANGE_VALUE:
1725 hf = hf_usb_vid_control_cur;
1726 fallback_name = "Current Value";
1729 /* @todo UVC 1.5 USB_SETUP_x_ALL?
1730 * They are poorly specified.
1735 fallback_name = "Value";
1739 value_size = tvb_reported_length_remaining(tvb, offset);
1743 header_field_info *hfinfo;
1744 hfinfo = proto_registrar_get_nth(hf);
1745 DISSECTOR_ASSERT(IS_FT_INT(hfinfo->type) || IS_FT_UINT(hfinfo->type));
1748 if ((hf != -1) && (value_size <= 4))
1750 proto_tree_add_item(tree, hf, tvb, offset, value_size, ENC_LITTLE_ENDIAN);
1754 /* @todo Display as FT_BYTES with a big-endian disclaimer?
1755 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7933
1757 proto_tree_add_bytes_format(tree, hf_usb_vid_control_value, tvb, offset, value_size, NULL, "%s", fallback_name);
1762 * Dissect video class GET/SET transactions.
1764 * @param pinfo Information associated with the packet being dissected
1765 * @param tree protocol tree to which fields should be added
1766 * @param tvb the tv_buff with the (remaining) packet data
1767 * @param offset where in tvb to begin dissection.
1768 * On entry this refers to the bRequest field of the SETUP
1770 * @param is_request true if the packet is host-to-device,
1771 * false if device-to-host
1772 * @param usb_trans_info Information specific to this request/response pair
1773 * @param usb_conv_info Information about the conversation with the host
1776 dissect_usb_vid_get_set(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
1777 int offset, gboolean is_request,
1778 usb_trans_info_t *usb_trans_info,
1779 usb_conv_info_t *usb_conv_info)
1781 const gchar *short_name = NULL;
1785 entity_id = usb_trans_info->setup.wIndex >> 8;
1786 control_sel = usb_trans_info->setup.wValue >> 8;
1788 /* Display something informative in the INFO column */
1789 col_append_str(pinfo->cinfo, COL_INFO, " [");
1790 short_name = get_control_selector_name(entity_id, control_sel, usb_conv_info);
1793 col_append_str(pinfo->cinfo, COL_INFO, short_name);
1796 short_name = "Unknown";
1800 col_append_fstr(pinfo->cinfo, COL_INFO, "Interface %u control 0x%x",
1801 usb_conv_info->interfaceNum, control_sel);
1805 col_append_fstr(pinfo->cinfo, COL_INFO, "Unit %u control 0x%x",
1806 entity_id, control_sel);
1810 col_append_str(pinfo->cinfo, COL_INFO, "]");
1811 col_set_fence(pinfo->cinfo, COL_INFO);
1813 /* Add information on request context,
1814 * as GENERATED fields if not directly available (for filtering)
1818 /* Move gaze to control selector (MSB of wValue) */
1820 proto_tree_add_uint_format_value(tree, hf_usb_vid_control_selector, tvb,
1821 offset, 1, control_sel, "%s (0x%02x)", short_name, control_sel);
1824 proto_tree_add_item(tree, hf_usb_vid_control_interface, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1827 proto_tree_add_item(tree, hf_usb_vid_control_entity, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1830 proto_tree_add_item(tree, hf_usb_vid_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1837 ti = proto_tree_add_uint(tree, hf_usb_vid_control_interface, tvb, 0, 0,
1838 usb_trans_info->setup.wIndex & 0xFF);
1839 proto_item_set_generated(ti);
1841 ti = proto_tree_add_uint(tree, hf_usb_vid_control_entity, tvb, 0, 0, entity_id);
1842 proto_item_set_generated(ti);
1844 ti = proto_tree_add_uint_format_value(tree, hf_usb_vid_control_selector, tvb,
1845 0, 0, control_sel, "%s (0x%02x)", short_name, control_sel);
1846 proto_item_set_generated(ti);
1849 if (!is_request || (usb_trans_info->setup.request == USB_SETUP_SET_CUR))
1851 gint value_size = tvb_reported_length_remaining(tvb, offset);
1853 if (value_size != 0)
1855 if ((entity_id == 0) && (usb_conv_info->interfaceSubclass == SC_VIDEOSTREAMING))
1857 if ((control_sel == VS_PROBE_CONTROL) || (control_sel == VS_COMMIT_CONTROL))
1859 int old_offset = offset;
1860 offset = dissect_usb_vid_probe(tree, tvb, offset);
1861 value_size -= (offset - old_offset);
1866 if (usb_trans_info->setup.request == USB_SETUP_GET_INFO)
1868 dissect_usb_vid_control_info(tree, tvb, offset);
1872 else if (usb_trans_info->setup.request == USB_SETUP_GET_LEN)
1874 proto_tree_add_item(tree, hf_usb_vid_control_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1878 else if ( (usb_trans_info->setup.request == USB_SETUP_GET_CUR)
1880 && (usb_conv_info->interfaceSubclass == SC_VIDEOCONTROL)
1881 && (control_sel == VC_REQUEST_ERROR_CODE_CONTROL))
1883 proto_tree_add_item(tree, hf_usb_vid_request_error, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1889 dissect_usb_vid_control_value(tree, tvb, offset, usb_trans_info->setup.request);
1890 offset += value_size;
1897 proto_tree_add_item(tree, hf_usb_vid_control_data, tvb, offset, -1, ENC_NA);
1898 offset += value_size;
1906 /* Table for dispatch of video class SETUP transactions based on bRequest.
1907 * At the moment this is overkill since the same function handles all defined
1910 typedef int (*usb_setup_dissector)(packet_info *pinfo, proto_tree *tree,
1911 tvbuff_t *tvb, int offset,
1912 gboolean is_request,
1913 usb_trans_info_t *usb_trans_info,
1914 usb_conv_info_t *usb_conv_info);
1916 typedef struct _usb_setup_dissector_table_t
1919 usb_setup_dissector dissector;
1920 } usb_setup_dissector_table_t;
1922 static const usb_setup_dissector_table_t setup_dissectors[] = {
1923 {USB_SETUP_SET_CUR, dissect_usb_vid_get_set},
1924 {USB_SETUP_SET_CUR_ALL, dissect_usb_vid_get_set},
1925 {USB_SETUP_GET_CUR, dissect_usb_vid_get_set},
1926 {USB_SETUP_GET_MIN, dissect_usb_vid_get_set},
1927 {USB_SETUP_GET_MAX, dissect_usb_vid_get_set},
1928 {USB_SETUP_GET_RES, dissect_usb_vid_get_set},
1929 {USB_SETUP_GET_LEN, dissect_usb_vid_get_set},
1930 {USB_SETUP_GET_INFO, dissect_usb_vid_get_set},
1931 {USB_SETUP_GET_DEF, dissect_usb_vid_get_set},
1932 {USB_SETUP_GET_CUR_ALL, dissect_usb_vid_get_set},
1933 {USB_SETUP_GET_MIN_ALL, dissect_usb_vid_get_set},
1934 {USB_SETUP_GET_MAX_ALL, dissect_usb_vid_get_set},
1935 {USB_SETUP_GET_RES_ALL, dissect_usb_vid_get_set},
1939 static const value_string setup_request_names_vals[] = {
1940 {USB_SETUP_SET_CUR, "SET CUR"},
1941 {USB_SETUP_SET_CUR_ALL, "SET CUR ALL"},
1942 {USB_SETUP_GET_CUR, "GET CUR"},
1943 {USB_SETUP_GET_MIN, "GET MIN"},
1944 {USB_SETUP_GET_MAX, "GET MAX"},
1945 {USB_SETUP_GET_RES, "GET RES"},
1946 {USB_SETUP_GET_LEN, "GET LEN"},
1947 {USB_SETUP_GET_INFO, "GET INFO"},
1948 {USB_SETUP_GET_DEF, "GET DEF"},
1949 {USB_SETUP_GET_CUR_ALL, "GET CUR ALL"},
1950 {USB_SETUP_GET_MIN_ALL, "GET MIN ALL"},
1951 {USB_SETUP_GET_MAX_ALL, "GET MAX ALL"},
1952 {USB_SETUP_GET_RES_ALL, "GET RES ALL"},
1953 {USB_SETUP_GET_DEF_ALL, "GET DEF ALL"},
1957 /* Registered dissector for video class-specific control requests.
1958 * Dispatch to an appropriate dissector function.
1960 * @param tvb the tv_buff with the (remaining) packet data.
1961 * On entry, the gaze is set to SETUP bRequest field.
1962 * @param pinfo the packet info of this packet (additional info)
1963 * @param tree the protocol tree to be built or NULL
1964 * @param data Not used
1966 * @return 0 no class specific dissector was found
1967 * @return <0 not enough data
1968 * @return >0 amount of data in the descriptor
1971 dissect_usb_vid_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1973 gboolean is_request = (pinfo->srcport == NO_ENDPOINT);
1974 usb_conv_info_t *usb_conv_info;
1975 usb_trans_info_t *usb_trans_info;
1977 usb_setup_dissector dissector = NULL;
1978 const usb_setup_dissector_table_t *tmp;
1980 /* Reject the packet if data or usb_trans_info are NULL */
1981 if (data == NULL || ((usb_conv_info_t *)data)->usb_trans_info == NULL)
1983 usb_conv_info = (usb_conv_info_t *)data;
1984 usb_trans_info = usb_conv_info->usb_trans_info;
1986 /* See if we can find a class specific dissector for this request */
1987 for (tmp=setup_dissectors; tmp->dissector; tmp++)
1989 if (tmp->request == usb_trans_info->setup.request)
1991 dissector = tmp->dissector;
1995 /* No we could not find any class specific dissector for this request
1996 * return FALSE and let USB try any of the standard requests.
2001 col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBVIDEO");
2002 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
2003 val_to_str(usb_trans_info->setup.request, setup_request_names_vals, "Unknown type %x"),
2004 is_request?"Request ":"Response");
2008 proto_tree_add_item(tree, hf_usb_vid_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2012 offset = dissector(pinfo, tree, tvb, offset, is_request, usb_trans_info, usb_conv_info);
2016 /* Registered dissector for video class-specific URB_INTERRUPT
2018 * @param tvb the tv_buff with the (remaining) packet data
2019 * @param pinfo the packet info of this packet (additional info)
2020 * @param tree the protocol tree to be built or NULL
2021 * @param data Unused API parameter
2023 * @return 0 no class specific dissector was found
2024 * @return <0 not enough data
2025 * @return >0 amount of data in the descriptor
2028 dissect_usb_vid_interrupt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2030 usb_conv_info_t *usb_conv_info;
2031 gint bytes_available;
2034 usb_conv_info = (usb_conv_info_t *)data;
2035 bytes_available = tvb_reported_length_remaining(tvb, offset);
2037 col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBVIDEO");
2039 if (bytes_available > 0)
2041 guint8 originating_interface;
2042 guint8 originating_entity;
2044 originating_interface = tvb_get_guint8(tvb, offset) & INT_ORIGINATOR_MASK;
2045 proto_tree_add_item(tree, hf_usb_vid_interrupt_bStatusType, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2048 originating_entity = tvb_get_guint8(tvb, offset);
2049 proto_tree_add_item(tree, hf_usb_vid_interrupt_bOriginator, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2052 if (originating_interface == INT_VIDEOCONTROL)
2056 const gchar *control_name;
2058 proto_tree_add_item(tree, hf_usb_vid_control_interrupt_bEvent, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2061 control_sel = tvb_get_guint8(tvb, offset);
2062 control_name = get_control_selector_name(originating_entity, control_sel, usb_conv_info);
2064 control_name = "Unknown";
2066 proto_tree_add_uint_format_value(tree, hf_usb_vid_control_selector, tvb,
2067 offset, 1, control_sel, "%s (0x%02x)",
2068 control_name, control_sel);
2071 attribute = tvb_get_guint8(tvb, offset);
2072 proto_tree_add_item(tree, hf_usb_vid_interrupt_bAttribute, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2077 case CONTROL_CHANGE_FAILURE:
2078 proto_tree_add_item(tree, hf_usb_vid_request_error, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2082 case CONTROL_CHANGE_INFO:
2083 offset = dissect_usb_vid_control_info(tree, tvb, offset);
2086 case CONTROL_CHANGE_VALUE:
2087 case CONTROL_CHANGE_MIN:
2088 case CONTROL_CHANGE_MAX:
2089 dissect_usb_vid_control_value(tree, tvb, offset, attribute);
2090 offset += tvb_reported_length_remaining(tvb, offset);
2094 proto_tree_add_item(tree, hf_usb_vid_value_data, tvb, offset, -1, ENC_NA);
2095 offset += tvb_reported_length_remaining(tvb, offset);
2099 else if (originating_interface == INT_VIDEOSTREAMING)
2111 proto_register_usb_vid(void)
2113 static hf_register_info hf[] = {
2115 { &hf_usb_vid_request,
2116 { "bRequest", "usbvideo.setup.bRequest", FT_UINT8, BASE_HEX, VALS(setup_request_names_vals), 0x0,
2120 { &hf_usb_vid_length,
2121 { "wLength", "usbvideo.setup.wLength", FT_UINT16, BASE_DEC, NULL, 0x0,
2125 /***** Request Error Control *****/
2126 { &hf_usb_vid_request_error,
2127 { "bRequestErrorCode", "usbvideo.reqerror.code",
2128 FT_UINT8, BASE_DEC | BASE_EXT_STRING,
2129 &request_error_codes_ext, 0,
2130 "Request Error Code", HFILL }
2133 /***** Unit/Terminal Controls *****/
2134 { &hf_usb_vid_control_selector,
2135 { "Control Selector", "usbvideo.control.selector", FT_UINT8, BASE_HEX, NULL, 0x0,
2136 "ID of the control within its entity", HFILL }
2139 { &hf_usb_vid_control_entity,
2140 { "Entity", "usbvideo.control.entity", FT_UINT8, BASE_HEX, NULL, 0x0,
2141 "Unit or terminal to which the control belongs", HFILL }
2144 { &hf_usb_vid_control_interface,
2145 { "Interface", "usbvideo.control.interface", FT_UINT8, BASE_HEX, NULL, 0x0,
2146 "Interface to which the control belongs", HFILL }
2149 { &hf_usb_vid_control_info,
2150 { "Info (Capabilities/State)", "usbvideo.control.info",
2151 FT_UINT8, BASE_HEX, NULL, 0,
2152 "Control capabilities and current state", HFILL }
2155 { &hf_usb_vid_control_info_D[0],
2156 { "Supports GET", "usbvideo.control.info.D0",
2157 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<0),
2161 { &hf_usb_vid_control_info_D[1],
2162 { "Supports SET", "usbvideo.control.info.D1",
2163 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<1),
2167 { &hf_usb_vid_control_info_D[2],
2168 { "Disabled due to automatic mode", "usbvideo.control.info.D2",
2169 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<2),
2173 { &hf_usb_vid_control_info_D[3],
2174 { "Autoupdate", "usbvideo.control.info.D3",
2175 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<3),
2179 { &hf_usb_vid_control_info_D[4],
2180 { "Asynchronous", "usbvideo.control.info.D4",
2181 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<4),
2185 { &hf_usb_vid_control_info_D[5],
2186 { "Disabled due to incompatibility with Commit state", "usbvideo.control.info.D5",
2187 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<5),
2191 { &hf_usb_vid_control_info_D[6],
2192 { "Reserved", "usbvideo.control.info.D6",
2193 FT_UINT8, BASE_HEX, NULL, (3<<6),
2197 { &hf_usb_vid_control_length,
2198 { "Control Length", "usbvideo.control.len",
2199 FT_UINT16, BASE_DEC, NULL, 0,
2200 "Control size in bytes", HFILL }
2203 { &hf_usb_vid_control_default,
2204 { "Default value", "usbvideo.control.value.default",
2205 FT_UINT32, BASE_DEC_HEX, NULL, 0,
2209 { &hf_usb_vid_control_min,
2210 { "Minimum value", "usbvideo.control.value.min",
2211 FT_UINT32, BASE_DEC_HEX, NULL, 0,
2215 { &hf_usb_vid_control_max,
2216 { "Maximum value", "usbvideo.control.value.max",
2217 FT_UINT32, BASE_DEC_HEX, NULL, 0,
2221 { &hf_usb_vid_control_res,
2222 { "Resolution", "usbvideo.control.value.res",
2223 FT_UINT32, BASE_DEC_HEX, NULL, 0,
2227 { &hf_usb_vid_control_cur,
2228 { "Current value", "usbvideo.control.value.cur",
2229 FT_UINT32, BASE_DEC_HEX, NULL, 0,
2233 /***** Terminal Descriptors *****/
2235 /* @todo Decide whether to unify .name fields */
2236 { &hf_usb_vid_control_ifdesc_iTerminal,
2237 { "iTerminal", "usbvideo.terminal.name", FT_UINT8, BASE_DEC, NULL, 0x0,
2238 "String Descriptor describing this terminal", HFILL }
2241 /* @todo Decide whether to unify .terminal.id and .unit.id under .entityID */
2242 { &hf_usb_vid_control_ifdesc_terminal_id,
2243 { "bTerminalID", "usbvideo.terminal.id", FT_UINT8, BASE_DEC, NULL, 0x0,
2247 { &hf_usb_vid_control_ifdesc_terminal_type,
2248 { "wTerminalType", "usbvideo.terminal.type",
2249 FT_UINT16, BASE_HEX | BASE_EXT_STRING, &vc_terminal_types_ext, 0,
2253 { &hf_usb_vid_control_ifdesc_assoc_terminal,
2254 { "bAssocTerminal", "usbvideo.terminal.assocTerminal", FT_UINT8, BASE_DEC, NULL, 0x0,
2255 "Associated Terminal", HFILL }
2258 /***** Camera Terminal Descriptor *****/
2260 { &hf_usb_vid_cam_objective_focal_len_min,
2261 { "wObjectiveFocalLengthMin", "usbvideo.camera.objectiveFocalLengthMin",
2262 FT_UINT16, BASE_DEC, NULL, 0,
2263 "Minimum Focal Length for Optical Zoom", HFILL }
2266 { &hf_usb_vid_cam_objective_focal_len_max,
2267 { "wObjectiveFocalLengthMax", "usbvideo.camera.objectiveFocalLengthMax",
2268 FT_UINT16, BASE_DEC, NULL, 0,
2269 "Minimum Focal Length for Optical Zoom", HFILL }
2272 { &hf_usb_vid_cam_ocular_focal_len,
2273 { "wOcularFocalLength", "usbvideo.camera.ocularFocalLength",
2274 FT_UINT16, BASE_DEC, NULL, 0,
2275 "Ocular Focal Length for Optical Zoom", HFILL }
2278 { &hf_usb_vid_cam_control_D[0],
2279 { "Scanning Mode", "usbvideo.camera.control.D0",
2281 array_length(hf_usb_vid_cam_control_D),
2282 TFS(&tfs_yes_no), (1<<0),
2286 { &hf_usb_vid_cam_control_D[1],
2287 { "Auto Exposure Mode", "usbvideo.camera.control.D1",
2289 array_length(hf_usb_vid_cam_control_D),
2290 TFS(&tfs_yes_no), (1<<1),
2294 { &hf_usb_vid_cam_control_D[2],
2295 { "Auto Exposure Priority", "usbvideo.camera.control.D2",
2297 array_length(hf_usb_vid_cam_control_D),
2298 TFS(&tfs_yes_no), (1<<2),
2302 { &hf_usb_vid_cam_control_D[3],
2303 { "Exposure Time (Absolute)", "usbvideo.camera.control.D3",
2305 array_length(hf_usb_vid_cam_control_D),
2306 TFS(&tfs_yes_no), (1<<3),
2310 { &hf_usb_vid_cam_control_D[4],
2311 { "Exposure Time (Relative)", "usbvideo.camera.control.D4",
2313 array_length(hf_usb_vid_cam_control_D),
2314 TFS(&tfs_yes_no), (1<<4),
2318 { &hf_usb_vid_cam_control_D[5],
2319 { "Focus (Absolute)", "usbvideo.camera.control.D5",
2321 array_length(hf_usb_vid_cam_control_D),
2322 TFS(&tfs_yes_no), (1<<5),
2326 { &hf_usb_vid_cam_control_D[6],
2327 { "Focus (Relative)", "usbvideo.camera.control.D6",
2329 array_length(hf_usb_vid_cam_control_D),
2330 TFS(&tfs_yes_no), (1<<6),
2334 { &hf_usb_vid_cam_control_D[7],
2335 { "Iris (Absolute)", "usbvideo.camera.control.D7",
2337 array_length(hf_usb_vid_cam_control_D),
2338 TFS(&tfs_yes_no), (1<<7),
2342 { &hf_usb_vid_cam_control_D[8],
2343 { "Iris (Relative)", "usbvideo.camera.control.D8",
2345 array_length(hf_usb_vid_cam_control_D),
2346 TFS(&tfs_yes_no), (1<<8),
2350 { &hf_usb_vid_cam_control_D[9],
2351 { "Zoom (Absolute)", "usbvideo.camera.control.D9",
2353 array_length(hf_usb_vid_cam_control_D),
2354 TFS(&tfs_yes_no), (1<<9),
2358 { &hf_usb_vid_cam_control_D[10],
2359 { "Zoom (Relative)", "usbvideo.camera.control.D10",
2361 array_length(hf_usb_vid_cam_control_D),
2362 TFS(&tfs_yes_no), (1<<10),
2366 { &hf_usb_vid_cam_control_D[11],
2367 { "PanTilt (Absolute)", "usbvideo.camera.control.D11",
2369 array_length(hf_usb_vid_cam_control_D),
2370 TFS(&tfs_yes_no), (1<<11),
2374 { &hf_usb_vid_cam_control_D[12],
2375 { "PanTilt (Relative)", "usbvideo.camera.control.D12",
2377 array_length(hf_usb_vid_cam_control_D),
2378 TFS(&tfs_yes_no), (1<<12),
2382 { &hf_usb_vid_cam_control_D[13],
2383 { "Roll (Absolute)", "usbvideo.camera.control.D13",
2385 array_length(hf_usb_vid_cam_control_D),
2386 TFS(&tfs_yes_no), (1<<13),
2390 { &hf_usb_vid_cam_control_D[14],
2391 { "Roll (Relative)", "usbvideo.camera.control.D14",
2393 array_length(hf_usb_vid_cam_control_D),
2394 TFS(&tfs_yes_no), (1<<14),
2398 { &hf_usb_vid_cam_control_D[15],
2399 { "D15", "usbvideo.camera.control.D15",
2401 array_length(hf_usb_vid_cam_control_D),
2402 TFS(&tfs_yes_no), (1<<15),
2406 { &hf_usb_vid_cam_control_D[16],
2407 { "D16", "usbvideo.camera.control.D16",
2409 array_length(hf_usb_vid_cam_control_D),
2410 TFS(&tfs_yes_no), (1<<16),
2414 { &hf_usb_vid_cam_control_D[17],
2415 { "Auto Focus", "usbvideo.camera.control.D17",
2417 array_length(hf_usb_vid_cam_control_D),
2418 TFS(&tfs_yes_no), (1<<17),
2422 { &hf_usb_vid_cam_control_D[18],
2423 { "Privacy", "usbvideo.camera.control.D18",
2425 array_length(hf_usb_vid_cam_control_D),
2426 TFS(&tfs_yes_no), (1<<18),
2430 { &hf_usb_vid_cam_control_D[19],
2431 { "Focus (Simple)", "usbvideo.camera.control.D19",
2433 array_length(hf_usb_vid_cam_control_D),
2434 TFS(&tfs_yes_no), (1<<19),
2438 { &hf_usb_vid_cam_control_D[20],
2439 { "Window", "usbvideo.camera.control.D20",
2441 array_length(hf_usb_vid_cam_control_D),
2442 TFS(&tfs_yes_no), (1<<20),
2446 { &hf_usb_vid_cam_control_D[21],
2447 { "Region of Interest", "usbvideo.camera.control.D21",
2449 array_length(hf_usb_vid_cam_control_D),
2450 TFS(&tfs_yes_no), (1<<21),
2454 /***** Unit Descriptors *****/
2456 { &hf_usb_vid_control_ifdesc_unit_id,
2457 { "bUnitID", "usbvideo.unit.id", FT_UINT8, BASE_DEC, NULL, 0x0,
2461 { &hf_usb_vid_num_inputs,
2462 { "bNrInPins", "usbvideo.unit.numInputs",
2463 FT_UINT8, BASE_DEC, NULL, 0,
2464 "Number of input pins", HFILL }
2467 { &hf_usb_vid_sources,
2468 { "baSourceID", "usbvideo.unit.sources",
2469 FT_BYTES, BASE_NONE, NULL, 0,
2470 "Input entity IDs", HFILL }
2474 /***** Processing Unit Descriptor *****/
2476 { &hf_usb_vid_iProcessing,
2477 { "iProcessing", "usbvideo.processor.name", FT_UINT8, BASE_DEC, NULL, 0x0,
2478 "String Descriptor describing this terminal", HFILL }
2481 { &hf_usb_vid_proc_control_D[0],
2482 { "Brightness", "usbvideo.processor.control.D0",
2483 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<0),
2487 { &hf_usb_vid_proc_control_D[1],
2488 { "Contrast", "usbvideo.processor.control.D1",
2489 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<1),
2493 { &hf_usb_vid_proc_control_D[2],
2494 { "Hue", "usbvideo.processor.control.D2",
2495 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<2),
2499 { &hf_usb_vid_proc_control_D[3],
2500 { "Saturation", "usbvideo.processor.control.D3",
2501 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<3),
2505 { &hf_usb_vid_proc_control_D[4],
2506 { "Sharpness", "usbvideo.processor.control.D4",
2507 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<4),
2511 { &hf_usb_vid_proc_control_D[5],
2512 { "Gamma", "usbvideo.processor.control.D5",
2513 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<5),
2517 { &hf_usb_vid_proc_control_D[6],
2518 { "White Balance Temperature", "usbvideo.processor.control.D6",
2519 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<6),
2523 { &hf_usb_vid_proc_control_D[7],
2524 { "White Balance Component", "usbvideo.processor.control.D7",
2525 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<7),
2529 { &hf_usb_vid_proc_control_D[8],
2530 { "Backlight Compensation", "usbvideo.processor.control.D8",
2531 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<8),
2535 { &hf_usb_vid_proc_control_D[9],
2536 { "Gain", "usbvideo.processor.control.D9",
2537 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<9),
2541 { &hf_usb_vid_proc_control_D[10],
2542 { "Power Line Frequency", "usbvideo.processor.control.D10",
2543 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<10),
2547 { &hf_usb_vid_proc_control_D[11],
2548 { "Hue, Auto", "usbvideo.processor.control.D11",
2549 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<11),
2553 { &hf_usb_vid_proc_control_D[12],
2554 { "White Balance Temperature, Auto", "usbvideo.processor.control.D12",
2555 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<12),
2559 { &hf_usb_vid_proc_control_D[13],
2560 { "White Balance Component, Auto", "usbvideo.processor.control.D13",
2561 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<13),
2565 { &hf_usb_vid_proc_control_D[14],
2566 { "Digital Multiplier", "usbvideo.processor.control.D14",
2567 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<14),
2571 { &hf_usb_vid_proc_control_D[15],
2572 { "Digital Multiplier Limit", "usbvideo.processor.control.D15",
2573 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<15),
2577 { &hf_usb_vid_proc_control_D[16],
2578 { "Analog Video Standard", "usbvideo.processor.control.D16",
2579 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<16),
2583 { &hf_usb_vid_proc_control_D[17],
2584 { "Analog Video Lock Status", "usbvideo.processor.control.D17",
2585 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<17),
2589 { &hf_usb_vid_proc_control_D[18],
2590 { "Contrast, Auto", "usbvideo.processor.control.D18",
2591 FT_BOOLEAN, 24, TFS(&tfs_yes_no), (1<<18),
2595 { &hf_usb_vid_proc_standards,
2596 { "bmVideoStandards", "usbvideo.processor.standards",
2597 FT_UINT8, BASE_HEX, NULL, 0,
2598 "Supported analog video standards", HFILL }
2601 { &hf_usb_vid_proc_standards_D[0],
2602 { "None", "usbvideo.processor.standards.D0",
2603 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<0),
2607 { &hf_usb_vid_proc_standards_D[1],
2608 { "NTSC - 525/60", "usbvideo.processor.standards.D1",
2609 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<1),
2613 { &hf_usb_vid_proc_standards_D[2],
2614 { "PAL - 625/50", "usbvideo.processor.standards.D2",
2615 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<2),
2619 { &hf_usb_vid_proc_standards_D[3],
2620 { "SECAM - 625/50", "usbvideo.processor.standards.D3",
2621 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<3),
2625 { &hf_usb_vid_proc_standards_D[4],
2626 { "NTSC - 625/50", "usbvideo.processor.standards.D4",
2627 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<4),
2631 { &hf_usb_vid_proc_standards_D[5],
2632 { "PAL - 525/60", "usbvideo.processor.standards.D5",
2633 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<5),
2637 { &hf_usb_vid_max_multiplier,
2638 { "wMaxMultiplier", "usbvideo.processor.maxMultiplier",
2639 FT_UINT16, BASE_DEC, NULL, 0,
2640 "100 x max digital multiplication", HFILL }
2643 /***** Selector Unit Descriptor *****/
2645 { &hf_usb_vid_iSelector,
2646 { "iSelector", "usbvideo.selector.name", FT_UINT8, BASE_DEC, NULL, 0x0,
2647 "String Descriptor describing this terminal", HFILL }
2650 /***** Extension Unit Descriptor *****/
2652 { &hf_usb_vid_iExtension,
2653 { "iExtension", "usbvideo.extension.name", FT_UINT8, BASE_DEC, NULL, 0x0,
2654 "String Descriptor describing this terminal", HFILL }
2657 { &hf_usb_vid_exten_guid,
2658 { "guid", "usbvideo.extension.guid",
2659 FT_GUID, BASE_NONE, NULL, 0,
2660 "Identifier", HFILL }
2663 { &hf_usb_vid_exten_num_controls,
2664 { "bNumControls", "usbvideo.extension.numControls",
2665 FT_UINT8, BASE_DEC, NULL, 0,
2666 "Number of controls", HFILL }
2669 /***** Probe/Commit *****/
2671 { &hf_usb_vid_probe_hint,
2672 { "bmHint", "usbvideo.probe.hint",
2673 FT_UINT16, BASE_HEX, NULL, 0,
2674 "Fields to hold constant during negotiation", HFILL }
2677 { &hf_usb_vid_probe_hint_D[0],
2678 { "dwFrameInterval", "usbvideo.probe.hint.D0",
2679 FT_BOOLEAN, 5, TFS(&probe_hint_meaning), (1<<0),
2680 "Frame Rate", HFILL }
2682 { &hf_usb_vid_probe_hint_D[1],
2683 { "wKeyFrameRate", "usbvideo.probe.hint.D1",
2684 FT_BOOLEAN, 5, TFS(&probe_hint_meaning), (1<<1),
2685 "Key Frame Rate", HFILL }
2687 { &hf_usb_vid_probe_hint_D[2],
2688 { "wPFrameRate", "usbvideo.probe.hint.D2",
2689 FT_BOOLEAN, 5, TFS(&probe_hint_meaning), (1<<2),
2690 "P-Frame Rate", HFILL }
2692 { &hf_usb_vid_probe_hint_D[3],
2693 { "wCompQuality", "usbvideo.probe.hint.D3",
2694 FT_BOOLEAN, 5, TFS(&probe_hint_meaning), (1<<3),
2695 "Compression Quality", HFILL }
2697 { &hf_usb_vid_probe_hint_D[4],
2698 { "wCompWindowSize", "usbvideo.probe.hint.D4",
2699 FT_BOOLEAN, 5, TFS(&probe_hint_meaning), (1<<4),
2700 "Compression Window Size", HFILL }
2703 { &hf_usb_vid_probe_key_frame_rate,
2704 { "wKeyFrameRate", "usbvideo.probe.keyFrameRate",
2705 FT_UINT16, BASE_DEC, NULL, 0,
2706 "Key frame rate", HFILL }
2709 { &hf_usb_vid_probe_p_frame_rate,
2710 { "wPFrameRate", "usbvideo.probe.pFrameRate",
2711 FT_UINT16, BASE_DEC, NULL, 0,
2712 "P frame rate", HFILL }
2715 { &hf_usb_vid_probe_comp_quality,
2716 { "wCompQuality", "usbvideo.probe.compQuality",
2717 FT_UINT16, BASE_DEC, NULL, 0,
2718 "Compression quality [0-10000]", HFILL }
2721 { &hf_usb_vid_probe_comp_window,
2722 { "wCompWindow", "usbvideo.probe.compWindow",
2723 FT_UINT16, BASE_DEC, NULL, 0,
2724 "Window size for average bit rate control", HFILL }
2726 { &hf_usb_vid_probe_delay,
2727 { "wDelay", "usbvideo.probe.delay",
2728 FT_UINT16, BASE_DEC, NULL, 0,
2729 "Latency in ms from capture to USB", HFILL }
2731 { &hf_usb_vid_probe_max_frame_sz,
2732 { "dwMaxVideoFrameSize", "usbvideo.probe.maxVideoFrameSize",
2733 FT_UINT32, BASE_DEC, NULL, 0,
2736 { &hf_usb_vid_probe_max_payload_sz,
2737 { "dwMaxPayloadTransferSize", "usbvideo.probe.maxPayloadTransferSize",
2738 FT_UINT32, BASE_DEC, NULL, 0,
2741 { &hf_usb_vid_probe_clock_freq,
2742 { "dwClockFrequency", "usbvideo.probe.clockFrequency",
2743 FT_UINT32, BASE_DEC, NULL, 0,
2744 "Device clock frequency in Hz", HFILL }
2747 { &hf_usb_vid_probe_framing,
2748 { "bmFramingInfo", "usbvideo.probe.framing",
2749 FT_UINT16, BASE_HEX, NULL, 0,
2753 { &hf_usb_vid_probe_framing_D[0],
2754 { "Frame ID required", "usbvideo.probe.framing.D0",
2755 FT_BOOLEAN, 2, TFS(&tfs_yes_no), (1<<0),
2758 { &hf_usb_vid_probe_framing_D[1],
2759 { "EOF utilized", "usbvideo.probe.framing.D1",
2760 FT_BOOLEAN, 2, TFS(&tfs_yes_no), (1<<1),
2764 { &hf_usb_vid_probe_preferred_ver,
2765 { "bPreferredVersion", "usbvideo.probe.preferredVersion",
2766 FT_UINT8, BASE_DEC, NULL, 0,
2767 "Preferred payload format version", HFILL }
2769 { &hf_usb_vid_probe_min_ver,
2770 { "bMinVersion", "usbvideo.probe.minVersion",
2771 FT_UINT8, BASE_DEC, NULL, 0,
2772 "Min supported payload format version", HFILL }
2774 { &hf_usb_vid_probe_max_ver,
2775 { "bPreferredVersion", "usbvideo.probe.maxVer",
2776 FT_UINT8, BASE_DEC, NULL, 0,
2777 "Max supported payload format version", HFILL }
2780 { &hf_usb_vid_control_ifdesc_dwClockFrequency,
2781 { "dwClockFrequency", "usbvideo.probe.clockFrequency",
2782 FT_UINT32, BASE_DEC, NULL, 0,
2783 "Device clock frequency (Hz) for selected format", HFILL }
2786 /***** Format Descriptors *****/
2788 { &hf_usb_vid_format_index,
2789 { "bFormatIndex", "usbvideo.format.index",
2790 FT_UINT8, BASE_DEC, NULL, 0,
2791 "Index of this format descriptor", HFILL }
2794 { &hf_usb_vid_format_num_frame_descriptors,
2795 { "bNumFrameDescriptors", "usbvideo.format.numFrameDescriptors",
2796 FT_UINT8, BASE_DEC, NULL, 0,
2797 "Number of frame descriptors for this format", HFILL }
2800 { &hf_usb_vid_format_guid,
2801 { "guidFormat", "usbvideo.format.guid",
2802 FT_GUID, BASE_NONE, NULL, 0,
2803 "Stream encoding format", HFILL }
2806 { &hf_usb_vid_format_bits_per_pixel,
2807 { "bBitsPerPixel", "usbvideo.format.bitsPerPixel",
2808 FT_UINT8, BASE_DEC, NULL, 0,
2809 "Bits per pixel", HFILL }
2812 { &hf_usb_vid_default_frame_index,
2813 { "bDefaultFrameIndex", "usbvideo.format.defaultFrameIndex",
2814 FT_UINT8, BASE_DEC, NULL, 0,
2815 "Optimum frame index for this stream", HFILL }
2818 { &hf_usb_vid_aspect_ratio_x,
2819 { "bAspectRatioX", "usbvideo.format.aspectRatioX",
2820 FT_UINT8, BASE_DEC, NULL, 0,
2821 "X dimension of picture aspect ratio", HFILL }
2824 { &hf_usb_vid_aspect_ratio_y,
2825 { "bAspectRatioY", "usbvideo.format.aspectRatioY",
2826 FT_UINT8, BASE_DEC, NULL, 0,
2827 "Y dimension of picture aspect ratio", HFILL }
2830 { &hf_usb_vid_interlace_flags,
2831 { "bmInterlaceFlags", "usbvideo.format.interlace",
2832 FT_UINT8, BASE_HEX, NULL, 0x0,
2836 { &hf_usb_vid_is_interlaced,
2837 { "Interlaced stream", "usbvideo.format.interlace.D0",
2838 FT_BOOLEAN, 8, TFS(&is_interlaced_meaning), (1<<0),
2842 { &hf_usb_vid_interlaced_fields,
2843 { "Fields per frame", "usbvideo.format.interlace.D1",
2844 FT_BOOLEAN, 8, TFS(&interlaced_fields_meaning), (1<<1),
2848 { &hf_usb_vid_field_1_first,
2849 { "Field 1 first", "usbvideo.format.interlace.D2",
2850 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<2),
2854 { &hf_usb_vid_field_pattern,
2855 { "Field pattern", "usbvideo.format.interlace.pattern",
2856 FT_UINT8, BASE_DEC | BASE_EXT_STRING,
2857 &field_pattern_meaning_ext, (3<<4),
2861 { &hf_usb_vid_copy_protect,
2862 { "bCopyProtect", "usbvideo.format.copyProtect",
2863 FT_UINT8, BASE_DEC, VALS(copy_protect_meaning), 0,
2867 { &hf_usb_vid_variable_size,
2868 { "Variable size", "usbvideo.format.variableSize",
2869 FT_BOOLEAN, BASE_DEC, NULL, 0,
2873 /***** MJPEG Format Descriptor *****/
2875 { &hf_usb_vid_mjpeg_flags,
2876 { "bmFlags", "usbvideo.mjpeg.flags",
2877 FT_UINT8, BASE_HEX, NULL, 0,
2878 "Characteristics", HFILL }
2881 { &hf_usb_vid_mjpeg_fixed_samples,
2882 { "Fixed size samples", "usbvideo.mjpeg.fixed_size",
2883 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<0),
2887 /***** Frame Descriptors *****/
2889 { &hf_usb_vid_frame_index,
2890 { "bFrameIndex", "usbvideo.frame.index",
2891 FT_UINT8, BASE_DEC, NULL, 0,
2892 "Index of this frame descriptor", HFILL }
2895 { &hf_usb_vid_frame_capabilities,
2896 { "bmCapabilities", "usbvideo.frame.capabilities",
2897 FT_UINT8, BASE_HEX, NULL, 0,
2898 "Capabilities", HFILL }
2901 { &hf_usb_vid_frame_stills_supported,
2902 { "Still image", "usbvideo.frame.stills",
2903 FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), (1<<0),
2907 { &hf_usb_vid_frame_interval,
2908 { "dwFrameInterval", "usbvideo.frame.interval",
2909 FT_UINT32, BASE_DEC, NULL, 0,
2910 "Frame interval multiple of 100 ns", HFILL }
2913 { &hf_usb_vid_frame_fixed_frame_rate,
2914 { "Fixed frame rate", "usbvideo.frame.fixedRate",
2915 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<1),
2918 { &hf_usb_vid_frame_width,
2919 { "wWidth", "usbvideo.frame.width",
2920 FT_UINT16, BASE_DEC, NULL, 0,
2921 "Width of frame in pixels", HFILL }
2923 { &hf_usb_vid_frame_height,
2924 { "wHeight", "usbvideo.frame.height",
2925 FT_UINT16, BASE_DEC, NULL, 0,
2926 "Height of frame in pixels", HFILL }
2928 { &hf_usb_vid_frame_min_bit_rate,
2929 { "dwMinBitRate", "usbvideo.frame.minBitRate",
2930 FT_UINT32, BASE_DEC, NULL, 0,
2931 "Minimum bit rate in bps", HFILL }
2933 { &hf_usb_vid_frame_max_bit_rate,
2934 { "dwMaxBitRate", "usbvideo.frame.maxBitRate",
2935 FT_UINT32, BASE_DEC, NULL, 0,
2936 "Maximum bit rate in bps", HFILL }
2939 { &hf_usb_vid_frame_max_frame_sz,
2940 { "dwMaxVideoFrameBufferSize", "usbvideo.frame.maxBuffer",
2941 FT_UINT32, BASE_DEC, NULL, 0,
2942 "Maximum bytes per frame", HFILL }
2944 { &hf_usb_vid_frame_default_interval,
2945 { "dwDefaultFrameInterval", "usbvideo.frame.interval.default",
2946 FT_UINT32, BASE_DEC, NULL, 0,
2947 "Suggested default", HFILL }
2950 { &hf_usb_vid_frame_interval_type,
2951 { "bFrameIntervalType", "usbvideo.frame.interval.type",
2952 FT_UINT8, BASE_DEC, NULL, 0,
2953 "Frame rate control (continuous/discrete)", HFILL }
2956 { &hf_usb_vid_frame_min_interval,
2957 { "dwMinFrameInterval", "usbvideo.frame.interval.min",
2958 FT_UINT32, BASE_DEC, NULL, 0,
2959 "Shortest frame interval (* 100 ns)", HFILL }
2962 { &hf_usb_vid_frame_max_interval,
2963 { "dwMaxFrameInterval", "usbvideo.frame.interval.max",
2964 FT_UINT32, BASE_DEC, NULL, 0,
2965 "Longest frame interval (* 100 ns)", HFILL }
2967 { &hf_usb_vid_frame_step_interval,
2968 { "dwMinFrameInterval", "usbvideo.frame.interval.step",
2969 FT_UINT32, BASE_DEC, NULL, 0,
2970 "Granularity of frame interval (* 100 ns)", HFILL }
2973 { &hf_usb_vid_frame_bytes_per_line,
2974 { "dwBytesPerLine", "usbvideo.frame.bytesPerLine",
2975 FT_UINT32, BASE_DEC, NULL, 0,
2976 "Fixed number of bytes per video line", HFILL }
2979 /***** Colorformat Descriptor *****/
2981 { &hf_usb_vid_color_primaries,
2982 { "bColorPrimaries", "usbvideo.color.primaries",
2983 FT_UINT8, BASE_DEC | BASE_EXT_STRING,
2984 &color_primaries_meaning_ext, 0,
2988 { &hf_usb_vid_transfer_characteristics,
2989 { "bTransferCharacteristics", "usbvideo.color.transferCharacteristics",
2990 FT_UINT8, BASE_DEC | BASE_EXT_STRING,
2991 &color_transfer_characteristics_ext, 0,
2995 { &hf_usb_vid_matrix_coefficients,
2996 { "bMatrixCoefficients", "usbvideo.color.matrixCoefficients",
2997 FT_UINT8, BASE_DEC | BASE_EXT_STRING,
2998 &matrix_coefficients_meaning_ext, 0,
3002 /***** Video Control Header Descriptor *****/
3004 { &hf_usb_vid_control_ifdesc_bcdUVC,
3005 { "bcdUVC", "usbvideo.bcdUVC",
3006 FT_UINT16, BASE_HEX, NULL, 0,
3007 "Video Device Class Specification release number", HFILL }
3010 { &hf_usb_vid_control_ifdesc_bInCollection,
3011 { "bInCollection", "usbvideo.numStreamingInterfaces",
3012 FT_UINT8, BASE_DEC, NULL, 0,
3013 "Number of VideoStreaming interfaces", HFILL }
3016 { &hf_usb_vid_control_ifdesc_baInterfaceNr,
3017 { "baInterfaceNr", "usbvideo.streamingInterfaceNumbers",
3018 FT_BYTES, BASE_NONE, NULL, 0,
3019 "Interface numbers of VideoStreaming interfaces", HFILL }},
3021 /***** Video Streaming Input Header Descriptor *****/
3023 { &hf_usb_vid_streaming_ifdesc_bNumFormats,
3024 { "bNumFormats", "usbvideo.streaming.numFormats",
3025 FT_UINT8, BASE_DEC, NULL, 0,
3026 "Number of video payload format descriptors", HFILL }
3029 { &hf_usb_vid_streaming_bmInfo,
3030 { "bmInfo", "usbvideo.streaming.info",
3031 FT_UINT8, BASE_HEX, NULL, 0,
3032 "Capabilities", HFILL }
3035 { &hf_usb_vid_streaming_info_D[0],
3036 { "Dynamic Format Change", "usbvideo.streaming.info.D0",
3037 FT_BOOLEAN, 8, TFS(&tfs_yes_no), (1<<0),
3038 "Dynamic Format Change", HFILL }
3041 { &hf_usb_vid_streaming_control_D[0],
3042 { "wKeyFrameRate", "usbvideo.streaming.control.D0",
3043 FT_BOOLEAN, 6, TFS(&tfs_yes_no), (1<<0),
3044 "Probe and Commit support", HFILL }
3047 { &hf_usb_vid_streaming_control_D[1],
3048 { "wPFrameRate", "usbvideo.streaming.control.D1",
3049 FT_BOOLEAN, 6, TFS(&tfs_yes_no), (1<<1),
3050 "Probe and Commit support", HFILL }
3053 { &hf_usb_vid_streaming_control_D[2],
3054 { "wCompQuality", "usbvideo.streaming.control.D2",
3055 FT_BOOLEAN, 6, TFS(&tfs_yes_no), (1<<2),
3056 "Probe and Commit support", HFILL }
3059 { &hf_usb_vid_streaming_control_D[3],
3060 { "wCompWindowSize", "usbvideo.streaming.control.D3",
3061 FT_BOOLEAN, 6, TFS(&tfs_yes_no), (1<<3),
3062 "Probe and Commit support", HFILL }
3065 { &hf_usb_vid_streaming_control_D[4],
3066 { "Generate Key Frame", "usbvideo.streaming.control.D4",
3067 FT_BOOLEAN, 6, TFS(&tfs_yes_no), (1<<4),
3068 "Probe and Commit support", HFILL }
3071 { &hf_usb_vid_streaming_control_D[5],
3072 { "Update Frame Segment", "usbvideo.streaming.control.D5",
3073 FT_BOOLEAN, 6, TFS(&tfs_yes_no), (1<<5),
3074 "Probe and Commit support", HFILL }
3077 { &hf_usb_vid_streaming_terminal_link,
3078 { "bTerminalLink", "usbvideo.streaming.terminalLink", FT_UINT8, BASE_DEC, NULL, 0x0,
3079 "Output terminal ID", HFILL }
3082 { &hf_usb_vid_streaming_still_capture_method,
3083 { "bStillCaptureMethod", "usbvideo.streaming.stillCaptureMethod",
3084 FT_UINT8, BASE_DEC | BASE_EXT_STRING,
3085 &vs_still_capture_methods_ext, 0,
3086 "Method of Still Image Capture", HFILL }
3089 { &hf_usb_vid_streaming_trigger_support,
3090 { "HW Triggering", "usbvideo.streaming.triggerSupport",
3091 FT_BOOLEAN, BASE_DEC, TFS(&tfs_supported_not_supported), 0,
3092 "Is HW triggering supported", HFILL }
3095 { &hf_usb_vid_streaming_trigger_usage,
3096 { "bTriggerUsage", "usbvideo.streaming.triggerUsage",
3097 FT_UINT8, BASE_DEC, VALS(vs_trigger_usage), 0,
3098 "How host SW should respond to trigger", HFILL }
3101 /***** Interrupt URB *****/
3103 { &hf_usb_vid_interrupt_bStatusType,
3104 { "Status Type", "usbvideo.interrupt.statusType",
3105 FT_UINT8, BASE_HEX, VALS(interrupt_status_types), 0xF,
3109 { &hf_usb_vid_interrupt_bAttribute,
3110 { "Change Type", "usbvideo.interrupt.attribute",
3111 FT_UINT8, BASE_HEX | BASE_EXT_STRING,
3112 &control_change_types_ext, 0,
3113 "Type of control change", HFILL }
3116 { &hf_usb_vid_interrupt_bOriginator,
3117 { "Originator", "usbvideo.interrupt.originator",
3118 FT_UINT8, BASE_DEC, NULL, 0,
3119 "ID of the entity that reports this interrupt", HFILL }
3122 { &hf_usb_vid_control_interrupt_bEvent,
3123 { "Event", "usbvideo.interrupt.controlEvent",
3124 FT_UINT8, BASE_HEX, VALS(control_interrupt_events), 0,
3125 "Type of event", HFILL }
3128 /***** Video Control Endpoint Descriptor *****/
3130 { &hf_usb_vid_epdesc_subtype,
3131 { "Subtype", "usbvideo.ep.descriptorSubType",
3132 FT_UINT8, BASE_DEC, VALS(vc_ep_descriptor_subtypes), 0,
3133 "Descriptor Subtype", HFILL }
3136 { &hf_usb_vid_epdesc_max_transfer_sz,
3137 { "wMaxTransferSize", "usbvideo.ep.maxInterruptSize", FT_UINT16,
3138 BASE_DEC, NULL, 0x0, "Max interrupt structure size", HFILL }
3141 /***** Fields used in multiple contexts *****/
3143 { &hf_usb_vid_ifdesc_wTotalLength,
3144 { "wTotalLength", "usbvideo.totalLength",
3145 FT_UINT16, BASE_DEC, NULL, 0,
3146 "Video interface descriptor size", HFILL }
3149 { &hf_usb_vid_bControlSize,
3150 { "bControlSize", "usbvideo.bmcontrolSize",
3151 FT_UINT8, BASE_DEC, NULL, 0,
3152 "Size of bmControls field", HFILL }
3155 { &hf_usb_vid_bmControl,
3156 { "bmControl", "usbvideo.availableControls",
3157 FT_UINT32, BASE_HEX, NULL, 0,
3158 "Available controls", HFILL }
3161 { &hf_usb_vid_bmControl_bytes,
3162 { "bmControl", "usbvideo.availableControls.bytes",
3163 FT_BYTES, BASE_NONE, NULL, 0,
3164 "Available controls", HFILL }
3167 { &hf_usb_vid_control_ifdesc_src_id,
3168 { "bSourceID", "usbvideo.sourceID", FT_UINT8, BASE_DEC, NULL, 0x0,
3169 "Entity to which this terminal/unit is connected", HFILL }
3174 { &hf_usb_vid_control_ifdesc_subtype,
3175 { "Subtype", "usbvideo.control.descriptorSubType",
3176 FT_UINT8, BASE_DEC | BASE_EXT_STRING,
3177 &vc_if_descriptor_subtypes_ext, 0,
3178 "Descriptor Subtype", HFILL }
3181 { &hf_usb_vid_streaming_ifdesc_subtype,
3182 { "Subtype", "usbvideo.streaming.descriptorSubType",
3183 FT_UINT8, BASE_DEC | BASE_EXT_STRING,
3184 &vs_if_descriptor_subtypes_ext, 0,
3185 "Descriptor Subtype", HFILL }
3188 { &hf_usb_vid_descriptor_data,
3189 { "Descriptor data", "usbvideo.descriptor_data", FT_BYTES, BASE_NONE, NULL, 0x0,
3193 { &hf_usb_vid_control_data,
3194 { "Control data", "usbvideo.control_data", FT_BYTES, BASE_NONE, NULL, 0x0,
3198 { &hf_usb_vid_control_value,
3199 { "Control value", "usbvideo.control_value", FT_BYTES, BASE_NONE, NULL, 0x0,
3203 { &hf_usb_vid_value_data,
3204 { "Value data", "usbvideo.value_data", FT_BYTES, BASE_NONE, NULL, 0x0,
3209 static gint *usb_vid_subtrees[] = {
3211 &ett_descriptor_video_endpoint,
3212 &ett_descriptor_video_control,
3213 &ett_descriptor_video_streaming,
3214 &ett_camera_controls,
3215 &ett_processing_controls,
3216 &ett_streaming_controls,
3217 &ett_streaming_info,
3218 &ett_interlace_flags,
3219 &ett_frame_capability_flags,
3224 &ett_video_standards,
3225 &ett_control_capabilities
3228 static ei_register_info ei[] = {
3229 { &ei_usb_vid_subtype_unknown, { "usbvideo.subtype.unknown", PI_UNDECODED, PI_WARN, "Unknown VC subtype", EXPFILL }},
3230 { &ei_usb_vid_bitmask_len, { "usbvideo.bitmask_len_error", PI_UNDECODED, PI_WARN, "Only least-significant bytes decoded", EXPFILL }},
3233 expert_module_t* expert_usb_vid;
3235 proto_usb_vid = proto_register_protocol("USB Video", "USBVIDEO", "usbvideo");
3236 proto_register_field_array(proto_usb_vid, hf, array_length(hf));
3237 proto_register_subtree_array(usb_vid_subtrees, array_length(usb_vid_subtrees));
3238 expert_usb_vid = expert_register_protocol(proto_usb_vid);
3239 expert_register_field_array(expert_usb_vid, ei, array_length(ei));
3243 proto_reg_handoff_usb_vid(void)
3245 dissector_handle_t usb_vid_control_handle;
3246 dissector_handle_t usb_vid_descriptor_handle;
3247 dissector_handle_t usb_vid_interrupt_handle;
3249 usb_vid_control_handle = create_dissector_handle(dissect_usb_vid_control, proto_usb_vid);
3250 dissector_add_uint("usb.control", IF_CLASS_VIDEO, usb_vid_control_handle);
3252 usb_vid_descriptor_handle = create_dissector_handle(dissect_usb_vid_descriptor, proto_usb_vid);
3253 dissector_add_uint("usb.descriptor", IF_CLASS_VIDEO, usb_vid_descriptor_handle);
3255 usb_vid_interrupt_handle = create_dissector_handle(dissect_usb_vid_interrupt, proto_usb_vid);
3256 dissector_add_uint("usb.interrupt", IF_CLASS_VIDEO, usb_vid_interrupt_handle);
3259 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3264 * indent-tabs-mode: nil
3267 * vi: set shiftwidth=4 tabstop=8 expandtab:
3268 * :indentSize=4:tabSize=8:noTabs=true: