5 * Forked from packet-usb-masstorage.c 35224 2010-12-20 05:35:29Z guy
6 * which was authored by Ronnie Sahlberg (2006)
9 * Steven J. Magnani 2013
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <epan/expert.h>
30 #include <epan/packet.h>
31 #include <epan/wmem/wmem.h>
32 #include <epan/conversation.h>
33 #include "packet-usb.h"
35 /* References are to sections in USB Video Class specifications -
36 * specifically V1.5, but versions have tended to keep
37 * the same numbering (as of this writing).
39 * http://www.usb.org/developers/devclass_docs/USB_Video_Class_1_5.zip
42 /* Table 2-1. Interrupt originators */
43 #define INT_VIDEOCONTROL 1
44 #define INT_VIDEOSTREAMING 2
46 #define INT_ORIGINATOR_MASK 0xF
48 /* Table 2-2. Video Control Status Packet bAttribute */
49 #define CONTROL_CHANGE_VALUE 0x00
50 #define CONTROL_CHANGE_INFO 0x01
51 #define CONTROL_CHANGE_FAILURE 0x02
52 #define CONTROL_CHANGE_MIN 0x03 /* UVC 1.5+ */
53 #define CONTROL_CHANGE_MAX 0x04 /* UVC 1.5+ */
56 /* A.2 Video Interface Subclass Codes */
57 #define SC_UNDEFINED 0
58 #define SC_VIDEOCONTROL 1
59 #define SC_VIDEOSTREAMING 2
60 #define SC_VIDEO_INTERFACE_COLLECTION 3
62 /* A.4. Video Class-Specific Descriptor Types */
63 #define CS_INTERFACE 0x24
64 #define CS_ENDPOINT 0x25
66 /* A.5 Video Class-Specific VC Interface Descriptor Subtypes */
68 #define VC_INPUT_TERMINAL 2
69 #define VC_OUTPUT_TERMINAL 3
70 #define VC_SELECTOR_UNIT 4
71 #define VC_PROCESSING_UNIT 5
72 #define VC_EXTENSION_UNIT 6
73 #define VC_ENCODING_UNIT 7
75 /* A.6 Video Class-Specific VS Interface Descriptor Subtypes */
76 #define VS_UNDEFINED 0x00
77 #define VS_INPUT_HEADER 0x01
78 #define VS_OUTPUT_HEADER 0x02
79 #define VS_STILL_IMAGE_FRAME 0x03
80 #define VS_FORMAT_UNCOMPRESSED 0x04
81 #define VS_FRAME_UNCOMPRESSED 0x05
82 #define VS_FORMAT_MJPEG 0x06
83 #define VS_FRAME_MJPEG 0x07
84 #define VS_FORMAT_MPEG1 0x08 /* Pre-UVC 1.1 */
85 #define VS_FORMAT_MPEG2PS 0x09 /* Pre-UVC 1.1 */
86 #define VS_FORMAT_MPEG2TS 0x0A
87 #define VS_FORMAT_MPEG4SL 0x0B /* Pre-UVC 1.1 */
88 #define VS_FORMAT_DV 0x0C
89 #define VS_COLORFORMAT 0x0D
90 #define VS_FORMAT_VENDOR 0x0E /* Pre-UVC 1.1 */
91 #define VS_FRAME_VENDOR 0x0F /* Pre-UVC 1.1 */
92 #define VS_FORMAT_FRAME_BASED 0x10
93 #define VS_FRAME_FRAME_BASED 0x11
94 #define VS_FORMAT_STREAM_BASED 0x12
95 #define VS_FORMAT_H264 0x13 /* UVC 1.5 */
96 #define VS_FRAME_H264 0x14 /* UVC 1.5 */
97 #define VS_FORMAT_H264_SIMULCAST 0x15 /* UVC 1.5 */
98 #define VS_FORMAT_VP8 0x16 /* UVC 1.5 */
99 #define VS_FRAME_VP8 0x17 /* UVC 1.5 */
100 #define VS_FORMAT_VP8_SIMULCAST 0x18 /* UVC 1.5 */
102 /* A.7 Video Class-Specific Endpoint Descriptor Subtypes */
103 #define EP_INTERRUPT 0x03
105 /* A.9.1 Video Control Interface Control Selectors */
106 #define VC_CONTROL_UNDEFINED 0x00
107 #define VC_VIDEO_POWER_MODE_CONTROL 0x01
108 #define VC_REQUEST_ERROR_CODE_CONTROL 0x02
109 #define VC_REQUEST_INDICATE_HOST_CLOCK_CONTROL 0x03 /* Pre-UVC 1.1 */
111 /* A.9.3 Selector Unit Control Selectors */
112 #define SU_CONTROL_UNDEFINED 0x00
113 #define SU_INPUT_SELECT_CONTROL 0x01
115 /* A.9.4 Camera Terminal Control Selectors */
116 #define CT_CONTROL_UNDEFINED 0x00
117 #define CT_SCANNING_MODE_CONTROL 0x01
118 #define CT_AE_MODE_CONTROL 0x02
119 #define CT_AE_PRIORITY_CONTROL 0x03
120 #define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
121 #define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
122 #define CT_FOCUS_ABSOLUTE_CONTROL 0x06
123 #define CT_FOCUS_RELATIVE_CONTROL 0x07
124 #define CT_FOCUS_AUTO_CONTROL 0x08
125 #define CT_IRIS_ABSOLUTE_CONTROL 0x09
126 #define CT_IRIS_RELATIVE_CONTROL 0x0A
127 #define CT_ZOOM_ABSOLUTE_CONTROL 0x0B
128 #define CT_ZOOM_RELATIVE_CONTROL 0x0C
129 #define CT_PANTILT_ABSOLUTE_CONTROL 0x0D
130 #define CT_PANTILT_RELATIVE_CONTROL 0x0E
131 #define CT_ROLL_ABSOLUTE_CONTROL 0x0F
132 #define CT_ROLL_RELATIVE_CONTROL 0x10
133 #define CT_PRIVACY_CONTROL 0x11
134 #define CT_FOCUS_SIMPLE_CONTROL 0x12 /* UVC 1.5 */
135 #define CT_WINDOW_CONTROL 0x13 /* UVC 1.5 */
136 #define CT_REGION_OF_INTEREST_CONTROL 0x14 /* UVC 1.5 */
138 /* A.9.5 Processing Unit Control Selectors */
139 #define PU_CONTROL_UNDEFINED 0x00
140 #define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
141 #define PU_BRIGHTNESS_CONTROL 0x02
142 #define PU_CONTRAST_CONTROL 0x03
143 #define PU_GAIN_CONTROL 0x04
144 #define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
145 #define PU_HUE_CONTROL 0x06
146 #define PU_SATURATION_CONTROL 0x07
147 #define PU_SHARPNESS_CONTROL 0x08
148 #define PU_GAMMA_CONTROL 0x09
149 #define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0A
150 #define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0B
151 #define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0C
152 #define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0D
153 #define PU_DIGITAL_MULTIPLIER_CONTROL 0x0E
154 #define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0F
155 #define PU_HUE_AUTO_CONTROL 0x10
156 #define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
157 #define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
158 #define PU_CONTRAST_AUTO_CONTROL 0x13
160 /* A.9.7 VideoStreaming Interface Control Selectors */
161 #define VS_CONTROL_UNDEFINED 0x00
162 #define VS_PROBE_CONTROL 0x01
163 #define VS_COMMIT_CONTROL 0x02
164 #define VS_STILL_PROBE_CONTROL 0x03
165 #define VS_STILL_COMMIT_CONTROL 0x04
166 #define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
167 #define VS_STREAM_ERROR_CODE_CONTROL 0x06
168 #define VS_GENERATE_KEY_FRAME_CONTROL 0x07
169 #define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
170 #define VS_SYNCH_DELAY_CONTROL 0x09
172 /* Appendix B Terminal Types */
173 #define TT_VENDOR_SPECIFIC 0x100
174 #define TT_STREAMING 0x101
175 #define ITT_VENDOR_SPECIFIC 0x200
176 #define ITT_CAMERA 0x201
177 #define ITT_MEDIA_TRANSPORT_INPUT 0x202
178 #define OTT_VENDOR_SPECIFIC 0x300
179 #define OTT_DISPLAY 0x301
180 #define OTT_MEDIA_TRANSPORT_OUTPUT 0x302
181 #define EXTERNAL_VENDOR_SPECIFIC 0x400
182 #define COMPOSITE_CONNECTOR 0x401
183 #define SVIDEO_CONNECTOR 0x402
184 #define COMPONENT_CONNECTOR 0x403
186 /* Table 2-2 Status Packet Format (VideoControl Interface as the Originator) */
187 #define CONTROL_INTERRUPT_EVENT_CONTROL_CHANGE 0
189 /* Table 4-7 Request Error Code Control bRequestErrorCode */
190 #define UVC_ERROR_NONE 0
191 #define UVC_ERROR_NOT_READY 1
192 #define UVC_ERROR_WRONG_STATE 2
193 #define UVC_ERROR_POWER 3
194 #define UVC_ERROR_OUT_OF_RANGE 4
195 #define UVC_ERROR_INVALID_UNIT 5
196 #define UVC_ERROR_INVALID_CONTROL 6
197 #define UVC_ERROR_INVALID_REQUEST 7
198 #define UVC_ERROR_INVALID_VALUE 8
199 #define UVC_ERROR_UNKNOWN 255
201 /* A.8 Video Class-Specific Request Codes */
202 #define USB_SETUP_SET_CUR 0x01
203 #define USB_SETUP_SET_CUR_ALL 0x11 /* UVC 1.5 */
204 #define USB_SETUP_GET_CUR 0x81
205 #define USB_SETUP_GET_MIN 0x82
206 #define USB_SETUP_GET_MAX 0x83
207 #define USB_SETUP_GET_RES 0x84
208 #define USB_SETUP_GET_LEN 0x85
209 #define USB_SETUP_GET_INFO 0x86
210 #define USB_SETUP_GET_DEF 0x87
211 #define USB_SETUP_GET_CUR_ALL 0x91 /* UVC 1.5 */
212 #define USB_SETUP_GET_MIN_ALL 0x92 /* UVC 1.5 */
213 #define USB_SETUP_GET_MAX_ALL 0x93 /* UVC 1.5 */
214 #define USB_SETUP_GET_RES_ALL 0x94 /* UVC 1.5 */
215 #define USB_SETUP_GET_DEF_ALL 0x97 /* UVC 1.5 */
217 /* protocols and header fields */
218 static int proto_usb_vid
= -1;
220 static int hf_usb_vid_control_entity
= -1;
221 static int hf_usb_vid_control_interface
= -1;
222 static int hf_usb_vid_control_selector
= -1;
223 static int hf_usb_vid_epdesc_subtype
= -1;
224 static int hf_usb_vid_epdesc_max_transfer_sz
= -1;
225 static int hf_usb_vid_control_ifdesc_subtype
= -1;
226 static int hf_usb_vid_control_ifdesc_terminal_id
= -1;
227 static int hf_usb_vid_control_ifdesc_terminal_type
= -1;
228 static int hf_usb_vid_control_ifdesc_assoc_terminal
= -1;
229 static int hf_usb_vid_streaming_ifdesc_subtype
= -1;
230 static int hf_usb_vid_streaming_ifdesc_bNumFormats
= -1;
231 static int hf_usb_vid_control_ifdesc_unit_id
= -1;
232 static int hf_usb_vid_request
= -1;
233 static int hf_usb_vid_length
= -1;
234 static int hf_usb_vid_interrupt_bStatusType
= -1;
235 static int hf_usb_vid_interrupt_bOriginator
= -1;
236 static int hf_usb_vid_interrupt_bAttribute
= -1;
237 static int hf_usb_vid_control_interrupt_bEvent
= -1;
238 static int hf_usb_vid_control_ifdesc_bcdUVC
= -1;
239 static int hf_usb_vid_ifdesc_wTotalLength
= -1;
240 static int hf_usb_vid_control_ifdesc_dwClockFrequency
= -1;
241 static int hf_usb_vid_control_ifdesc_bInCollection
= -1;
242 static int hf_usb_vid_control_ifdesc_baInterfaceNr
= -1;
243 static int hf_usb_vid_control_ifdesc_iTerminal
= -1;
244 static int hf_usb_vid_control_ifdesc_src_id
= -1;
245 static int hf_usb_vid_cam_objective_focal_len_min
= -1;
246 static int hf_usb_vid_cam_objective_focal_len_max
= -1;
247 static int hf_usb_vid_cam_ocular_focal_len
= -1;
248 static int hf_usb_vid_bControlSize
= -1;
249 static int hf_usb_vid_bmControl
= -1;
250 static int hf_usb_vid_control_default
= -1;
251 static int hf_usb_vid_control_min
= -1;
252 static int hf_usb_vid_control_max
= -1;
253 static int hf_usb_vid_control_res
= -1;
254 static int hf_usb_vid_control_cur
= -1;
255 static int hf_usb_vid_control_info
= -1;
256 static int hf_usb_vid_control_info_D
[7] = { -1, -1, -1, -1, -1, -1, -1 };
257 static int hf_usb_vid_control_length
= -1;
258 static int hf_usb_vid_cam_control_D
[22] = { -1, -1, -1, -1, -1, -1, -1, -1,
259 -1, -1, -1, -1, -1, -1, -1, -1,
260 -1, -1, -1, -1, -1, -1 };
261 static int hf_usb_vid_proc_control_D
[19] = { -1, -1, -1, -1, -1, -1, -1, -1,
262 -1, -1, -1, -1, -1, -1, -1, -1,
264 static int hf_usb_vid_proc_standards_D
[6] = { -1, -1, -1, -1, -1, -1 };
265 static int hf_usb_vid_exten_guid
= -1;
266 static int hf_usb_vid_exten_num_controls
= -1;
267 static int hf_usb_vid_num_inputs
= -1;
268 static int hf_usb_vid_sources
= -1;
269 static int hf_usb_vid_streaming_bmInfo
= -1;
270 static int hf_usb_vid_streaming_info_D
[1] = { -1 };
271 static int hf_usb_vid_streaming_terminal_link
= -1;
272 static int hf_usb_vid_streaming_still_capture_method
= -1;
273 static int hf_usb_vid_streaming_trigger_support
= -1;
274 static int hf_usb_vid_streaming_trigger_usage
= -1;
275 static int hf_usb_vid_streaming_control_D
[6] = { -1, -1, -1, -1, -1, -1 };
276 static int hf_usb_vid_format_index
= -1;
277 static int hf_usb_vid_format_num_frame_descriptors
= -1;
278 static int hf_usb_vid_format_guid
= -1;
279 static int hf_usb_vid_format_bits_per_pixel
= -1;
280 static int hf_usb_vid_default_frame_index
= -1;
281 static int hf_usb_vid_aspect_ratio_x
= -1;
282 static int hf_usb_vid_aspect_ratio_y
= -1;
283 static int hf_usb_vid_is_interlaced
= -1;
284 static int hf_usb_vid_interlaced_fields
= -1;
285 static int hf_usb_vid_field_1_first
= -1;
286 static int hf_usb_vid_field_pattern
= -1;
287 static int hf_usb_vid_copy_protect
= -1;
288 static int hf_usb_vid_variable_size
= -1;
289 static int hf_usb_vid_frame_index
= -1;
290 static int hf_usb_vid_frame_capabilities
= -1;
291 static int hf_usb_vid_frame_stills_supported
= -1;
292 static int hf_usb_vid_frame_fixed_frame_rate
= -1;
293 static int hf_usb_vid_frame_width
= -1;
294 static int hf_usb_vid_frame_height
= -1;
295 static int hf_usb_vid_frame_min_bit_rate
= -1;
296 static int hf_usb_vid_frame_max_bit_rate
= -1;
297 static int hf_usb_vid_frame_max_frame_sz
= -1;
298 static int hf_usb_vid_frame_default_interval
= -1;
299 static int hf_usb_vid_frame_bytes_per_line
= -1;
300 static int hf_usb_vid_mjpeg_flags
= -1;
301 static int hf_usb_vid_mjpeg_fixed_samples
= -1;
302 static int hf_usb_vid_probe_hint
= -1;
303 static int hf_usb_vid_probe_hint_D
[5] = { -1, -1, -1, -1, -1 };
304 static int hf_usb_vid_frame_interval
= -1;
305 static int hf_usb_vid_probe_key_frame_rate
= -1;
306 static int hf_usb_vid_probe_p_frame_rate
= -1;
307 static int hf_usb_vid_probe_comp_quality
= -1;
308 static int hf_usb_vid_probe_comp_window
= -1;
309 static int hf_usb_vid_probe_delay
= -1;
310 static int hf_usb_vid_probe_max_frame_sz
= -1;
311 static int hf_usb_vid_probe_max_payload_sz
= -1;
312 static int hf_usb_vid_probe_clock_freq
= -1;
313 static int hf_usb_vid_probe_framing
= -1;
314 static int hf_usb_vid_probe_framing_D
[2] = { -1, -1 };
315 static int hf_usb_vid_probe_preferred_ver
= -1;
316 static int hf_usb_vid_probe_min_ver
= -1;
317 static int hf_usb_vid_probe_max_ver
= -1;
318 static int hf_usb_vid_frame_interval_type
= -1;
319 static int hf_usb_vid_frame_min_interval
= -1;
320 static int hf_usb_vid_frame_max_interval
= -1;
321 static int hf_usb_vid_frame_step_interval
= -1;
322 static int hf_usb_vid_color_primaries
= -1;
323 static int hf_usb_vid_transfer_characteristics
= -1;
324 static int hf_usb_vid_matrix_coefficients
= -1;
325 static int hf_usb_vid_max_multiplier
= -1;
326 static int hf_usb_vid_iProcessing
= -1;
327 static int hf_usb_vid_iExtension
= -1;
328 static int hf_usb_vid_iSelector
= -1;
329 static int hf_usb_vid_proc_standards
= -1;
330 static int hf_usb_vid_request_error
= -1;
333 static gint ett_usb_vid
= -1;
334 static gint ett_descriptor_video_endpoint
= -1;
335 static gint ett_descriptor_video_control
= -1;
336 static gint ett_descriptor_video_streaming
= -1;
337 static gint ett_camera_controls
= -1;
338 static gint ett_processing_controls
= -1;
339 static gint ett_streaming_controls
= -1;
340 static gint ett_streaming_info
= -1;
341 static gint ett_interlace_flags
= -1;
342 static gint ett_frame_capability_flags
= -1;
343 static gint ett_mjpeg_flags
= -1;
344 static gint ett_video_probe
= -1;
345 static gint ett_probe_hint
= -1;
346 static gint ett_probe_framing
= -1;
347 static gint ett_video_standards
= -1;
348 static gint ett_control_capabilities
= -1;
350 static expert_field ei_usb_vid_subtype_unknown
= EI_INIT
;
351 static expert_field ei_usb_vid_bitmask_len
= EI_INIT
;
354 static const value_string vc_ep_descriptor_subtypes
[] = {
355 { EP_INTERRUPT
, "Interrupt" },
359 static const value_string vid_descriptor_type_vals
[] = {
360 {CS_INTERFACE
, "video class interface"},
361 {CS_ENDPOINT
, "video class endpoint"},
364 static value_string_ext vid_descriptor_type_vals_ext
=
365 VALUE_STRING_EXT_INIT(vid_descriptor_type_vals
);
367 static const value_string vc_if_descriptor_subtypes
[] = {
368 { VC_HEADER
, "Header" },
369 { VC_INPUT_TERMINAL
, "Input Terminal" },
370 { VC_OUTPUT_TERMINAL
, "Output Terminal" },
371 { VC_SELECTOR_UNIT
, "Selector Unit" },
372 { VC_PROCESSING_UNIT
, "Processing Unit" },
373 { VC_EXTENSION_UNIT
, "Extension Unit" },
374 { VC_ENCODING_UNIT
, "Encoding Unit" },
377 static value_string_ext vc_if_descriptor_subtypes_ext
=
378 VALUE_STRING_EXT_INIT(vc_if_descriptor_subtypes
);
380 static const value_string cs_control_interface
[] = {
381 { VC_CONTROL_UNDEFINED
, "Undefined" },
382 { VC_VIDEO_POWER_MODE_CONTROL
, "Video Power Mode" },
383 { VC_REQUEST_ERROR_CODE_CONTROL
, "Request Error Code" },
384 { VC_REQUEST_INDICATE_HOST_CLOCK_CONTROL
, "Request Indicate Host Clock" },
387 static value_string_ext cs_control_interface_ext
=
388 VALUE_STRING_EXT_INIT(cs_control_interface
);
390 static const value_string cs_streaming_interface
[] = {
391 { VS_CONTROL_UNDEFINED
, "Undefined" },
392 { VS_PROBE_CONTROL
, "Probe" },
393 { VS_COMMIT_CONTROL
, "Commit" },
394 { VS_STILL_PROBE_CONTROL
, "Still Probe" },
395 { VS_STILL_COMMIT_CONTROL
, "Still Commit" },
396 { VS_STILL_IMAGE_TRIGGER_CONTROL
, "Still Image Trigger" },
397 { VS_STREAM_ERROR_CODE_CONTROL
, "Stream Error Code" },
398 { VS_GENERATE_KEY_FRAME_CONTROL
, "Generate Key Frame" },
399 { VS_UPDATE_FRAME_SEGMENT_CONTROL
, "Update Frame Segment" },
400 { VS_SYNCH_DELAY_CONTROL
, "Synch Delay" },
403 static value_string_ext cs_streaming_interface_ext
=
404 VALUE_STRING_EXT_INIT(cs_streaming_interface
);
406 static const value_string cs_selector_unit
[] = {
407 { SU_CONTROL_UNDEFINED
, "Undefined" },
408 { SU_INPUT_SELECT_CONTROL
, "Input Select" },
411 static value_string_ext cs_selector_unit_ext
=
412 VALUE_STRING_EXT_INIT(cs_selector_unit
);
414 static const value_string cs_camera_terminal
[] = {
415 { CT_CONTROL_UNDEFINED
, "Undefined" },
416 { CT_SCANNING_MODE_CONTROL
, "Scanning Mode" },
417 { CT_AE_MODE_CONTROL
, "Auto-Exposure Mode" },
418 { CT_AE_PRIORITY_CONTROL
, "Auto-Exposure Priority" },
419 { CT_EXPOSURE_TIME_ABSOLUTE_CONTROL
, "Exposure Time (Absolute)" },
420 { CT_EXPOSURE_TIME_RELATIVE_CONTROL
, "Exposure Time (Relative)" },
421 { CT_FOCUS_ABSOLUTE_CONTROL
, "Focus (Absolute)" },
422 { CT_FOCUS_RELATIVE_CONTROL
, "Focus (Relative)" },
423 { CT_FOCUS_AUTO_CONTROL
, "Focus, Auto" },
424 { CT_IRIS_ABSOLUTE_CONTROL
, "Iris (Absolute)" },
425 { CT_IRIS_RELATIVE_CONTROL
, "Iris (Relative)" },
426 { CT_ZOOM_ABSOLUTE_CONTROL
, "Zoom (Absolute)" },
427 { CT_ZOOM_RELATIVE_CONTROL
, "Zoom (Relative)" },
428 { CT_PANTILT_ABSOLUTE_CONTROL
, "PanTilt (Absolute)" },
429 { CT_PANTILT_RELATIVE_CONTROL
, "PanTilt (Relative)" },
430 { CT_ROLL_ABSOLUTE_CONTROL
, "Roll (Absolute)" },
431 { CT_ROLL_RELATIVE_CONTROL
, "Roll (Relative)" },
432 { CT_PRIVACY_CONTROL
, "Privacy" },
433 { CT_FOCUS_SIMPLE_CONTROL
, "Focus (Simple)" },
434 { CT_WINDOW_CONTROL
, "Window" },
435 { CT_REGION_OF_INTEREST_CONTROL
, "Region of Interest" },
438 static value_string_ext cs_camera_terminal_ext
=
439 VALUE_STRING_EXT_INIT(cs_camera_terminal
);
441 static const value_string cs_processing_unit
[] = {
442 { PU_CONTROL_UNDEFINED
, "Undefined" },
443 { PU_BACKLIGHT_COMPENSATION_CONTROL
, "Backlight Compensation" },
444 { PU_BRIGHTNESS_CONTROL
, "Brightness" },
445 { PU_CONTRAST_CONTROL
, "Contrast" },
446 { PU_GAIN_CONTROL
, "Gain" },
447 { PU_POWER_LINE_FREQUENCY_CONTROL
, "Power Line Frequency" },
448 { PU_HUE_CONTROL
, "Hue" },
449 { PU_SATURATION_CONTROL
, "Saturation" },
450 { PU_SHARPNESS_CONTROL
, "Sharpness" },
451 { PU_GAMMA_CONTROL
, "Gamma" },
452 { PU_WHITE_BALANCE_TEMPERATURE_CONTROL
, "White Balance Temperature" },
453 { PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL
,"White Balance Temperature Auto" },
454 { PU_WHITE_BALANCE_COMPONENT_CONTROL
, "White Balance Component" },
455 { PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL
, "White Balance Component Auto" },
456 { PU_DIGITAL_MULTIPLIER_CONTROL
, "Digital Multiplier" },
457 { PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL
, "Digital Multiplier Limit" },
458 { PU_HUE_AUTO_CONTROL
, "Hue Auto" },
459 { PU_ANALOG_VIDEO_STANDARD_CONTROL
, "Video Standard" },
460 { PU_ANALOG_LOCK_STATUS_CONTROL
, "Analog Lock Status" },
461 { PU_CONTRAST_AUTO_CONTROL
, "Contrast Auto" },
464 static value_string_ext cs_processing_unit_ext
=
465 VALUE_STRING_EXT_INIT(cs_processing_unit
);
467 static const value_string vc_terminal_types
[] = {
468 { TT_VENDOR_SPECIFIC
, "Vendor Specific", },
469 { TT_STREAMING
, "Streaming" },
470 { ITT_VENDOR_SPECIFIC
, "Vendor Specific Input" },
471 { ITT_CAMERA
, "Camera Input" },
472 { ITT_MEDIA_TRANSPORT_INPUT
, "Media Transport Input" },
473 { OTT_VENDOR_SPECIFIC
, "Vendor Specific Output" },
474 { OTT_DISPLAY
, "Display Output" },
475 { OTT_MEDIA_TRANSPORT_OUTPUT
, "Media Transport Output" },
476 { EXTERNAL_VENDOR_SPECIFIC
, "Vendor Specific External" },
477 { COMPOSITE_CONNECTOR
, "Composite Connector" },
478 { SVIDEO_CONNECTOR
, "SVideo Connector" },
479 { COMPONENT_CONNECTOR
, "Component Connector" },
482 static value_string_ext vc_terminal_types_ext
=
483 VALUE_STRING_EXT_INIT(vc_terminal_types
);
485 static const value_string vs_if_descriptor_subtypes
[] = {
486 { VS_UNDEFINED
, "Undefined" },
487 { VS_INPUT_HEADER
, "Input Header" },
488 { VS_OUTPUT_HEADER
, "Output Header" },
489 { VS_STILL_IMAGE_FRAME
, "Still Image Frame" },
490 { VS_FORMAT_UNCOMPRESSED
, "Format Uncompressed" },
491 { VS_FRAME_UNCOMPRESSED
, "Frame Uncompressed" },
492 { VS_FORMAT_MJPEG
, "Format MJPEG" },
493 { VS_FRAME_MJPEG
, "Frame MJPEG" },
494 { VS_FORMAT_MPEG1
, "Format MPEG1" },
495 { VS_FORMAT_MPEG2PS
, "Format MPEG2-PS" },
496 { VS_FORMAT_MPEG2TS
, "Format MPEG2-TS" },
497 { VS_FORMAT_MPEG4SL
, "Format MPEG4-SL" },
498 { VS_FORMAT_DV
, "Format DV" },
499 { VS_COLORFORMAT
, "Colorformat" },
500 { VS_FORMAT_VENDOR
, "Format Vendor" },
501 { VS_FRAME_VENDOR
, "Frame Vendor" },
502 { VS_FORMAT_FRAME_BASED
, "Format Frame-Based" },
503 { VS_FRAME_FRAME_BASED
, "Frame Frame-Based" },
504 { VS_FORMAT_STREAM_BASED
, "Format Stream Based" },
505 { VS_FORMAT_H264
, "Format H.264" },
506 { VS_FRAME_H264
, "Frame H.264" },
507 { VS_FORMAT_H264_SIMULCAST
, "Format H.264 Simulcast" },
508 { VS_FORMAT_VP8
, "Format VP8" },
509 { VS_FRAME_VP8
, "Frame VP8" },
510 { VS_FORMAT_VP8_SIMULCAST
, "Format VP8 Simulcast" },
513 static value_string_ext vs_if_descriptor_subtypes_ext
=
514 VALUE_STRING_EXT_INIT(vs_if_descriptor_subtypes
);
516 static const value_string interrupt_status_types
[] = {
517 { INT_VIDEOCONTROL
, "VideoControl Interface" },
518 { INT_VIDEOSTREAMING
, "VideoStreaming Interface" },
522 static const value_string control_change_types
[] = {
523 { CONTROL_CHANGE_VALUE
, "Value" },
524 { CONTROL_CHANGE_INFO
, "Info" },
525 { CONTROL_CHANGE_FAILURE
, "Failure" },
526 { CONTROL_CHANGE_MIN
, "Min" },
527 { CONTROL_CHANGE_MAX
, "Max" },
530 static value_string_ext control_change_types_ext
=
531 VALUE_STRING_EXT_INIT(control_change_types
);
533 static const value_string control_interrupt_events
[] = {
534 { CONTROL_INTERRUPT_EVENT_CONTROL_CHANGE
, "Control Change" },
538 /* Table 3-13 VS Interface Input Header Descriptor - bStillCaptureMethod field */
539 static const value_string vs_still_capture_methods
[] = {
541 { 1, "Uninterrupted streaming" },
542 { 2, "Suspended streaming" },
543 { 3, "Dedicated pipe" },
546 static value_string_ext vs_still_capture_methods_ext
=
547 VALUE_STRING_EXT_INIT(vs_still_capture_methods
);
549 /* Table 3-13 VS Interface Input Header Descriptor - bTriggerUsage field */
550 static const value_string vs_trigger_usage
[] = {
551 { 0, "Initiate still image capture" },
552 { 1, "General purpose button event" },
556 /* bmInterlaceFlags for format descriptors */
557 static const true_false_string is_interlaced_meaning
= {
562 /* bmInterlaceFlags for format descriptors */
563 static const true_false_string interlaced_fields_meaning
= {
568 /* bmInterlaceFlags for format descriptors */
569 static const value_string field_pattern_meaning
[] = {
570 { 0, "Field 1 only" },
571 { 1, "Field 2 only" },
572 { 2, "Regular pattern of fields 1 and 2" },
573 { 3, "Random pattern of fields 1 and 2" },
576 static value_string_ext field_pattern_meaning_ext
=
577 VALUE_STRING_EXT_INIT(field_pattern_meaning
);
579 /* bCopyProtect for format descriptors */
580 static const value_string copy_protect_meaning
[] = {
581 { 0, "No restrictions" },
582 { 1, "Restrict duplication" },
586 /* Table 4-46 Video Probe and Commit Controls - bmHint field */
587 static const true_false_string probe_hint_meaning
= {
592 /* Table 3-19 Color Matching Descriptor - bColorPrimaries field */
593 static const value_string color_primaries_meaning
[] = {
594 { 0, "Unspecified" },
595 { 1, "BT.709, sRGB" },
596 { 2, "BT.470-2 (M)" },
597 { 3, "BT.470-2 (B,G)" },
602 static value_string_ext color_primaries_meaning_ext
=
603 VALUE_STRING_EXT_INIT(color_primaries_meaning
);
605 /* Table 3-19 Color Matching Descriptor - bTransferCharacteristics field */
606 static const value_string color_transfer_characteristics
[] = {
607 { 0, "Unspecified" },
609 { 2, "BT.470-2 (M)" },
610 { 3, "BT.470-2 (B,G)" },
613 { 6, "Linear (V=Lc)" },
617 static value_string_ext color_transfer_characteristics_ext
=
618 VALUE_STRING_EXT_INIT(color_transfer_characteristics
);
620 /* Table 3-19 Color Matching Descriptor - bMatrixCoefficients field */
621 static const value_string matrix_coefficients_meaning
[] = {
622 { 0, "Unspecified" },
625 { 3, "BT.470-2 (B,G)" },
626 { 4, "SMPTE 170M (BT.601)" },
630 static value_string_ext matrix_coefficients_meaning_ext
=
631 VALUE_STRING_EXT_INIT(matrix_coefficients_meaning
);
633 static const value_string request_error_codes
[] = {
634 { UVC_ERROR_NONE
, "No error" },
635 { UVC_ERROR_NOT_READY
, "Not ready" },
636 { UVC_ERROR_WRONG_STATE
, "Wrong state" },
637 { UVC_ERROR_POWER
, "Insufficient power" } ,
638 { UVC_ERROR_OUT_OF_RANGE
, "Out of range" },
639 { UVC_ERROR_INVALID_UNIT
, "Invalid unit" },
640 { UVC_ERROR_INVALID_CONTROL
, "Invalid control" },
641 { UVC_ERROR_INVALID_REQUEST
, "Invalid request" },
642 { UVC_ERROR_INVALID_VALUE
, "Invalid value within range" },
643 { UVC_ERROR_UNKNOWN
, "Unknown" },
646 static value_string_ext request_error_codes_ext
=
647 VALUE_STRING_EXT_INIT(request_error_codes
);
649 /* There is one such structure per terminal or unit per interface */
654 guint16 terminalType
;
657 /* video_entity_t's (units/terminals) associated with each video interface */
658 /* There is one such structure for each video conversation (interface) */
659 typedef struct _video_conv_info_t
{
660 wmem_tree_t
* entities
; /* indexed by entity ID */
663 /*****************************************************************************/
664 /* UTILITY FUNCTIONS */
665 /*****************************************************************************/
668 * Dissector for variable-length bmControl bitmask / bControlSize pair.
670 * Creates an item for bControlSize, and a subtree for the bmControl bitmask.
672 * @param tree protocol tree to be the parent of the bitmask subtree
673 * @param tvb the tv_buff with the (remaining) packet data
674 * @param offset where in tvb to find bControlSize field
675 * @param ett_subtree index of the subtree to use for this bitmask
676 * @param bm_items NULL-terminated array of pointers that lists all the fields
679 * @return offset within tvb at which dissection should continue
682 dissect_bmControl(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
,
683 gint ett_subtree
, const int** bm_items
)
687 bm_size
= tvb_get_guint8(tvb
, offset
);
688 proto_tree_add_item(tree
, hf_usb_vid_bControlSize
, tvb
, offset
, 1, ENC_NA
);
693 proto_tree_add_bitmask_len(tree
, tvb
, offset
, bm_size
, hf_usb_vid_bmControl
,
694 ett_subtree
, bm_items
, &ei_usb_vid_bitmask_len
, ENC_LITTLE_ENDIAN
);
701 /*****************************************************************************/
702 /* VIDEO CONTROL DESCRIPTORS */
703 /*****************************************************************************/
705 /* Dissect a Camera Terminal descriptor */
707 dissect_usb_video_camera_terminal(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
709 static const int *control_bits
[] = {
710 &hf_usb_vid_cam_control_D
[0],
711 &hf_usb_vid_cam_control_D
[1],
712 &hf_usb_vid_cam_control_D
[2],
713 &hf_usb_vid_cam_control_D
[3],
714 &hf_usb_vid_cam_control_D
[4],
715 &hf_usb_vid_cam_control_D
[5],
716 &hf_usb_vid_cam_control_D
[6],
717 &hf_usb_vid_cam_control_D
[7],
718 &hf_usb_vid_cam_control_D
[8],
719 &hf_usb_vid_cam_control_D
[9],
720 &hf_usb_vid_cam_control_D
[10],
721 &hf_usb_vid_cam_control_D
[11],
722 &hf_usb_vid_cam_control_D
[12],
723 &hf_usb_vid_cam_control_D
[13],
724 &hf_usb_vid_cam_control_D
[14],
725 &hf_usb_vid_cam_control_D
[15],
726 &hf_usb_vid_cam_control_D
[16],
727 &hf_usb_vid_cam_control_D
[17],
728 &hf_usb_vid_cam_control_D
[18],
729 &hf_usb_vid_cam_control_D
[19],
730 &hf_usb_vid_cam_control_D
[20],
731 &hf_usb_vid_cam_control_D
[21],
735 DISSECTOR_ASSERT(array_length(control_bits
) == (1+array_length(hf_usb_vid_cam_control_D
)));
737 proto_tree_add_item(tree
, hf_usb_vid_cam_objective_focal_len_min
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
739 proto_tree_add_item(tree
, hf_usb_vid_cam_objective_focal_len_max
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
741 proto_tree_add_item(tree
, hf_usb_vid_cam_ocular_focal_len
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
744 offset
= dissect_bmControl(tree
, tvb
, offset
, ett_camera_controls
, control_bits
);
749 /* Dissect a Processing Unit descriptor */
751 dissect_usb_video_processing_unit(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
753 static const int *control_bits
[] = {
754 &hf_usb_vid_proc_control_D
[0],
755 &hf_usb_vid_proc_control_D
[1],
756 &hf_usb_vid_proc_control_D
[2],
757 &hf_usb_vid_proc_control_D
[3],
758 &hf_usb_vid_proc_control_D
[4],
759 &hf_usb_vid_proc_control_D
[5],
760 &hf_usb_vid_proc_control_D
[6],
761 &hf_usb_vid_proc_control_D
[7],
762 &hf_usb_vid_proc_control_D
[8],
763 &hf_usb_vid_proc_control_D
[9],
764 &hf_usb_vid_proc_control_D
[10],
765 &hf_usb_vid_proc_control_D
[11],
766 &hf_usb_vid_proc_control_D
[12],
767 &hf_usb_vid_proc_control_D
[13],
768 &hf_usb_vid_proc_control_D
[14],
769 &hf_usb_vid_proc_control_D
[15],
770 &hf_usb_vid_proc_control_D
[16],
771 &hf_usb_vid_proc_control_D
[17],
772 &hf_usb_vid_proc_control_D
[18],
776 DISSECTOR_ASSERT(array_length(control_bits
) == (1+array_length(hf_usb_vid_proc_control_D
)));
778 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_src_id
, tvb
, offset
, 1, ENC_NA
);
779 proto_tree_add_item(tree
, hf_usb_vid_max_multiplier
, tvb
, offset
+1, 2, ENC_LITTLE_ENDIAN
);
782 offset
= dissect_bmControl(tree
, tvb
, offset
, ett_processing_controls
, control_bits
);
784 proto_tree_add_item(tree
, hf_usb_vid_iProcessing
, tvb
, offset
, 1, ENC_NA
);
787 /* UVC 1.1 added bmVideoStandards */
788 if (tvb_reported_length_remaining(tvb
, offset
) > 0)
790 static const int *standard_bits
[] = {
791 &hf_usb_vid_proc_standards_D
[0],
792 &hf_usb_vid_proc_standards_D
[1],
793 &hf_usb_vid_proc_standards_D
[2],
794 &hf_usb_vid_proc_standards_D
[3],
795 &hf_usb_vid_proc_standards_D
[4],
796 &hf_usb_vid_proc_standards_D
[5],
800 DISSECTOR_ASSERT(array_length(standard_bits
) == (1+array_length(hf_usb_vid_proc_standards_D
)));
802 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_proc_standards
,
803 ett_video_standards
, standard_bits
, ENC_NA
);
810 /* Dissect a Selector Unit descriptor */
812 dissect_usb_video_selector_unit(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
816 num_inputs
= tvb_get_guint8(tvb
, offset
);
817 proto_tree_add_item(tree
, hf_usb_vid_num_inputs
, tvb
, offset
, 1, ENC_NA
);
822 proto_tree_add_item(tree
, hf_usb_vid_sources
, tvb
, offset
, num_inputs
, ENC_NA
);
823 offset
+= num_inputs
;
826 proto_tree_add_item(tree
, hf_usb_vid_iSelector
, tvb
, offset
, 1, ENC_NA
);
832 /* Dissect an Extension Unit descriptor */
834 dissect_usb_video_extension_unit(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
839 proto_tree_add_item(tree
, hf_usb_vid_exten_guid
, tvb
, offset
, 16, ENC_LITTLE_ENDIAN
);
840 proto_tree_add_item(tree
, hf_usb_vid_exten_num_controls
, tvb
, offset
+16, 1, ENC_NA
);
843 num_inputs
= tvb_get_guint8(tvb
, offset
);
844 proto_tree_add_item(tree
, hf_usb_vid_num_inputs
, tvb
, offset
, 1, ENC_NA
);
849 proto_tree_add_item(tree
, hf_usb_vid_sources
, tvb
, offset
, num_inputs
, ENC_NA
);
850 offset
+= num_inputs
;
853 control_size
= tvb_get_guint8(tvb
, offset
);
854 proto_tree_add_item(tree
, hf_usb_vid_bControlSize
, tvb
, offset
, 1, ENC_NA
);
857 if (control_size
> 0)
859 if (control_size
<= proto_registrar_get_length(hf_usb_vid_bmControl
))
861 proto_tree_add_item(tree
, hf_usb_vid_bmControl
, tvb
, offset
, control_size
,
866 /* Too big to display as integer */
867 /* @todo Display as FT_BYTES with a big-endian disclaimer?
868 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7933
870 proto_tree_add_text(tree
, tvb
, offset
, control_size
, "bmControl");
872 offset
+= control_size
;
875 proto_tree_add_item(tree
, hf_usb_vid_iExtension
, tvb
, offset
, 1, ENC_NA
);
882 * Dissector for video class control interface descriptors
884 * @param parent_tree the protocol tree to be the parent of the descriptor subtree
885 * @param tvb the tv_buff with the (remaining) packet data
886 * On entry the gaze is set to the descriptor length field.
887 * @param descriptor_len Length of the descriptor to dissect
888 * @param pinfo Information associated with the packet being dissected
890 * @return offset within tvb at which dissection should continue
893 dissect_usb_video_control_interface_descriptor(proto_tree
*parent_tree
, tvbuff_t
*tvb
,
894 guint8 descriptor_len
, packet_info
*pinfo
, usb_conv_info_t
*usb_conv_info
)
896 video_conv_info_t
*video_conv_info
= NULL
;
897 video_entity_t
*entity
= NULL
;
898 proto_item
*item
= NULL
;
899 proto_item
*subtype_item
= NULL
;
900 proto_tree
*tree
= NULL
;
901 guint8 entity_id
= 0;
902 guint16 terminal_type
= 0;
906 subtype
= tvb_get_guint8(tvb
, offset
+2);
910 const gchar
* subtype_str
;
912 subtype_str
= val_to_str_ext(subtype
, &vc_if_descriptor_subtypes_ext
, "Unknown (0x%x)");
914 item
= proto_tree_add_text(parent_tree
, tvb
, offset
, descriptor_len
,
915 "VIDEO CONTROL INTERFACE DESCRIPTOR [%s]",
917 tree
= proto_item_add_subtree(item
, ett_descriptor_video_control
);
921 dissect_usb_descriptor_header(tree
, tvb
, offset
, &vid_descriptor_type_vals_ext
);
922 subtype_item
= proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_subtype
, tvb
, offset
+2, 1, ENC_NA
);
925 if (subtype
== VC_HEADER
)
927 guint8 num_vs_interfaces
;
929 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_bcdUVC
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
930 proto_tree_add_item(tree
, hf_usb_vid_ifdesc_wTotalLength
, tvb
, offset
+2, 2, ENC_LITTLE_ENDIAN
);
931 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_dwClockFrequency
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
933 num_vs_interfaces
= tvb_get_guint8(tvb
, offset
+8);
934 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_bInCollection
, tvb
, offset
+8, 1, ENC_LITTLE_ENDIAN
);
936 if (num_vs_interfaces
> 0)
938 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_baInterfaceNr
, tvb
, offset
+9, num_vs_interfaces
, ENC_NA
);
941 offset
+= 9 + num_vs_interfaces
;
943 else if ((subtype
== VC_INPUT_TERMINAL
) || (subtype
== VC_OUTPUT_TERMINAL
))
945 /* Fields common to input and output terminals */
946 entity_id
= tvb_get_guint8(tvb
, offset
);
947 terminal_type
= tvb_get_letohs(tvb
, offset
+1);
949 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_terminal_id
, tvb
, offset
, 1, ENC_NA
);
950 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_terminal_type
, tvb
, offset
+1, 2, ENC_LITTLE_ENDIAN
);
951 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_assoc_terminal
, tvb
, offset
+3, 1, ENC_NA
);
954 if (subtype
== VC_OUTPUT_TERMINAL
)
956 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_src_id
, tvb
, offset
, 1, ENC_NA
);
960 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_iTerminal
, tvb
, offset
, 1, ENC_NA
);
963 if (subtype
== VC_INPUT_TERMINAL
)
965 if (terminal_type
== ITT_CAMERA
)
967 offset
= dissect_usb_video_camera_terminal(tree
, tvb
, offset
);
969 else if (terminal_type
== ITT_MEDIA_TRANSPORT_INPUT
)
975 if (subtype
== VC_OUTPUT_TERMINAL
)
977 if (terminal_type
== OTT_MEDIA_TRANSPORT_OUTPUT
)
985 /* Field common to extension / processing / selector / encoding units */
986 entity_id
= tvb_get_guint8(tvb
, offset
);
987 proto_tree_add_item(tree
, hf_usb_vid_control_ifdesc_unit_id
, tvb
, offset
, 1, ENC_NA
);
990 if (subtype
== VC_PROCESSING_UNIT
)
992 offset
= dissect_usb_video_processing_unit(tree
, tvb
, offset
);
994 else if (subtype
== VC_SELECTOR_UNIT
)
996 offset
= dissect_usb_video_selector_unit(tree
, tvb
, offset
);
998 else if (subtype
== VC_EXTENSION_UNIT
)
1000 offset
= dissect_usb_video_extension_unit(tree
, tvb
, offset
);
1002 else if (subtype
== VC_ENCODING_UNIT
)
1008 expert_add_info_format(pinfo
, subtype_item
, &ei_usb_vid_subtype_unknown
,
1009 "Unknown VC subtype %u", subtype
);
1013 /* Soak up descriptor bytes beyond those we know how to dissect */
1014 if (offset
< descriptor_len
)
1016 proto_tree_add_text(tree
, tvb
, offset
, descriptor_len
-offset
, "Descriptor data");
1017 /* offset = descriptor_len; */
1021 proto_item_append_text(item
, " (Entity %d)", entity_id
);
1023 if (subtype
!= VC_HEADER
&& usb_conv_info
)
1025 /* Switch to the usb_conv_info of the Video Control interface */
1026 usb_conv_info
= get_usb_iface_conv_info(pinfo
, usb_conv_info
->interfaceNum
);
1027 video_conv_info
= (video_conv_info_t
*)usb_conv_info
->class_data
;
1029 if (!video_conv_info
)
1031 video_conv_info
= wmem_new(wmem_file_scope(), video_conv_info_t
);
1032 video_conv_info
->entities
= wmem_tree_new(wmem_file_scope());
1033 usb_conv_info
->class_data
= video_conv_info
;
1036 entity
= (video_entity_t
*) wmem_tree_lookup32(video_conv_info
->entities
, entity_id
);
1039 entity
= wmem_new(wmem_file_scope(), video_entity_t
);
1040 entity
->entityID
= entity_id
;
1041 entity
->subtype
= subtype
;
1042 entity
->terminalType
= terminal_type
;
1044 wmem_tree_insert32(video_conv_info
->entities
, entity_id
, entity
);
1048 return descriptor_len
;
1051 /*****************************************************************************/
1052 /* VIDEO STREAMING DESCRIPTORS */
1053 /*****************************************************************************/
1055 /* Dissect a Video Streaming Input Header descriptor */
1057 dissect_usb_video_streaming_input_header(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
1062 static const int *info_bits
[] = {
1063 &hf_usb_vid_streaming_info_D
[0],
1066 static const int *control_bits
[] = {
1067 &hf_usb_vid_streaming_control_D
[0],
1068 &hf_usb_vid_streaming_control_D
[1],
1069 &hf_usb_vid_streaming_control_D
[2],
1070 &hf_usb_vid_streaming_control_D
[3],
1071 &hf_usb_vid_streaming_control_D
[4],
1072 &hf_usb_vid_streaming_control_D
[5],
1076 DISSECTOR_ASSERT(array_length(control_bits
) == (1+array_length(hf_usb_vid_streaming_control_D
)));
1078 num_formats
= tvb_get_guint8(tvb
, offset
);
1079 proto_tree_add_item(tree
, hf_usb_vid_streaming_ifdesc_bNumFormats
, tvb
, offset
, 1, ENC_NA
);
1080 proto_tree_add_item(tree
, hf_usb_vid_ifdesc_wTotalLength
, tvb
, offset
+1, 2, ENC_LITTLE_ENDIAN
);
1083 dissect_usb_endpoint_address(tree
, tvb
, offset
);
1086 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_streaming_bmInfo
,
1087 ett_streaming_info
, info_bits
, ENC_NA
);
1089 proto_tree_add_item(tree
, hf_usb_vid_streaming_terminal_link
, tvb
, offset
+1, 1, ENC_NA
);
1090 proto_tree_add_item(tree
, hf_usb_vid_streaming_still_capture_method
, tvb
, offset
+2, 1, ENC_NA
);
1093 proto_tree_add_item(tree
, hf_usb_vid_streaming_trigger_support
, tvb
, offset
, 1, ENC_NA
);
1094 if (tvb_get_guint8(tvb
, offset
) > 0)
1096 proto_tree_add_item(tree
, hf_usb_vid_streaming_trigger_usage
, tvb
, offset
+1, 1, ENC_NA
);
1100 proto_tree_add_text(tree
, tvb
, offset
+1, 1, "bTriggerUsage: Not applicable");
1105 /* NOTE: Can't use dissect_bmControl here because there's only one size
1106 * field for (potentially) multiple bmControl fields
1108 bm_size
= tvb_get_guint8(tvb
, offset
);
1109 proto_tree_add_item(tree
, hf_usb_vid_bControlSize
, tvb
, offset
, 1, ENC_NA
);
1115 for (i
=0; i
<num_formats
; ++i
)
1117 proto_tree_add_bitmask_len(tree
, tvb
, offset
, bm_size
, hf_usb_vid_bmControl
,
1118 ett_streaming_controls
, control_bits
, &ei_usb_vid_bitmask_len
,
1128 * Dissect a known Video Payload Format descriptor.
1130 * @param tree protocol tree to which fields should be added
1131 * @param tvb the tv_buff with the (remaining) packet data
1132 * @param offset where in tvb to begin dissection.
1133 * On entry this refers to the bFormatIndex field.
1134 * @param subtype Type of format descriptor, from the
1135 * bDescriptorSubtype field
1137 * @return offset within tvb at which dissection should continue
1140 dissect_usb_video_format(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
,
1143 static const int *interlace_bits
[] = {
1144 &hf_usb_vid_is_interlaced
,
1145 &hf_usb_vid_interlaced_fields
,
1146 &hf_usb_vid_field_1_first
,
1147 &hf_usb_vid_field_pattern
,
1151 proto_item
*desc_item
;
1152 guint8 format_index
;
1154 /* Augment the descriptor root item with the index of this descriptor */
1155 format_index
= tvb_get_guint8(tvb
, offset
);
1156 desc_item
= proto_tree_get_parent(tree
);
1157 proto_item_append_text(desc_item
, " (Format %u)", format_index
);
1159 proto_tree_add_item(tree
, hf_usb_vid_format_index
, tvb
, offset
, 1, ENC_NA
);
1160 proto_tree_add_item(tree
, hf_usb_vid_format_num_frame_descriptors
, tvb
, offset
+1, 1, ENC_NA
);
1163 if ((subtype
== VS_FORMAT_UNCOMPRESSED
) || (subtype
== VS_FORMAT_FRAME_BASED
))
1165 /* Augment the descriptor root item with the format's four-character-code */
1167 tvb_memcpy(tvb
, (guint8
*)fourcc
, offset
, 4);
1169 proto_item_append_text(desc_item
, ": %s", fourcc
);
1171 proto_tree_add_item(tree
, hf_usb_vid_format_guid
, tvb
, offset
, 16, ENC_LITTLE_ENDIAN
);
1172 proto_tree_add_item(tree
, hf_usb_vid_format_bits_per_pixel
, tvb
, offset
+16, 1, ENC_NA
);
1175 else if (subtype
== VS_FORMAT_MJPEG
)
1177 proto_item
*flags_item
= NULL
;
1178 proto_tree
*flags_tree
= NULL
;
1181 flags_item
= proto_tree_add_item(tree
, hf_usb_vid_mjpeg_flags
, tvb
, offset
, 1, ENC_NA
);
1182 flags_tree
= proto_item_add_subtree(flags_item
, ett_mjpeg_flags
);
1184 bmFlags
= tvb_get_guint8(tvb
, offset
);
1186 proto_tree_add_boolean(flags_tree
, hf_usb_vid_mjpeg_fixed_samples
, tvb
, offset
, 1, bmFlags
);
1191 /* We should only be called for known format descriptor subtypes */
1192 DISSECTOR_ASSERT_NOT_REACHED();
1195 proto_tree_add_item(tree
, hf_usb_vid_default_frame_index
, tvb
, offset
, 1, ENC_NA
);
1196 proto_tree_add_item(tree
, hf_usb_vid_aspect_ratio_x
, tvb
, offset
+1, 1, ENC_NA
);
1197 proto_tree_add_item(tree
, hf_usb_vid_aspect_ratio_y
, tvb
, offset
+2, 1, ENC_NA
);
1201 /* @todo Display "N/A" if Camera Terminal does not support scanning mode control */
1203 proto_tree_add_text(tree
, tvb
, offset
, 1, "bmInterlaceFlags: Not applicable");
1206 proto_tree_add_bitmask_text(tree
, tvb
, offset
, 1, "bmInterlaceFlags", NULL
,
1207 ett_interlace_flags
, interlace_bits
, ENC_NA
,
1211 proto_tree_add_item(tree
, hf_usb_vid_copy_protect
, tvb
, offset
, 1, ENC_NA
);
1214 if (subtype
== VS_FORMAT_FRAME_BASED
)
1216 proto_tree_add_item(tree
, hf_usb_vid_variable_size
, tvb
, offset
, 1, ENC_NA
);
1224 * Dissect a known Video Frame descriptor.
1226 * @param tree protocol tree to which fields should be added
1227 * @param tvb the tv_buff with the (remaining) packet data
1228 * @param offset where in tvb to begin dissection.
1229 * On entry this refers to the bFrameIndex field.
1230 * @param subtype Type of frame descriptor, from the
1231 * bDescriptorSubtype field
1233 * @return offset within tvb at which dissection should continue
1236 dissect_usb_video_frame(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
,
1239 static const int *capability_bits
[] = {
1240 &hf_usb_vid_frame_stills_supported
,
1241 &hf_usb_vid_frame_fixed_frame_rate
,
1244 proto_item
*desc_item
;
1245 guint8 bFrameIntervalType
;
1247 guint16 frame_width
;
1248 guint16 frame_height
;
1250 frame_index
= tvb_get_guint8(tvb
, offset
);
1251 proto_tree_add_item(tree
, hf_usb_vid_frame_index
, tvb
, offset
, 1, ENC_NA
);
1254 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_frame_capabilities
,
1255 ett_frame_capability_flags
, capability_bits
, ENC_NA
);
1258 proto_tree_add_item(tree
, hf_usb_vid_frame_width
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1259 proto_tree_add_item(tree
, hf_usb_vid_frame_height
, tvb
, offset
+2, 2, ENC_LITTLE_ENDIAN
);
1261 /* Augment the descriptor root item with useful information */
1262 frame_width
= tvb_get_letohs(tvb
, offset
);
1263 frame_height
= tvb_get_letohs(tvb
, offset
+2);
1264 desc_item
= proto_tree_get_parent(tree
);
1265 proto_item_append_text(desc_item
, " (Index %2u): %4u x %4u", frame_index
, frame_width
, frame_height
);
1267 proto_tree_add_item(tree
, hf_usb_vid_frame_min_bit_rate
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
1268 proto_tree_add_item(tree
, hf_usb_vid_frame_max_bit_rate
, tvb
, offset
+8, 4, ENC_LITTLE_ENDIAN
);
1271 if (subtype
!= VS_FRAME_FRAME_BASED
)
1273 proto_tree_add_item(tree
, hf_usb_vid_frame_max_frame_sz
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1277 proto_tree_add_item(tree
, hf_usb_vid_frame_default_interval
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1280 bFrameIntervalType
= tvb_get_guint8(tvb
, offset
);
1281 if (bFrameIntervalType
== 0)
1283 proto_tree_add_uint_format_value(tree
, hf_usb_vid_frame_interval_type
, tvb
, offset
, 1,
1284 bFrameIntervalType
, "Continuous (0)");
1287 if (subtype
== VS_FRAME_FRAME_BASED
)
1289 proto_tree_add_item(tree
, hf_usb_vid_frame_bytes_per_line
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1293 proto_tree_add_item(tree
, hf_usb_vid_frame_min_interval
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1294 proto_tree_add_item(tree
, hf_usb_vid_frame_max_interval
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
1295 proto_tree_add_item(tree
, hf_usb_vid_frame_step_interval
, tvb
, offset
+8, 4, ENC_LITTLE_ENDIAN
);
1301 proto_tree_add_uint_format_value(tree
, hf_usb_vid_frame_interval_type
, tvb
, offset
, 1,
1302 bFrameIntervalType
, "Discrete (%u choice%s)",
1303 bFrameIntervalType
, (bFrameIntervalType
> 1) ? "s" : "");
1306 if (subtype
== VS_FRAME_FRAME_BASED
)
1308 proto_tree_add_item(tree
, hf_usb_vid_frame_bytes_per_line
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1312 for (i
=0; i
<bFrameIntervalType
; ++i
)
1314 proto_tree_add_item(tree
, hf_usb_vid_frame_interval
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1322 /* Dissect a Color Matching descriptor */
1324 dissect_usb_video_colorformat(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
1326 proto_tree_add_item(tree
, hf_usb_vid_color_primaries
, tvb
, offset
, 1, ENC_NA
);
1327 proto_tree_add_item(tree
, hf_usb_vid_transfer_characteristics
, tvb
, offset
+1, 1, ENC_NA
);
1328 proto_tree_add_item(tree
, hf_usb_vid_matrix_coefficients
, tvb
, offset
+2, 1, ENC_NA
);
1335 * Dissector for video class streaming interface descriptors.
1337 * @param parent_tree the protocol tree to be the parent of the descriptor subtree
1338 * @param tvb the tv_buff with the (remaining) packet data
1339 * On entry the gaze is set to the descriptor length field.
1340 * @param descriptor_len Length of the descriptor to dissect
1342 * @return offset within tvb at which dissection should continue
1345 dissect_usb_video_streaming_interface_descriptor(proto_tree
*parent_tree
, tvbuff_t
*tvb
,
1346 guint8 descriptor_len
)
1351 const gchar
* subtype_str
;
1354 subtype
= tvb_get_guint8(tvb
, offset
+2);
1356 subtype_str
= val_to_str_ext(subtype
, &vs_if_descriptor_subtypes_ext
, "Unknown (0x%x)");
1357 item
= proto_tree_add_text(parent_tree
, tvb
, offset
, descriptor_len
,
1358 "VIDEO STREAMING INTERFACE DESCRIPTOR [%s]",
1360 tree
= proto_item_add_subtree(item
, ett_descriptor_video_streaming
);
1362 dissect_usb_descriptor_header(tree
, tvb
, offset
, &vid_descriptor_type_vals_ext
);
1363 proto_tree_add_item(tree
, hf_usb_vid_streaming_ifdesc_subtype
, tvb
, offset
+2, 1, ENC_NA
);
1368 case VS_INPUT_HEADER
:
1369 offset
= dissect_usb_video_streaming_input_header(tree
, tvb
, offset
);
1372 case VS_FORMAT_UNCOMPRESSED
:
1373 case VS_FORMAT_MJPEG
:
1374 case VS_FORMAT_FRAME_BASED
:
1375 offset
= dissect_usb_video_format(tree
, tvb
, offset
, subtype
);
1378 /* @todo MPEG2, H.264, VP8, Still Image Frame */
1379 /* @todo Obsolete UVC-1.0 descriptors? */
1381 case VS_FRAME_UNCOMPRESSED
:
1382 case VS_FRAME_MJPEG
:
1383 case VS_FRAME_FRAME_BASED
:
1384 offset
= dissect_usb_video_frame(tree
, tvb
, offset
, subtype
);
1387 case VS_COLORFORMAT
:
1388 offset
= dissect_usb_video_colorformat(tree
, tvb
, offset
);
1395 /* Soak up descriptor bytes beyond those we know how to dissect */
1396 if (offset
< descriptor_len
)
1397 proto_tree_add_text(tree
, tvb
, offset
, descriptor_len
-offset
, "Descriptor data");
1399 return descriptor_len
;
1402 /*****************************************************************************/
1405 * Dissector for video class-specific endpoint descriptor.
1407 * @param parent_tree the protocol tree to be the parent of the descriptor subtree
1408 * @param tvb the tv_buff with the (remaining) packet data
1409 * On entry the gaze is set to the descriptor length field.
1410 * @param descriptor_len Length of the descriptor to dissect
1412 * @return offset within tvb at which dissection should continue
1415 dissect_usb_video_endpoint_descriptor(proto_tree
*parent_tree
, tvbuff_t
*tvb
,
1416 guint8 descriptor_len
)
1418 proto_item
*item
= NULL
;
1419 proto_tree
*tree
= NULL
;
1423 subtype
= tvb_get_guint8(tvb
, offset
+2);
1427 const gchar
* subtype_str
;
1429 subtype_str
= val_to_str(subtype
, vc_ep_descriptor_subtypes
, "Unknown (0x%x)");
1430 item
= proto_tree_add_text(parent_tree
, tvb
, offset
, descriptor_len
,
1431 "VIDEO CONTROL ENDPOINT DESCRIPTOR [%s]",
1433 tree
= proto_item_add_subtree(item
, ett_descriptor_video_endpoint
);
1436 dissect_usb_descriptor_header(tree
, tvb
, offset
, &vid_descriptor_type_vals_ext
);
1437 proto_tree_add_item(tree
, hf_usb_vid_epdesc_subtype
, tvb
, offset
+2, 1, ENC_NA
);
1440 if (subtype
== EP_INTERRUPT
)
1442 proto_tree_add_item(tree
, hf_usb_vid_epdesc_max_transfer_sz
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1446 /* Soak up descriptor bytes beyond those we know how to dissect */
1447 if (offset
< descriptor_len
)
1448 proto_tree_add_text(tree
, tvb
, offset
, descriptor_len
-offset
, "Descriptor data");
1450 return descriptor_len
;
1454 * Registered dissector for video class-specific descriptors
1456 * @param tvb the tv_buff with the (remaining) packet data
1457 * On entry the gaze is set to the descriptor length field.
1458 * @param pinfo the packet info of this packet (additional info)
1459 * @param tree the protocol tree to be built or NULL
1460 * @param data Not used
1462 * @return 0 no class specific dissector was found
1463 * @return <0 not enough data
1464 * @return >0 amount of data in the descriptor
1467 dissect_usb_vid_descriptor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1470 guint8 descriptor_len
;
1471 guint8 descriptor_type
;
1472 gint bytes_available
;
1473 usb_conv_info_t
*usb_conv_info
= (usb_conv_info_t
*)data
;
1477 descriptor_len
= tvb_get_guint8(tvb
, offset
);
1478 descriptor_type
= tvb_get_guint8(tvb
, offset
+1);
1480 bytes_available
= tvb_length_remaining(tvb
, offset
);
1481 desc_tvb
= tvb_new_subset(tvb
, 0, bytes_available
, descriptor_len
);
1483 if (descriptor_type
== CS_ENDPOINT
)
1485 offset
= dissect_usb_video_endpoint_descriptor(tree
, desc_tvb
,
1488 else if (descriptor_type
== CS_INTERFACE
)
1490 if (usb_conv_info
->interfaceSubclass
== SC_VIDEOCONTROL
)
1492 offset
= dissect_usb_video_control_interface_descriptor(tree
, desc_tvb
,
1494 pinfo
, usb_conv_info
);
1496 else if (usb_conv_info
->interfaceSubclass
== SC_VIDEOSTREAMING
)
1498 offset
= dissect_usb_video_streaming_interface_descriptor(tree
, desc_tvb
,
1502 /* else not something we recognize, just return offset = 0 */
1507 /*****************************************************************************/
1508 /* CONTROL TRANSFERS */
1509 /*****************************************************************************/
1512 * Dissect GET/SET transactions on the Video Probe and Commit controls.
1514 * @param parent_tree protocol tree to which the probe/commit subtree should be added
1515 * @param tvb the tv_buff with the (remaining) packet data
1516 * @param offset where in tvb to begin dissection.
1517 * On entry this refers to the probe/commit bmHint field.
1519 * @return offset within tvb at which dissection should continue
1522 dissect_usb_vid_probe(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
)
1524 proto_tree
*tree
= NULL
;
1526 static const int *hint_bits
[] = {
1527 &hf_usb_vid_probe_hint_D
[0],
1528 &hf_usb_vid_probe_hint_D
[1],
1529 &hf_usb_vid_probe_hint_D
[2],
1530 &hf_usb_vid_probe_hint_D
[3],
1531 &hf_usb_vid_probe_hint_D
[4],
1535 DISSECTOR_ASSERT(array_length(hint_bits
) == (1+array_length(hf_usb_vid_probe_hint_D
)));
1541 item
= proto_tree_add_text(parent_tree
, tvb
, offset
, -1, "Probe/Commit Info");
1542 tree
= proto_item_add_subtree(item
, ett_video_probe
);
1545 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_probe_hint
,
1546 ett_probe_hint
, hint_bits
, ENC_LITTLE_ENDIAN
);
1548 proto_tree_add_item(tree
, hf_usb_vid_format_index
, tvb
, offset
+2, 1, ENC_NA
);
1549 proto_tree_add_item(tree
, hf_usb_vid_frame_index
, tvb
, offset
+3, 1, ENC_NA
);
1550 proto_tree_add_item(tree
, hf_usb_vid_frame_interval
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
1551 proto_tree_add_item(tree
, hf_usb_vid_probe_key_frame_rate
, tvb
, offset
+8, 2, ENC_LITTLE_ENDIAN
);
1552 proto_tree_add_item(tree
, hf_usb_vid_probe_p_frame_rate
, tvb
, offset
+10, 2, ENC_LITTLE_ENDIAN
);
1553 proto_tree_add_item(tree
, hf_usb_vid_probe_comp_quality
, tvb
, offset
+12, 2, ENC_LITTLE_ENDIAN
);
1554 proto_tree_add_item(tree
, hf_usb_vid_probe_comp_window
, tvb
, offset
+14, 2, ENC_LITTLE_ENDIAN
);
1555 proto_tree_add_item(tree
, hf_usb_vid_probe_delay
, tvb
, offset
+16, 2, ENC_LITTLE_ENDIAN
);
1556 proto_tree_add_item(tree
, hf_usb_vid_probe_max_frame_sz
, tvb
, offset
+18, 4, ENC_LITTLE_ENDIAN
);
1557 proto_tree_add_item(tree
, hf_usb_vid_probe_max_payload_sz
, tvb
, offset
+22, 4, ENC_LITTLE_ENDIAN
);
1560 /* UVC 1.1 fields */
1561 if (tvb_length_remaining(tvb
, offset
) > 0)
1563 static const int *framing_bits
[] = {
1564 &hf_usb_vid_probe_framing_D
[0],
1565 &hf_usb_vid_probe_framing_D
[1],
1569 DISSECTOR_ASSERT(array_length(framing_bits
) == (1+array_length(hf_usb_vid_probe_framing_D
)));
1571 proto_tree_add_item(tree
, hf_usb_vid_probe_clock_freq
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1574 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_probe_framing
,
1575 ett_probe_framing
, framing_bits
, ENC_NA
);
1578 proto_tree_add_item(tree
, hf_usb_vid_probe_preferred_ver
, tvb
, offset
, 1, ENC_NA
);
1579 proto_tree_add_item(tree
, hf_usb_vid_probe_min_ver
, tvb
, offset
+1, 1, ENC_NA
);
1580 proto_tree_add_item(tree
, hf_usb_vid_probe_max_ver
, tvb
, offset
+2, 1, ENC_NA
);
1588 * Fetch the table that describes known control selectors for the specified unit/terminal.
1590 * @param entity_id Unit or terminal of interest
1591 * @param usb_conv_info Information about the interface the entity is part of
1593 * @return Table describing control selectors for the specified entity (may be NULL)
1595 static const value_string_ext
*
1596 get_control_selector_values(guint8 entity_id
, usb_conv_info_t
*usb_conv_info
)
1598 video_conv_info_t
*video_conv_info
;
1599 video_entity_t
*entity
= NULL
;
1600 const value_string_ext
*selectors
= NULL
;
1602 video_conv_info
= (video_conv_info_t
*)usb_conv_info
->class_data
;
1603 if (video_conv_info
)
1604 entity
= (video_entity_t
*) wmem_tree_lookup32(video_conv_info
->entities
, entity_id
);
1608 /* Interface Request*/
1609 switch (usb_conv_info
->interfaceSubclass
)
1611 case SC_VIDEOCONTROL
:
1612 selectors
= &cs_control_interface_ext
;
1615 case SC_VIDEOSTREAMING
:
1616 selectors
= &cs_streaming_interface_ext
;
1625 switch (entity
->subtype
)
1627 case VC_INPUT_TERMINAL
:
1628 if (entity
->terminalType
== ITT_CAMERA
)
1630 selectors
= &cs_camera_terminal_ext
;
1634 case VC_PROCESSING_UNIT
:
1635 selectors
= &cs_processing_unit_ext
;
1638 case VC_SELECTOR_UNIT
:
1639 selectors
= &cs_selector_unit_ext
;
1651 * Fetch the name of an entity's control.
1653 * @param entity_id Unit or terminal of interest
1654 * @param control_sel Control of interest
1655 * @param usb_conv_info Information about the interface the entity is part of
1657 * @return Table describing control selectors for the specified entity (may be NULL)
1660 get_control_selector_name(guint8 entity_id
, guint8 control_sel
, usb_conv_info_t
*usb_conv_info
)
1662 const gchar
*control_name
= NULL
;
1663 const value_string_ext
*selectors
= NULL
;
1665 selectors
= get_control_selector_values(entity_id
, usb_conv_info
);
1668 control_name
= try_val_to_str_ext(control_sel
, selectors
);
1670 return control_name
;
1673 /* Dissect the response to a GET INFO request */
1675 dissect_usb_vid_control_info(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
1677 static const int *capability_bits
[] = {
1678 &hf_usb_vid_control_info_D
[0],
1679 &hf_usb_vid_control_info_D
[1],
1680 &hf_usb_vid_control_info_D
[2],
1681 &hf_usb_vid_control_info_D
[3],
1682 &hf_usb_vid_control_info_D
[4],
1683 &hf_usb_vid_control_info_D
[5],
1684 &hf_usb_vid_control_info_D
[6],
1688 DISSECTOR_ASSERT(array_length(capability_bits
) == (1+array_length(hf_usb_vid_control_info_D
)));
1690 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_usb_vid_control_info
,
1691 ett_control_capabilities
, capability_bits
, ENC_NA
);
1696 /* Dissect all remaining bytes in the tvb as a specified type of UVC value.
1697 * These are displayed as an unsigned integer where possible, otherwise just as
1700 * @param tree the protocol tree to which an item will be added
1701 * @param tvb the tv_buff with the (remaining) packet data
1702 * @param offset How far into tvb the value data begins
1703 * @param request Identifies type of value - either bRequest from a CONTROL
1704 * transfer (i.e., USB_SETUP_GET_MAX), or bValue from an
1705 * INTERRUPT transfer (i.e., CONTROL_CHANGE_MAX).
1708 dissect_usb_vid_control_value(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, guint8 request
)
1711 const char* fallback_name
;
1716 case USB_SETUP_GET_DEF
:
1717 hf
= hf_usb_vid_control_default
;
1718 fallback_name
= "Default Value";
1721 case USB_SETUP_GET_MIN
:
1722 case CONTROL_CHANGE_MIN
:
1723 hf
= hf_usb_vid_control_min
;
1724 fallback_name
= "Min Value";
1727 case USB_SETUP_GET_MAX
:
1728 case CONTROL_CHANGE_MAX
:
1729 hf
= hf_usb_vid_control_max
;
1730 fallback_name
= "Max Value";
1733 case USB_SETUP_GET_RES
:
1734 hf
= hf_usb_vid_control_res
;
1735 fallback_name
= "Resolution";
1738 case USB_SETUP_GET_CUR
:
1739 case USB_SETUP_SET_CUR
:
1740 case CONTROL_CHANGE_VALUE
:
1741 hf
= hf_usb_vid_control_cur
;
1742 fallback_name
= "Current Value";
1745 /* @todo UVC 1.5 USB_SETUP_x_ALL?
1746 * They are poorly specified.
1751 fallback_name
= "Value";
1755 value_size
= tvb_reported_length_remaining(tvb
, offset
);
1759 header_field_info
*hfinfo
;
1760 hfinfo
= proto_registrar_get_nth(hf
);
1761 DISSECTOR_ASSERT(IS_FT_INT(hfinfo
->type
) || IS_FT_UINT(hfinfo
->type
));
1764 if ((hf
!= -1) && (value_size
<= 4))
1766 proto_tree_add_item(tree
, hf
, tvb
, offset
, value_size
, ENC_LITTLE_ENDIAN
);
1770 /* @todo Display as FT_BYTES with a big-endian disclaimer?
1771 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7933
1773 proto_tree_add_text(tree
, tvb
, offset
, value_size
, "%s", fallback_name
);
1778 * Dissect video class GET/SET transactions.
1780 * @param pinfo Information associated with the packet being dissected
1781 * @param tree protocol tree to which fields should be added
1782 * @param tvb the tv_buff with the (remaining) packet data
1783 * @param offset where in tvb to begin dissection.
1784 * On entry this refers to the bRequest field of the SETUP
1786 * @param is_request true if the packet is host-to-device,
1787 * false if device-to-host
1788 * @param usb_trans_info Information specific to this request/response pair
1789 * @param usb_conv_info Information about the conversation with the host
1792 dissect_usb_vid_get_set(packet_info
*pinfo
, proto_tree
*tree
, tvbuff_t
*tvb
,
1793 int offset
, gboolean is_request
,
1794 usb_trans_info_t
*usb_trans_info
,
1795 usb_conv_info_t
*usb_conv_info
)
1797 const gchar
*short_name
= NULL
;
1801 entity_id
= usb_trans_info
->setup
.wIndex
>> 8;
1802 control_sel
= usb_trans_info
->setup
.wValue
>> 8;
1804 /* Display something informative in the INFO column */
1805 col_append_str(pinfo
->cinfo
, COL_INFO
, " [");
1806 short_name
= get_control_selector_name(entity_id
, control_sel
, usb_conv_info
);
1809 col_append_str(pinfo
->cinfo
, COL_INFO
, short_name
);
1812 short_name
= "Unknown";
1816 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Interface %u control 0x%x",
1817 usb_conv_info
->interfaceNum
, control_sel
);
1821 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Unit %u control 0x%x",
1822 entity_id
, control_sel
);
1826 col_append_str(pinfo
->cinfo
, COL_INFO
, "]");
1827 col_set_fence(pinfo
->cinfo
, COL_INFO
);
1829 /* Add information on request context,
1830 * as GENERATED fields if not directly available (for filtering)
1834 /* Move gaze to control selector (MSB of wValue) */
1836 proto_tree_add_uint_format_value(tree
, hf_usb_vid_control_selector
, tvb
,
1837 offset
, 1, control_sel
, "%s (0x%02x)", short_name
, control_sel
);
1840 proto_tree_add_item(tree
, hf_usb_vid_control_interface
, tvb
, offset
, 1, ENC_NA
);
1843 proto_tree_add_item(tree
, hf_usb_vid_control_entity
, tvb
, offset
, 1, ENC_NA
);
1846 proto_tree_add_item(tree
, hf_usb_vid_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1849 /* If there is an extended pseudo header, skip over it to reach the payload */
1850 if ((usb_trans_info
->setup
.request
== USB_SETUP_SET_CUR
) && usb_trans_info
->header_len_64
)
1857 ti
= proto_tree_add_uint(tree
, hf_usb_vid_control_interface
, tvb
, 0, 0,
1858 usb_trans_info
->setup
.wIndex
& 0xFF);
1859 PROTO_ITEM_SET_GENERATED(ti
);
1861 ti
= proto_tree_add_uint(tree
, hf_usb_vid_control_entity
, tvb
, 0, 0, entity_id
);
1862 PROTO_ITEM_SET_GENERATED(ti
);
1864 ti
= proto_tree_add_uint_format_value(tree
, hf_usb_vid_control_selector
, tvb
,
1865 0, 0, control_sel
, "%s (0x%02x)", short_name
, control_sel
);
1866 PROTO_ITEM_SET_GENERATED(ti
);
1869 if (!is_request
|| (usb_trans_info
->setup
.request
== USB_SETUP_SET_CUR
))
1871 gint value_size
= tvb_reported_length_remaining(tvb
, offset
);
1873 if (value_size
!= 0)
1875 if ((entity_id
== 0) && (usb_conv_info
->interfaceSubclass
== SC_VIDEOSTREAMING
))
1877 if ((control_sel
== VS_PROBE_CONTROL
) || (control_sel
== VS_COMMIT_CONTROL
))
1879 int old_offset
= offset
;
1880 offset
= dissect_usb_vid_probe(tree
, tvb
, offset
);
1881 value_size
-= (offset
- old_offset
);
1886 if (usb_trans_info
->setup
.request
== USB_SETUP_GET_INFO
)
1888 dissect_usb_vid_control_info(tree
, tvb
, offset
);
1892 else if (usb_trans_info
->setup
.request
== USB_SETUP_GET_LEN
)
1894 proto_tree_add_item(tree
, hf_usb_vid_control_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1898 else if ( (usb_trans_info
->setup
.request
== USB_SETUP_GET_CUR
)
1900 && (usb_conv_info
->interfaceSubclass
== SC_VIDEOCONTROL
)
1901 && (control_sel
== VC_REQUEST_ERROR_CODE_CONTROL
))
1903 proto_tree_add_item(tree
, hf_usb_vid_request_error
, tvb
, offset
, 1, ENC_NA
);
1909 dissect_usb_vid_control_value(tree
, tvb
, offset
, usb_trans_info
->setup
.request
);
1910 offset
+= value_size
;
1917 proto_tree_add_text(tree
, tvb
, offset
, -1, "Control data");
1918 offset
+= value_size
;
1926 /* Table for dispatch of video class SETUP transactions based on bRequest.
1927 * At the moment this is overkill since the same function handles all defined
1930 typedef int (*usb_setup_dissector
)(packet_info
*pinfo
, proto_tree
*tree
,
1931 tvbuff_t
*tvb
, int offset
,
1932 gboolean is_request
,
1933 usb_trans_info_t
*usb_trans_info
,
1934 usb_conv_info_t
*usb_conv_info
);
1936 typedef struct _usb_setup_dissector_table_t
1939 usb_setup_dissector dissector
;
1940 } usb_setup_dissector_table_t
;
1942 static const usb_setup_dissector_table_t setup_dissectors
[] = {
1943 {USB_SETUP_SET_CUR
, dissect_usb_vid_get_set
},
1944 {USB_SETUP_SET_CUR_ALL
, dissect_usb_vid_get_set
},
1945 {USB_SETUP_GET_CUR
, dissect_usb_vid_get_set
},
1946 {USB_SETUP_GET_MIN
, dissect_usb_vid_get_set
},
1947 {USB_SETUP_GET_MAX
, dissect_usb_vid_get_set
},
1948 {USB_SETUP_GET_RES
, dissect_usb_vid_get_set
},
1949 {USB_SETUP_GET_LEN
, dissect_usb_vid_get_set
},
1950 {USB_SETUP_GET_INFO
, dissect_usb_vid_get_set
},
1951 {USB_SETUP_GET_DEF
, dissect_usb_vid_get_set
},
1952 {USB_SETUP_GET_CUR_ALL
, dissect_usb_vid_get_set
},
1953 {USB_SETUP_GET_MIN_ALL
, dissect_usb_vid_get_set
},
1954 {USB_SETUP_GET_MAX_ALL
, dissect_usb_vid_get_set
},
1955 {USB_SETUP_GET_RES_ALL
, dissect_usb_vid_get_set
},
1959 static const value_string setup_request_names_vals
[] = {
1960 {USB_SETUP_SET_CUR
, "SET CUR"},
1961 {USB_SETUP_SET_CUR_ALL
, "SET CUR ALL"},
1962 {USB_SETUP_GET_CUR
, "GET CUR"},
1963 {USB_SETUP_GET_MIN
, "GET MIN"},
1964 {USB_SETUP_GET_MAX
, "GET MAX"},
1965 {USB_SETUP_GET_RES
, "GET RES"},
1966 {USB_SETUP_GET_LEN
, "GET LEN"},
1967 {USB_SETUP_GET_INFO
, "GET INFO"},
1968 {USB_SETUP_GET_DEF
, "GET DEF"},
1969 {USB_SETUP_GET_CUR_ALL
, "GET CUR ALL"},
1970 {USB_SETUP_GET_MIN_ALL
, "GET MIN ALL"},
1971 {USB_SETUP_GET_MAX_ALL
, "GET MAX ALL"},
1972 {USB_SETUP_GET_RES_ALL
, "GET RES ALL"},
1973 {USB_SETUP_GET_DEF_ALL
, "GET DEF ALL"},
1977 /* Registered dissector for video class-specific control requests.
1978 * Dispatch to an appropriate dissector function.
1980 * @param tvb the tv_buff with the (remaining) packet data.
1981 * On entry, the gaze is set to SETUP bRequest field.
1982 * @param pinfo the packet info of this packet (additional info)
1983 * @param tree the protocol tree to be built or NULL
1984 * @param data Not used
1986 * @return 0 no class specific dissector was found
1987 * @return <0 not enough data
1988 * @return >0 amount of data in the descriptor
1991 dissect_usb_vid_control(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1993 gboolean is_request
= (pinfo
->srcport
== NO_ENDPOINT
);
1994 usb_conv_info_t
*usb_conv_info
= (usb_conv_info_t
*)data
;
1995 usb_trans_info_t
*usb_trans_info
= usb_conv_info
->usb_trans_info
;
1997 usb_setup_dissector dissector
= NULL
;
1998 const usb_setup_dissector_table_t
*tmp
;
2000 /* See if we can find a class specific dissector for this request */
2001 for (tmp
=setup_dissectors
; tmp
->dissector
; tmp
++)
2003 if (tmp
->request
== usb_trans_info
->setup
.request
)
2005 dissector
= tmp
->dissector
;
2009 /* No we could not find any class specific dissector for this request
2010 * return FALSE and let USB try any of the standard requests.
2015 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "USBVIDEO");
2016 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s %s",
2017 val_to_str(usb_trans_info
->setup
.request
, setup_request_names_vals
, "Unknown type %x"),
2018 is_request
?"Request ":"Response");
2022 proto_tree_add_item(tree
, hf_usb_vid_request
, tvb
, offset
, 1, ENC_NA
);
2026 offset
= dissector(pinfo
, tree
, tvb
, offset
, is_request
, usb_trans_info
, usb_conv_info
);
2030 /* Registered dissector for video class-specific URB_INTERRUPT
2032 * @param tvb the tv_buff with the (remaining) packet data
2033 * @param pinfo the packet info of this packet (additional info)
2034 * @param tree the protocol tree to be built or NULL
2035 * @param data Unused API parameter
2037 * @return 0 no class specific dissector was found
2038 * @return <0 not enough data
2039 * @return >0 amount of data in the descriptor
2042 dissect_usb_vid_interrupt(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
2044 usb_conv_info_t
*usb_conv_info
;
2045 gint bytes_available
;
2048 usb_conv_info
= (usb_conv_info_t
*)data
;
2049 bytes_available
= tvb_length_remaining(tvb
, offset
);
2051 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "USBVIDEO");
2053 if (bytes_available
> 0)
2055 guint8 originating_interface
;
2056 guint8 originating_entity
;
2058 originating_interface
= tvb_get_guint8(tvb
, offset
) & INT_ORIGINATOR_MASK
;
2059 proto_tree_add_item(tree
, hf_usb_vid_interrupt_bStatusType
, tvb
, offset
, 1, ENC_NA
);
2062 originating_entity
= tvb_get_guint8(tvb
, offset
);
2063 proto_tree_add_item(tree
, hf_usb_vid_interrupt_bOriginator
, tvb
, offset
, 1, ENC_NA
);
2066 if (originating_interface
== INT_VIDEOCONTROL
)
2070 const gchar
*control_name
;
2072 proto_tree_add_item(tree
, hf_usb_vid_control_interrupt_bEvent
, tvb
, offset
, 1, ENC_NA
);
2075 control_sel
= tvb_get_guint8(tvb
, offset
);
2076 control_name
= get_control_selector_name(originating_entity
, control_sel
, usb_conv_info
);
2078 control_name
= "Unknown";
2080 proto_tree_add_uint_format_value(tree
, hf_usb_vid_control_selector
, tvb
,
2081 offset
, 1, control_sel
, "%s (0x%02x)",
2082 control_name
, control_sel
);
2085 attribute
= tvb_get_guint8(tvb
, offset
);
2086 proto_tree_add_item(tree
, hf_usb_vid_interrupt_bAttribute
, tvb
, offset
, 1, ENC_NA
);
2091 case CONTROL_CHANGE_FAILURE
:
2092 proto_tree_add_item(tree
, hf_usb_vid_request_error
, tvb
, offset
, 1, ENC_NA
);
2096 case CONTROL_CHANGE_INFO
:
2097 offset
= dissect_usb_vid_control_info(tree
, tvb
, offset
);
2100 case CONTROL_CHANGE_VALUE
:
2101 case CONTROL_CHANGE_MIN
:
2102 case CONTROL_CHANGE_MAX
:
2103 dissect_usb_vid_control_value(tree
, tvb
, offset
, attribute
);
2104 offset
+= tvb_reported_length_remaining(tvb
, offset
);
2108 proto_tree_add_text(tree
, tvb
, offset
, -1, "Value data");
2109 offset
+= tvb_reported_length_remaining(tvb
, offset
);
2113 else if (originating_interface
== INT_VIDEOSTREAMING
)
2125 proto_register_usb_vid(void)
2127 static hf_register_info hf
[] = {
2129 { &hf_usb_vid_request
,
2130 { "bRequest", "usbvideo.setup.bRequest", FT_UINT8
, BASE_HEX
, VALS(setup_request_names_vals
), 0x0,
2134 { &hf_usb_vid_length
,
2135 { "wLength", "usbvideo.setup.wLength", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2139 /***** Request Error Control *****/
2140 { &hf_usb_vid_request_error
,
2141 { "bRequestErrorCode", "usbvideo.reqerror.code",
2142 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
2143 &request_error_codes_ext
, 0,
2144 "Request Error Code", HFILL
}
2147 /***** Unit/Terminal Controls *****/
2148 { &hf_usb_vid_control_selector
,
2149 { "Control Selector", "usbvideo.control.selector", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2150 "ID of the control within its entity", HFILL
}
2153 { &hf_usb_vid_control_entity
,
2154 { "Entity", "usbvideo.control.entity", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2155 "Unit or terminal to which the control belongs", HFILL
}
2158 { &hf_usb_vid_control_interface
,
2159 { "Interface", "usbvideo.control.interface", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2160 "Interface to which the control belongs", HFILL
}
2163 { &hf_usb_vid_control_info
,
2164 { "Info (Capabilities/State)", "usbvideo.control.info",
2165 FT_UINT8
, BASE_HEX
, NULL
, 0,
2166 "Control capabilities and current state", HFILL
}
2169 { &hf_usb_vid_control_info_D
[0],
2170 { "Supports GET", "usbvideo.control.info.D0",
2171 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<0),
2175 { &hf_usb_vid_control_info_D
[1],
2176 { "Supports SET", "usbvideo.control.info.D1",
2177 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<1),
2181 { &hf_usb_vid_control_info_D
[2],
2182 { "Disabled due to automatic mode", "usbvideo.control.info.D2",
2183 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<2),
2187 { &hf_usb_vid_control_info_D
[3],
2188 { "Autoupdate", "usbvideo.control.info.D3",
2189 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<3),
2193 { &hf_usb_vid_control_info_D
[4],
2194 { "Asynchronous", "usbvideo.control.info.D4",
2195 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<4),
2199 { &hf_usb_vid_control_info_D
[5],
2200 { "Disabled due to incompatibility with Commit state", "usbvideo.control.info.D5",
2201 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<5),
2205 { &hf_usb_vid_control_info_D
[6],
2206 { "Reserved", "usbvideo.control.info.D6",
2207 FT_UINT8
, BASE_HEX
, NULL
, (3<<6),
2211 { &hf_usb_vid_control_length
,
2212 { "Control Length", "usbvideo.control.len",
2213 FT_UINT16
, BASE_DEC
, NULL
, 0,
2214 "Control size in bytes", HFILL
}
2217 { &hf_usb_vid_control_default
,
2218 { "Default value", "usbvideo.control.value.default",
2219 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0,
2223 { &hf_usb_vid_control_min
,
2224 { "Minimum value", "usbvideo.control.value.min",
2225 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0,
2229 { &hf_usb_vid_control_max
,
2230 { "Maximum value", "usbvideo.control.value.max",
2231 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0,
2235 { &hf_usb_vid_control_res
,
2236 { "Resolution", "usbvideo.control.value.res",
2237 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0,
2241 { &hf_usb_vid_control_cur
,
2242 { "Current value", "usbvideo.control.value.cur",
2243 FT_UINT32
, BASE_DEC_HEX
, NULL
, 0,
2247 /***** Terminal Descriptors *****/
2249 /* @todo Decide whether to unify .name fields */
2250 { &hf_usb_vid_control_ifdesc_iTerminal
,
2251 { "iTerminal", "usbvideo.terminal.name", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2252 "String Descriptor describing this terminal", HFILL
}
2255 /* @todo Decide whether to unify .terminal.id and .unit.id under .entityID */
2256 { &hf_usb_vid_control_ifdesc_terminal_id
,
2257 { "bTerminalID", "usbvideo.terminal.id", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2261 { &hf_usb_vid_control_ifdesc_terminal_type
,
2262 { "wTerminalType", "usbvideo.terminal.type",
2263 FT_UINT16
, BASE_HEX
| BASE_EXT_STRING
, &vc_terminal_types_ext
, 0,
2267 { &hf_usb_vid_control_ifdesc_assoc_terminal
,
2268 { "bAssocTerminal", "usbvideo.terminal.assocTerminal", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2269 "Associated Terminal", HFILL
}
2272 /***** Camera Terminal Descriptor *****/
2274 { &hf_usb_vid_cam_objective_focal_len_min
,
2275 { "wObjectiveFocalLengthMin", "usbvideo.camera.objectiveFocalLengthMin",
2276 FT_UINT16
, BASE_DEC
, NULL
, 0,
2277 "Minimum Focal Length for Optical Zoom", HFILL
}
2280 { &hf_usb_vid_cam_objective_focal_len_max
,
2281 { "wObjectiveFocalLengthMax", "usbvideo.camera.objectiveFocalLengthMax",
2282 FT_UINT16
, BASE_DEC
, NULL
, 0,
2283 "Minimum Focal Length for Optical Zoom", HFILL
}
2286 { &hf_usb_vid_cam_ocular_focal_len
,
2287 { "wOcularFocalLength", "usbvideo.camera.ocularFocalLength",
2288 FT_UINT16
, BASE_DEC
, NULL
, 0,
2289 "Ocular Focal Length for Optical Zoom", HFILL
}
2292 { &hf_usb_vid_cam_control_D
[0],
2293 { "Scanning Mode", "usbvideo.camera.control.D0",
2295 array_length(hf_usb_vid_cam_control_D
),
2296 TFS(&tfs_yes_no
), (1<<0),
2300 { &hf_usb_vid_cam_control_D
[1],
2301 { "Auto Exposure Mode", "usbvideo.camera.control.D1",
2303 array_length(hf_usb_vid_cam_control_D
),
2304 TFS(&tfs_yes_no
), (1<<1),
2308 { &hf_usb_vid_cam_control_D
[2],
2309 { "Auto Exposure Priority", "usbvideo.camera.control.D2",
2311 array_length(hf_usb_vid_cam_control_D
),
2312 TFS(&tfs_yes_no
), (1<<2),
2316 { &hf_usb_vid_cam_control_D
[3],
2317 { "Exposure Time (Absolute)", "usbvideo.camera.control.D3",
2319 array_length(hf_usb_vid_cam_control_D
),
2320 TFS(&tfs_yes_no
), (1<<3),
2324 { &hf_usb_vid_cam_control_D
[4],
2325 { "Exposure Time (Relative)", "usbvideo.camera.control.D4",
2327 array_length(hf_usb_vid_cam_control_D
),
2328 TFS(&tfs_yes_no
), (1<<4),
2332 { &hf_usb_vid_cam_control_D
[5],
2333 { "Focus (Absolute)", "usbvideo.camera.control.D5",
2335 array_length(hf_usb_vid_cam_control_D
),
2336 TFS(&tfs_yes_no
), (1<<5),
2340 { &hf_usb_vid_cam_control_D
[6],
2341 { "Focus (Relative)", "usbvideo.camera.control.D6",
2343 array_length(hf_usb_vid_cam_control_D
),
2344 TFS(&tfs_yes_no
), (1<<6),
2348 { &hf_usb_vid_cam_control_D
[7],
2349 { "Iris (Absolute)", "usbvideo.camera.control.D7",
2351 array_length(hf_usb_vid_cam_control_D
),
2352 TFS(&tfs_yes_no
), (1<<7),
2356 { &hf_usb_vid_cam_control_D
[8],
2357 { "Iris (Relative)", "usbvideo.camera.control.D8",
2359 array_length(hf_usb_vid_cam_control_D
),
2360 TFS(&tfs_yes_no
), (1<<8),
2364 { &hf_usb_vid_cam_control_D
[9],
2365 { "Zoom (Absolute)", "usbvideo.camera.control.D9",
2367 array_length(hf_usb_vid_cam_control_D
),
2368 TFS(&tfs_yes_no
), (1<<9),
2372 { &hf_usb_vid_cam_control_D
[10],
2373 { "Zoom (Relative)", "usbvideo.camera.control.D10",
2375 array_length(hf_usb_vid_cam_control_D
),
2376 TFS(&tfs_yes_no
), (1<<10),
2380 { &hf_usb_vid_cam_control_D
[11],
2381 { "PanTilt (Absolute)", "usbvideo.camera.control.D11",
2383 array_length(hf_usb_vid_cam_control_D
),
2384 TFS(&tfs_yes_no
), (1<<11),
2388 { &hf_usb_vid_cam_control_D
[12],
2389 { "PanTilt (Relative)", "usbvideo.camera.control.D12",
2391 array_length(hf_usb_vid_cam_control_D
),
2392 TFS(&tfs_yes_no
), (1<<12),
2396 { &hf_usb_vid_cam_control_D
[13],
2397 { "Roll (Absolute)", "usbvideo.camera.control.D13",
2399 array_length(hf_usb_vid_cam_control_D
),
2400 TFS(&tfs_yes_no
), (1<<13),
2404 { &hf_usb_vid_cam_control_D
[14],
2405 { "Roll (Relative)", "usbvideo.camera.control.D14",
2407 array_length(hf_usb_vid_cam_control_D
),
2408 TFS(&tfs_yes_no
), (1<<14),
2412 { &hf_usb_vid_cam_control_D
[15],
2413 { "D15", "usbvideo.camera.control.D15",
2415 array_length(hf_usb_vid_cam_control_D
),
2416 TFS(&tfs_yes_no
), (1<<15),
2420 { &hf_usb_vid_cam_control_D
[16],
2421 { "D16", "usbvideo.camera.control.D16",
2423 array_length(hf_usb_vid_cam_control_D
),
2424 TFS(&tfs_yes_no
), (1<<16),
2428 { &hf_usb_vid_cam_control_D
[17],
2429 { "Auto Focus", "usbvideo.camera.control.D17",
2431 array_length(hf_usb_vid_cam_control_D
),
2432 TFS(&tfs_yes_no
), (1<<17),
2436 { &hf_usb_vid_cam_control_D
[18],
2437 { "Privacy", "usbvideo.camera.control.D18",
2439 array_length(hf_usb_vid_cam_control_D
),
2440 TFS(&tfs_yes_no
), (1<<18),
2444 { &hf_usb_vid_cam_control_D
[19],
2445 { "Focus (Simple)", "usbvideo.camera.control.D19",
2447 array_length(hf_usb_vid_cam_control_D
),
2448 TFS(&tfs_yes_no
), (1<<19),
2452 { &hf_usb_vid_cam_control_D
[20],
2453 { "Window", "usbvideo.camera.control.D20",
2455 array_length(hf_usb_vid_cam_control_D
),
2456 TFS(&tfs_yes_no
), (1<<20),
2460 { &hf_usb_vid_cam_control_D
[21],
2461 { "Region of Interest", "usbvideo.camera.control.D21",
2463 array_length(hf_usb_vid_cam_control_D
),
2464 TFS(&tfs_yes_no
), (1<<21),
2468 /***** Unit Descriptors *****/
2470 { &hf_usb_vid_control_ifdesc_unit_id
,
2471 { "bUnitID", "usbvideo.unit.id", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2475 { &hf_usb_vid_num_inputs
,
2476 { "bNrInPins", "usbvideo.unit.numInputs",
2477 FT_UINT8
, BASE_DEC
, NULL
, 0,
2478 "Number of input pins", HFILL
}
2481 { &hf_usb_vid_sources
,
2482 { "baSourceID", "usbvideo.unit.sources",
2483 FT_BYTES
, BASE_NONE
, NULL
, 0,
2484 "Input entity IDs", HFILL
}
2488 /***** Processing Unit Descriptor *****/
2490 { &hf_usb_vid_iProcessing
,
2491 { "iProcessing", "usbvideo.processor.name", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2492 "String Descriptor describing this terminal", HFILL
}
2495 { &hf_usb_vid_proc_control_D
[0],
2496 { "Brightness", "usbvideo.processor.control.D0",
2497 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<0),
2501 { &hf_usb_vid_proc_control_D
[1],
2502 { "Contrast", "usbvideo.processor.control.D1",
2503 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<1),
2507 { &hf_usb_vid_proc_control_D
[2],
2508 { "Hue", "usbvideo.processor.control.D2",
2509 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<2),
2513 { &hf_usb_vid_proc_control_D
[3],
2514 { "Saturation", "usbvideo.processor.control.D3",
2515 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<3),
2519 { &hf_usb_vid_proc_control_D
[4],
2520 { "Sharpness", "usbvideo.processor.control.D4",
2521 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<4),
2525 { &hf_usb_vid_proc_control_D
[5],
2526 { "Gamma", "usbvideo.processor.control.D5",
2527 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<5),
2531 { &hf_usb_vid_proc_control_D
[6],
2532 { "White Balance Temperature", "usbvideo.processor.control.D6",
2533 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<6),
2537 { &hf_usb_vid_proc_control_D
[7],
2538 { "White Balance Component", "usbvideo.processor.control.D7",
2539 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<7),
2543 { &hf_usb_vid_proc_control_D
[8],
2544 { "Backlight Compensation", "usbvideo.processor.control.D8",
2545 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<8),
2549 { &hf_usb_vid_proc_control_D
[9],
2550 { "Gain", "usbvideo.processor.control.D9",
2551 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<9),
2555 { &hf_usb_vid_proc_control_D
[10],
2556 { "Power Line Frequency", "usbvideo.processor.control.D10",
2557 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<10),
2561 { &hf_usb_vid_proc_control_D
[11],
2562 { "Hue, Auto", "usbvideo.processor.control.D11",
2563 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<11),
2567 { &hf_usb_vid_proc_control_D
[12],
2568 { "White Balance Temperature, Auto", "usbvideo.processor.control.D12",
2569 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<12),
2573 { &hf_usb_vid_proc_control_D
[13],
2574 { "White Balance Component, Auto", "usbvideo.processor.control.D13",
2575 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<13),
2579 { &hf_usb_vid_proc_control_D
[14],
2580 { "Digital Multiplier", "usbvideo.processor.control.D14",
2581 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<14),
2585 { &hf_usb_vid_proc_control_D
[15],
2586 { "Digital Multiplier Limit", "usbvideo.processor.control.D15",
2587 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<15),
2591 { &hf_usb_vid_proc_control_D
[16],
2592 { "Analog Video Standard", "usbvideo.processor.control.D16",
2593 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<16),
2597 { &hf_usb_vid_proc_control_D
[17],
2598 { "Analog Video Lock Status", "usbvideo.processor.control.D17",
2599 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<17),
2603 { &hf_usb_vid_proc_control_D
[18],
2604 { "Contrast, Auto", "usbvideo.processor.control.D18",
2605 FT_BOOLEAN
, 24, TFS(&tfs_yes_no
), (1<<18),
2609 { &hf_usb_vid_proc_standards
,
2610 { "bmVideoStandards", "usbvideo.processor.standards",
2611 FT_UINT8
, BASE_HEX
, NULL
, 0,
2612 "Supported analog video standards", HFILL
}
2615 { &hf_usb_vid_proc_standards_D
[0],
2616 { "None", "usbvideo.processor.standards.D0",
2617 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<0),
2621 { &hf_usb_vid_proc_standards_D
[1],
2622 { "NTSC - 525/60", "usbvideo.processor.standards.D1",
2623 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<1),
2627 { &hf_usb_vid_proc_standards_D
[2],
2628 { "PAL - 625/50", "usbvideo.processor.standards.D2",
2629 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<2),
2633 { &hf_usb_vid_proc_standards_D
[3],
2634 { "SECAM - 625/50", "usbvideo.processor.standards.D3",
2635 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<3),
2639 { &hf_usb_vid_proc_standards_D
[4],
2640 { "NTSC - 625/50", "usbvideo.processor.standards.D4",
2641 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<4),
2645 { &hf_usb_vid_proc_standards_D
[5],
2646 { "PAL - 525/60", "usbvideo.processor.standards.D5",
2647 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<5),
2651 { &hf_usb_vid_max_multiplier
,
2652 { "wMaxMultiplier", "usbvideo.processor.maxMultiplier",
2653 FT_UINT16
, BASE_DEC
, NULL
, 0,
2654 "100 x max digital multiplication", HFILL
}
2657 /***** Selector Unit Descriptor *****/
2659 { &hf_usb_vid_iSelector
,
2660 { "iSelector", "usbvideo.selector.name", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2661 "String Descriptor describing this terminal", HFILL
}
2664 /***** Extension Unit Descriptor *****/
2666 { &hf_usb_vid_iExtension
,
2667 { "iExtension", "usbvideo.extension.name", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2668 "String Descriptor describing this terminal", HFILL
}
2671 { &hf_usb_vid_exten_guid
,
2672 { "guid", "usbvideo.extension.guid",
2673 FT_GUID
, BASE_NONE
, NULL
, 0,
2674 "Identifier", HFILL
}
2677 { &hf_usb_vid_exten_num_controls
,
2678 { "bNumControls", "usbvideo.extension.numControls",
2679 FT_UINT8
, BASE_DEC
, NULL
, 0,
2680 "Number of controls", HFILL
}
2683 /***** Probe/Commit *****/
2685 { &hf_usb_vid_probe_hint
,
2686 { "bmHint", "usbvideo.probe.hint",
2687 FT_UINT16
, BASE_HEX
, NULL
, 0,
2688 "Fields to hold constant during negotiation", HFILL
}
2691 { &hf_usb_vid_probe_hint_D
[0],
2692 { "dwFrameInterval", "usbvideo.probe.hint.D0",
2693 FT_BOOLEAN
, 5, TFS(&probe_hint_meaning
), (1<<0),
2694 "Frame Rate", HFILL
}
2696 { &hf_usb_vid_probe_hint_D
[1],
2697 { "wKeyFrameRate", "usbvideo.probe.hint.D1",
2698 FT_BOOLEAN
, 5, TFS(&probe_hint_meaning
), (1<<1),
2699 "Key Frame Rate", HFILL
}
2701 { &hf_usb_vid_probe_hint_D
[2],
2702 { "wPFrameRate", "usbvideo.probe.hint.D2",
2703 FT_BOOLEAN
, 5, TFS(&probe_hint_meaning
), (1<<2),
2704 "P-Frame Rate", HFILL
}
2706 { &hf_usb_vid_probe_hint_D
[3],
2707 { "wCompQuality", "usbvideo.probe.hint.D3",
2708 FT_BOOLEAN
, 5, TFS(&probe_hint_meaning
), (1<<3),
2709 "Compression Quality", HFILL
}
2711 { &hf_usb_vid_probe_hint_D
[4],
2712 { "wCompWindowSize", "usbvideo.probe.hint.D4",
2713 FT_BOOLEAN
, 5, TFS(&probe_hint_meaning
), (1<<4),
2714 "Compression Window Size", HFILL
}
2717 { &hf_usb_vid_probe_key_frame_rate
,
2718 { "wKeyFrameRate", "usbvideo.probe.keyFrameRate",
2719 FT_UINT16
, BASE_DEC
, NULL
, 0,
2720 "Key frame rate", HFILL
}
2723 { &hf_usb_vid_probe_p_frame_rate
,
2724 { "wPFrameRate", "usbvideo.probe.pFrameRate",
2725 FT_UINT16
, BASE_DEC
, NULL
, 0,
2726 "P frame rate", HFILL
}
2729 { &hf_usb_vid_probe_comp_quality
,
2730 { "wCompQuality", "usbvideo.probe.compQuality",
2731 FT_UINT16
, BASE_DEC
, NULL
, 0,
2732 "Compression quality [0-10000]", HFILL
}
2735 { &hf_usb_vid_probe_comp_window
,
2736 { "wCompWindow", "usbvideo.probe.compWindow",
2737 FT_UINT16
, BASE_DEC
, NULL
, 0,
2738 "Window size for average bit rate control", HFILL
}
2740 { &hf_usb_vid_probe_delay
,
2741 { "wDelay", "usbvideo.probe.delay",
2742 FT_UINT16
, BASE_DEC
, NULL
, 0,
2743 "Latency in ms from capture to USB", HFILL
}
2745 { &hf_usb_vid_probe_max_frame_sz
,
2746 { "dwMaxVideoFrameSize", "usbvideo.probe.maxVideoFrameSize",
2747 FT_UINT32
, BASE_DEC
, NULL
, 0,
2750 { &hf_usb_vid_probe_max_payload_sz
,
2751 { "dwMaxPayloadTransferSize", "usbvideo.probe.maxPayloadTransferSize",
2752 FT_UINT32
, BASE_DEC
, NULL
, 0,
2755 { &hf_usb_vid_probe_clock_freq
,
2756 { "dwClockFrequency", "usbvideo.probe.clockFrequency",
2757 FT_UINT32
, BASE_DEC
, NULL
, 0,
2758 "Device clock frequency in Hz", HFILL
}
2761 { &hf_usb_vid_probe_framing
,
2762 { "bmFramingInfo", "usbvideo.probe.framing",
2763 FT_UINT16
, BASE_HEX
, NULL
, 0,
2767 { &hf_usb_vid_probe_framing_D
[0],
2768 { "Frame ID required", "usbvideo.probe.framing.D0",
2769 FT_BOOLEAN
, 2, TFS(&tfs_yes_no
), (1<<0),
2772 { &hf_usb_vid_probe_framing_D
[1],
2773 { "EOF utilized", "usbvideo.probe.framing.D1",
2774 FT_BOOLEAN
, 2, TFS(&tfs_yes_no
), (1<<1),
2778 { &hf_usb_vid_probe_preferred_ver
,
2779 { "bPreferredVersion", "usbvideo.probe.preferredVersion",
2780 FT_UINT8
, BASE_DEC
, NULL
, 0,
2781 "Preferred payload format version", HFILL
}
2783 { &hf_usb_vid_probe_min_ver
,
2784 { "bMinVersion", "usbvideo.probe.minVersion",
2785 FT_UINT8
, BASE_DEC
, NULL
, 0,
2786 "Min supported payload format version", HFILL
}
2788 { &hf_usb_vid_probe_max_ver
,
2789 { "bPreferredVersion", "usbvideo.probe.maxVer",
2790 FT_UINT8
, BASE_DEC
, NULL
, 0,
2791 "Max supported payload format version", HFILL
}
2794 { &hf_usb_vid_control_ifdesc_dwClockFrequency
,
2795 { "dwClockFrequency", "usbvideo.probe.clockFrequency",
2796 FT_UINT32
, BASE_DEC
, NULL
, 0,
2797 "Device clock frequency (Hz) for selected format", HFILL
}
2800 /***** Format Descriptors *****/
2802 { &hf_usb_vid_format_index
,
2803 { "bFormatIndex", "usbvideo.format.index",
2804 FT_UINT8
, BASE_DEC
, NULL
, 0,
2805 "Index of this format descriptor", HFILL
}
2808 { &hf_usb_vid_format_num_frame_descriptors
,
2809 { "bNumFrameDescriptors", "usbvideo.format.numFrameDescriptors",
2810 FT_UINT8
, BASE_DEC
, NULL
, 0,
2811 "Number of frame descriptors for this format", HFILL
}
2814 { &hf_usb_vid_format_guid
,
2815 { "guidFormat", "usbvideo.format.guid",
2816 FT_GUID
, BASE_NONE
, NULL
, 0,
2817 "Stream encoding format", HFILL
}
2820 { &hf_usb_vid_format_bits_per_pixel
,
2821 { "bBitsPerPixel", "usbvideo.format.bitsPerPixel",
2822 FT_UINT8
, BASE_DEC
, NULL
, 0,
2823 "Bits per pixel", HFILL
}
2826 { &hf_usb_vid_default_frame_index
,
2827 { "bDefaultFrameIndex", "usbvideo.format.defaultFrameIndex",
2828 FT_UINT8
, BASE_DEC
, NULL
, 0,
2829 "Optimum frame index for this stream", HFILL
}
2832 { &hf_usb_vid_aspect_ratio_x
,
2833 { "bAspectRatioX", "usbvideo.format.aspectRatioX",
2834 FT_UINT8
, BASE_DEC
, NULL
, 0,
2835 "X dimension of picture aspect ratio", HFILL
}
2838 { &hf_usb_vid_aspect_ratio_y
,
2839 { "bAspectRatioY", "usbvideo.format.aspectRatioY",
2840 FT_UINT8
, BASE_DEC
, NULL
, 0,
2841 "Y dimension of picture aspect ratio", HFILL
}
2844 { &hf_usb_vid_is_interlaced
,
2845 { "Interlaced stream", "usbvideo.format.interlace.D0",
2846 FT_BOOLEAN
, 8, TFS(&is_interlaced_meaning
), (1<<0),
2850 { &hf_usb_vid_interlaced_fields
,
2851 { "Fields per frame", "usbvideo.format.interlace.D1",
2852 FT_BOOLEAN
, 8, TFS(&interlaced_fields_meaning
), (1<<1),
2856 { &hf_usb_vid_field_1_first
,
2857 { "Field 1 first", "usbvideo.format.interlace.D2",
2858 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<2),
2862 { &hf_usb_vid_field_pattern
,
2863 { "Field pattern", "usbvideo.format.interlace.pattern",
2864 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
2865 &field_pattern_meaning_ext
, (3<<4),
2869 { &hf_usb_vid_copy_protect
,
2870 { "bCopyProtect", "usbvideo.format.copyProtect",
2871 FT_UINT8
, BASE_DEC
, VALS(copy_protect_meaning
), 0,
2875 { &hf_usb_vid_variable_size
,
2876 { "Variable size", "usbvideo.format.variableSize",
2877 FT_BOOLEAN
, BASE_DEC
, NULL
, 0,
2881 /***** MJPEG Format Descriptor *****/
2883 { &hf_usb_vid_mjpeg_flags
,
2884 { "bmFlags", "usbvideo.mjpeg.flags",
2885 FT_UINT8
, BASE_HEX
, NULL
, 0,
2886 "Characteristics", HFILL
}
2889 { &hf_usb_vid_mjpeg_fixed_samples
,
2890 { "Fixed size samples", "usbvideo.mjpeg.fixed_size",
2891 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<0),
2895 /***** Frame Descriptors *****/
2897 { &hf_usb_vid_frame_index
,
2898 { "bFrameIndex", "usbvideo.frame.index",
2899 FT_UINT8
, BASE_DEC
, NULL
, 0,
2900 "Index of this frame descriptor", HFILL
}
2903 { &hf_usb_vid_frame_capabilities
,
2904 { "bmCapabilities", "usbvideo.frame.capabilities",
2905 FT_UINT8
, BASE_HEX
, NULL
, 0,
2906 "Capabilities", HFILL
}
2909 { &hf_usb_vid_frame_stills_supported
,
2910 { "Still image", "usbvideo.frame.stills",
2911 FT_BOOLEAN
, 8, TFS(&tfs_supported_not_supported
), (1<<0),
2915 { &hf_usb_vid_frame_interval
,
2916 { "dwFrameInterval", "usbvideo.frame.interval",
2917 FT_UINT32
, BASE_DEC
, NULL
, 0,
2918 "Frame interval multiple of 100 ns", HFILL
}
2921 { &hf_usb_vid_frame_fixed_frame_rate
,
2922 { "Fixed frame rate", "usbvideo.frame.fixedRate",
2923 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<1),
2926 { &hf_usb_vid_frame_width
,
2927 { "wWidth", "usbvideo.frame.width",
2928 FT_UINT16
, BASE_DEC
, NULL
, 0,
2929 "Width of frame in pixels", HFILL
}
2931 { &hf_usb_vid_frame_height
,
2932 { "wHeight", "usbvideo.frame.height",
2933 FT_UINT16
, BASE_DEC
, NULL
, 0,
2934 "Height of frame in pixels", HFILL
}
2936 { &hf_usb_vid_frame_min_bit_rate
,
2937 { "dwMinBitRate", "usbvideo.frame.minBitRate",
2938 FT_UINT32
, BASE_DEC
, NULL
, 0,
2939 "Minimum bit rate in bps", HFILL
}
2941 { &hf_usb_vid_frame_max_bit_rate
,
2942 { "dwMaxBitRate", "usbvideo.frame.maxBitRate",
2943 FT_UINT32
, BASE_DEC
, NULL
, 0,
2944 "Maximum bit rate in bps", HFILL
}
2947 { &hf_usb_vid_frame_max_frame_sz
,
2948 { "dwMaxVideoFrameBufferSize", "usbvideo.frame.maxBuffer",
2949 FT_UINT32
, BASE_DEC
, NULL
, 0,
2950 "Maximum bytes per frame", HFILL
}
2952 { &hf_usb_vid_frame_default_interval
,
2953 { "dwDefaultFrameInterval", "usbvideo.frame.interval.default",
2954 FT_UINT32
, BASE_DEC
, NULL
, 0,
2955 "Suggested default", HFILL
}
2958 { &hf_usb_vid_frame_interval_type
,
2959 { "bFrameIntervalType", "usbvideo.frame.interval.type",
2960 FT_UINT8
, BASE_DEC
, NULL
, 0,
2961 "Frame rate control (continuous/discrete)", HFILL
}
2964 { &hf_usb_vid_frame_min_interval
,
2965 { "dwMinFrameInterval", "usbvideo.frame.interval.min",
2966 FT_UINT32
, BASE_DEC
, NULL
, 0,
2967 "Shortest frame interval (* 100 ns)", HFILL
}
2970 { &hf_usb_vid_frame_max_interval
,
2971 { "dwMaxFrameInterval", "usbvideo.frame.interval.max",
2972 FT_UINT32
, BASE_DEC
, NULL
, 0,
2973 "Longest frame interval (* 100 ns)", HFILL
}
2975 { &hf_usb_vid_frame_step_interval
,
2976 { "dwMinFrameInterval", "usbvideo.frame.interval.step",
2977 FT_UINT32
, BASE_DEC
, NULL
, 0,
2978 "Granularity of frame interval (* 100 ns)", HFILL
}
2981 { &hf_usb_vid_frame_bytes_per_line
,
2982 { "dwBytesPerLine", "usbvideo.frame.bytesPerLine",
2983 FT_UINT32
, BASE_DEC
, NULL
, 0,
2984 "Fixed number of bytes per video line", HFILL
}
2987 /***** Colorformat Descriptor *****/
2989 { &hf_usb_vid_color_primaries
,
2990 { "bColorPrimaries", "usbvideo.color.primaries",
2991 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
2992 &color_primaries_meaning_ext
, 0,
2996 { &hf_usb_vid_transfer_characteristics
,
2997 { "bTransferCharacteristics", "usbvideo.color.transferCharacteristics",
2998 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
2999 &color_transfer_characteristics_ext
, 0,
3003 { &hf_usb_vid_matrix_coefficients
,
3004 { "bMatrixCoefficients", "usbvideo.color.matrixCoefficients",
3005 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
3006 &matrix_coefficients_meaning_ext
, 0,
3010 /***** Video Control Header Descriptor *****/
3012 { &hf_usb_vid_control_ifdesc_bcdUVC
,
3013 { "bcdUVC", "usbvideo.bcdUVC",
3014 FT_UINT16
, BASE_HEX
, NULL
, 0,
3015 "Video Device Class Specification release number", HFILL
}
3018 { &hf_usb_vid_control_ifdesc_bInCollection
,
3019 { "bInCollection", "usbvideo.numStreamingInterfaces",
3020 FT_UINT8
, BASE_DEC
, NULL
, 0,
3021 "Number of VideoStreaming interfaces", HFILL
}
3024 { &hf_usb_vid_control_ifdesc_baInterfaceNr
,
3025 { "baInterfaceNr", "usbvideo.streamingInterfaceNumbers",
3026 FT_BYTES
, BASE_NONE
, NULL
, 0,
3027 "Interface numbers of VideoStreaming interfaces", HFILL
}},
3029 /***** Video Streaming Input Header Descriptor *****/
3031 { &hf_usb_vid_streaming_ifdesc_bNumFormats
,
3032 { "bNumFormats", "usbvideo.streaming.numFormats",
3033 FT_UINT8
, BASE_DEC
, NULL
, 0,
3034 "Number of video payload format descriptors", HFILL
}
3037 { &hf_usb_vid_streaming_bmInfo
,
3038 { "bmInfo", "usbvideo.streaming.info",
3039 FT_UINT8
, BASE_HEX
, NULL
, 0,
3040 "Capabilities", HFILL
}
3043 { &hf_usb_vid_streaming_info_D
[0],
3044 { "Dynamic Format Change", "usbvideo.streaming.info.D0",
3045 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), (1<<0),
3046 "Dynamic Format Change", HFILL
}
3049 { &hf_usb_vid_streaming_control_D
[0],
3050 { "wKeyFrameRate", "usbvideo.streaming.control.D0",
3051 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<0),
3052 "Probe and Commit support", HFILL
}
3055 { &hf_usb_vid_streaming_control_D
[1],
3056 { "wPFrameRate", "usbvideo.streaming.control.D1",
3057 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<1),
3058 "Probe and Commit support", HFILL
}
3061 { &hf_usb_vid_streaming_control_D
[2],
3062 { "wCompQuality", "usbvideo.streaming.control.D2",
3063 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<2),
3064 "Probe and Commit support", HFILL
}
3067 { &hf_usb_vid_streaming_control_D
[3],
3068 { "wCompWindowSize", "usbvideo.streaming.control.D3",
3069 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<3),
3070 "Probe and Commit support", HFILL
}
3073 { &hf_usb_vid_streaming_control_D
[4],
3074 { "Generate Key Frame", "usbvideo.streaming.control.D4",
3075 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<4),
3076 "Probe and Commit support", HFILL
}
3079 { &hf_usb_vid_streaming_control_D
[5],
3080 { "Update Frame Segment", "usbvideo.streaming.control.D5",
3081 FT_BOOLEAN
, 6, TFS(&tfs_yes_no
), (1<<5),
3082 "Probe and Commit support", HFILL
}
3085 { &hf_usb_vid_streaming_terminal_link
,
3086 { "bTerminalLink", "usbvideo.streaming.terminalLink", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3087 "Output terminal ID", HFILL
}
3090 { &hf_usb_vid_streaming_still_capture_method
,
3091 { "bStillCaptureMethod", "usbvideo.streaming.stillCaptureMethod",
3092 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
3093 &vs_still_capture_methods_ext
, 0,
3094 "Method of Still Image Capture", HFILL
}
3097 { &hf_usb_vid_streaming_trigger_support
,
3098 { "HW Triggering", "usbvideo.streaming.triggerSupport",
3099 FT_BOOLEAN
, BASE_DEC
, TFS(&tfs_supported_not_supported
), 0,
3100 "Is HW triggering supported", HFILL
}
3103 { &hf_usb_vid_streaming_trigger_usage
,
3104 { "bTriggerUsage", "usbvideo.streaming.triggerUsage",
3105 FT_UINT8
, BASE_DEC
, VALS(vs_trigger_usage
), 0,
3106 "How host SW should respond to trigger", HFILL
}
3109 /***** Interrupt URB *****/
3111 { &hf_usb_vid_interrupt_bStatusType
,
3112 { "Status Type", "usbvideo.interrupt.statusType",
3113 FT_UINT8
, BASE_HEX
, VALS(interrupt_status_types
), 0xF,
3117 { &hf_usb_vid_interrupt_bAttribute
,
3118 { "Change Type", "usbvideo.interrupt.attribute",
3119 FT_UINT8
, BASE_HEX
| BASE_EXT_STRING
,
3120 &control_change_types_ext
, 0,
3121 "Type of control change", HFILL
}
3124 { &hf_usb_vid_interrupt_bOriginator
,
3125 { "Originator", "usbvideo.interrupt.originator",
3126 FT_UINT8
, BASE_DEC
, NULL
, 0,
3127 "ID of the entity that reports this interrupt", HFILL
}
3130 { &hf_usb_vid_control_interrupt_bEvent
,
3131 { "Event", "usbvideo.interrupt.controlEvent",
3132 FT_UINT8
, BASE_HEX
, VALS(control_interrupt_events
), 0,
3133 "Type of event", HFILL
}
3136 /***** Video Control Endpoint Descriptor *****/
3138 { &hf_usb_vid_epdesc_subtype
,
3139 { "Subtype", "usbvideo.ep.descriptorSubType",
3140 FT_UINT8
, BASE_DEC
, VALS(vc_ep_descriptor_subtypes
), 0,
3141 "Descriptor Subtype", HFILL
}
3144 { &hf_usb_vid_epdesc_max_transfer_sz
,
3145 { "wMaxTransferSize", "usbvideo.ep.maxInterruptSize", FT_UINT16
,
3146 BASE_DEC
, NULL
, 0x0, "Max interrupt structure size", HFILL
}
3149 /***** Fields used in multiple contexts *****/
3151 { &hf_usb_vid_ifdesc_wTotalLength
,
3152 { "wTotalLength", "usbvideo.totalLength",
3153 FT_UINT16
, BASE_DEC
, NULL
, 0,
3154 "Video interface descriptor size", HFILL
}
3157 { &hf_usb_vid_bControlSize
,
3158 { "bControlSize", "usbvideo.bmcontrolSize",
3159 FT_UINT8
, BASE_DEC
, NULL
, 0,
3160 "Size of bmControls field", HFILL
}
3163 { &hf_usb_vid_bmControl
,
3164 { "bmControl", "usbvideo.availableControls",
3165 FT_UINT32
, BASE_HEX
, NULL
, 0,
3166 "Available controls", HFILL
}
3169 { &hf_usb_vid_control_ifdesc_src_id
,
3170 { "bSourceID", "usbvideo.sourceID", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3171 "Entity to which this terminal/unit is connected", HFILL
}
3176 { &hf_usb_vid_control_ifdesc_subtype
,
3177 { "Subtype", "usbvideo.control.descriptorSubType",
3178 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
3179 &vc_if_descriptor_subtypes_ext
, 0,
3180 "Descriptor Subtype", HFILL
}
3183 { &hf_usb_vid_streaming_ifdesc_subtype
,
3184 { "Subtype", "usbvideo.streaming.descriptorSubType",
3185 FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
,
3186 &vs_if_descriptor_subtypes_ext
, 0,
3187 "Descriptor Subtype", HFILL
}
3191 static gint
*usb_vid_subtrees
[] = {
3193 &ett_descriptor_video_endpoint
,
3194 &ett_descriptor_video_control
,
3195 &ett_descriptor_video_streaming
,
3196 &ett_camera_controls
,
3197 &ett_processing_controls
,
3198 &ett_streaming_controls
,
3199 &ett_streaming_info
,
3200 &ett_interlace_flags
,
3201 &ett_frame_capability_flags
,
3206 &ett_video_standards
,
3207 &ett_control_capabilities
3210 static ei_register_info ei
[] = {
3211 { &ei_usb_vid_subtype_unknown
, { "usbvideo.subtype.unknown", PI_UNDECODED
, PI_WARN
, "Unknown VC subtype", EXPFILL
}},
3212 { &ei_usb_vid_bitmask_len
, { "usbvideo.bitmask_len_error", PI_UNDECODED
, PI_WARN
, "Only least-significant bytes decoded", EXPFILL
}},
3215 expert_module_t
* expert_usb_vid
;
3217 proto_usb_vid
= proto_register_protocol("USB Video", "USBVIDEO", "usbvideo");
3218 proto_register_field_array(proto_usb_vid
, hf
, array_length(hf
));
3219 proto_register_subtree_array(usb_vid_subtrees
, array_length(usb_vid_subtrees
));
3220 expert_usb_vid
= expert_register_protocol(proto_usb_vid
);
3221 expert_register_field_array(expert_usb_vid
, ei
, array_length(ei
));
3225 proto_reg_handoff_usb_vid(void)
3227 dissector_handle_t usb_vid_control_handle
;
3228 dissector_handle_t usb_vid_descriptor_handle
;
3229 dissector_handle_t usb_vid_interrupt_handle
;
3231 usb_vid_control_handle
= new_create_dissector_handle(dissect_usb_vid_control
, proto_usb_vid
);
3232 dissector_add_uint("usb.control", IF_CLASS_VIDEO
, usb_vid_control_handle
);
3234 usb_vid_descriptor_handle
= new_create_dissector_handle(dissect_usb_vid_descriptor
, proto_usb_vid
);
3235 dissector_add_uint("usb.descriptor", IF_CLASS_VIDEO
, usb_vid_descriptor_handle
);
3237 usb_vid_interrupt_handle
= new_create_dissector_handle(dissect_usb_vid_interrupt
, proto_usb_vid
);
3238 dissector_add_uint("usb.interrupt", IF_CLASS_VIDEO
, usb_vid_interrupt_handle
);
3241 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3246 * indent-tabs-mode: nil
3249 * vi: set shiftwidth=4 tabstop=4 expandtab:
3250 * :indentSize=4:tabSize=4:noTabs=true: