dcerpc-netlogon: maintain netlogon_auth_vars for NetrServerAuthenticateKerberos
[wireshark-sm.git] / epan / dissectors / packet-usb-audio.c
blob8ac91ca785b4ec91bb8c4fd819cbe8465230e5b4
1 /* packet-usb-audio.c
3 * usb audio dissector
4 * Tomasz Mon 2012
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
9 /* the parsing of audio-specific descriptors is based on
10 USB Audio Device Class Specification for Basic Audio Devices, Release 1.0,
11 USB Device Class Definition for Audio Devices, Release 2.0 and
12 USB Device Class Definition for MIDI Devices, Release 1.0 */
14 #include "config.h"
16 #include <epan/packet.h>
17 #include <epan/expert.h>
18 #include <epan/reassemble.h>
19 #include "packet-usb.h"
21 /* XXX - we use the same macro for mpeg sections,
22 can we put this in a common include file? */
23 #define USB_AUDIO_BCD44_TO_DEC(x) ((((x)&0xf0) >> 4) * 10 + ((x)&0x0f))
25 void proto_register_usb_audio(void);
26 void proto_reg_handoff_usb_audio(void);
28 /* protocols and header fields */
29 static int proto_usb_audio;
30 static int hf_midi_cable_number;
31 static int hf_midi_code_index;
32 static int hf_midi_event;
33 static int hf_midi_padding;
34 static int hf_ac_if_desc_subtype;
35 static int hf_ac_if_hdr_ver;
36 static int hf_ac_if_hdr_total_len;
37 static int hf_ac_if_hdr_bInCollection;
38 static int hf_ac_if_hdr_if_num;
39 static int hf_ac_if_hdr_category;
40 static int hf_ac_if_hdr_controls;
41 static int hf_ac_if_hdr_controls_latency;
42 static int hf_ac_if_hdr_controls_rsv;
43 static int hf_ac_if_input_terminalid;
44 static int hf_ac_if_input_terminaltype;
45 static int hf_ac_if_input_assocterminal;
46 static int hf_ac_if_input_csourceid;
47 static int hf_ac_if_input_nrchannels;
48 static int hf_ac_if_input_wchannelconfig;
49 static int hf_ac_if_input_wchannelconfig_d0;
50 static int hf_ac_if_input_wchannelconfig_d1;
51 static int hf_ac_if_input_wchannelconfig_d2;
52 static int hf_ac_if_input_wchannelconfig_d3;
53 static int hf_ac_if_input_wchannelconfig_d4;
54 static int hf_ac_if_input_wchannelconfig_d5;
55 static int hf_ac_if_input_wchannelconfig_d6;
56 static int hf_ac_if_input_wchannelconfig_d7;
57 static int hf_ac_if_input_wchannelconfig_d8;
58 static int hf_ac_if_input_wchannelconfig_d9;
59 static int hf_ac_if_input_wchannelconfig_d10;
60 static int hf_ac_if_input_wchannelconfig_d11;
61 static int hf_ac_if_input_wchannelconfig_rsv;
62 static int hf_ac_if_input_bmchannelconfig;
63 static int hf_ac_if_input_bmchannelconfig_d0;
64 static int hf_ac_if_input_bmchannelconfig_d1;
65 static int hf_ac_if_input_bmchannelconfig_d2;
66 static int hf_ac_if_input_bmchannelconfig_d3;
67 static int hf_ac_if_input_bmchannelconfig_d4;
68 static int hf_ac_if_input_bmchannelconfig_d5;
69 static int hf_ac_if_input_bmchannelconfig_d6;
70 static int hf_ac_if_input_bmchannelconfig_d7;
71 static int hf_ac_if_input_bmchannelconfig_d8;
72 static int hf_ac_if_input_bmchannelconfig_d9;
73 static int hf_ac_if_input_bmchannelconfig_d10;
74 static int hf_ac_if_input_bmchannelconfig_d11;
75 static int hf_ac_if_input_bmchannelconfig_d12;
76 static int hf_ac_if_input_bmchannelconfig_d13;
77 static int hf_ac_if_input_bmchannelconfig_d14;
78 static int hf_ac_if_input_bmchannelconfig_d15;
79 static int hf_ac_if_input_bmchannelconfig_d16;
80 static int hf_ac_if_input_bmchannelconfig_d17;
81 static int hf_ac_if_input_bmchannelconfig_d18;
82 static int hf_ac_if_input_bmchannelconfig_d19;
83 static int hf_ac_if_input_bmchannelconfig_d20;
84 static int hf_ac_if_input_bmchannelconfig_d21;
85 static int hf_ac_if_input_bmchannelconfig_d22;
86 static int hf_ac_if_input_bmchannelconfig_d23;
87 static int hf_ac_if_input_bmchannelconfig_d24;
88 static int hf_ac_if_input_bmchannelconfig_d25;
89 static int hf_ac_if_input_bmchannelconfig_d26;
90 static int hf_ac_if_input_bmchannelconfig_rsv;
91 static int hf_ac_if_input_bmchannelconfig_d31;
92 static int hf_ac_if_input_channelnames;
93 static int hf_ac_if_input_controls;
94 static int hf_ac_if_input_controls_copy;
95 static int hf_ac_if_input_controls_connector;
96 static int hf_ac_if_input_controls_overload;
97 static int hf_ac_if_input_controls_cluster;
98 static int hf_ac_if_input_controls_underflow;
99 static int hf_ac_if_input_controls_overflow;
100 static int hf_ac_if_input_controls_rsv;
101 static int hf_ac_if_input_terminal;
102 static int hf_ac_if_output_terminalid;
103 static int hf_ac_if_output_terminaltype;
104 static int hf_ac_if_output_assocterminal;
105 static int hf_ac_if_output_sourceid;
106 static int hf_ac_if_output_clk_sourceid;
107 static int hf_ac_if_output_controls;
108 static int hf_ac_if_output_controls_copy;
109 static int hf_ac_if_output_controls_connector;
110 static int hf_ac_if_output_controls_overload;
111 static int hf_ac_if_output_controls_underflow;
112 static int hf_ac_if_output_controls_overflow;
113 static int hf_ac_if_output_controls_rsv;
114 static int hf_ac_if_output_terminal;
115 static int hf_ac_if_fu_unitid;
116 static int hf_ac_if_fu_sourceid;
117 static int hf_ac_if_fu_controlsize;
118 static int hf_ac_if_fu_controls;
119 static int hf_ac_if_fu_control;
120 static int hf_ac_if_fu_controls_d0;
121 static int hf_ac_if_fu_controls_d1;
122 static int hf_ac_if_fu_controls_d2;
123 static int hf_ac_if_fu_controls_d3;
124 static int hf_ac_if_fu_controls_d4;
125 static int hf_ac_if_fu_controls_d5;
126 static int hf_ac_if_fu_controls_d6;
127 static int hf_ac_if_fu_controls_d7;
128 static int hf_ac_if_fu_controls_d8;
129 static int hf_ac_if_fu_controls_d9;
130 static int hf_ac_if_fu_controls_rsv;
131 static int hf_ac_if_fu_controls_v2;
132 static int hf_ac_if_fu_control_v2;
133 static int hf_ac_if_fu_controls_v2_d0;
134 static int hf_ac_if_fu_controls_v2_d1;
135 static int hf_ac_if_fu_controls_v2_d2;
136 static int hf_ac_if_fu_controls_v2_d3;
137 static int hf_ac_if_fu_controls_v2_d4;
138 static int hf_ac_if_fu_controls_v2_d5;
139 static int hf_ac_if_fu_controls_v2_d6;
140 static int hf_ac_if_fu_controls_v2_d7;
141 static int hf_ac_if_fu_controls_v2_d8;
142 static int hf_ac_if_fu_controls_v2_d9;
143 static int hf_ac_if_fu_controls_v2_d10;
144 static int hf_ac_if_fu_controls_v2_d11;
145 static int hf_ac_if_fu_controls_v2_d12;
146 static int hf_ac_if_fu_controls_v2_d13;
147 static int hf_ac_if_fu_controls_v2_d14;
148 static int hf_ac_if_fu_controls_v2_rsv;
149 static int hf_ac_if_fu_ifeature;
150 static int hf_ac_if_su_unitid;
151 static int hf_ac_if_su_nrinpins;
152 static int hf_ac_if_su_sourceids;
153 static int hf_ac_if_su_sourceid;
154 static int hf_ac_if_su_controls;
155 static int hf_ac_if_su_controls_d0;
156 static int hf_ac_if_su_controls_rsv;
157 static int hf_ac_if_su_iselector;
158 static int hf_ac_if_mu_unitid;
159 static int hf_ac_if_mu_nrinpins;
160 static int hf_ac_if_mu_sourceid;
161 static int hf_ac_if_mu_nrchannels;
162 static int hf_ac_if_mu_channelconfig;
163 static int hf_ac_if_mu_channelconfig_d0;
164 static int hf_ac_if_mu_channelconfig_d1;
165 static int hf_ac_if_mu_channelconfig_d2;
166 static int hf_ac_if_mu_channelconfig_d3;
167 static int hf_ac_if_mu_channelconfig_d4;
168 static int hf_ac_if_mu_channelconfig_d5;
169 static int hf_ac_if_mu_channelconfig_d6;
170 static int hf_ac_if_mu_channelconfig_d7;
171 static int hf_ac_if_mu_channelconfig_d8;
172 static int hf_ac_if_mu_channelconfig_d9;
173 static int hf_ac_if_mu_channelconfig_d10;
174 static int hf_ac_if_mu_channelconfig_d11;
175 static int hf_ac_if_mu_channelconfig_rsv;
176 static int hf_ac_if_mu_channelnames;
177 static int hf_ac_if_mu_controls;
178 static int hf_ac_if_mu_imixer;
179 static int hf_ac_if_clksrc_id;
180 static int hf_ac_if_clksrc_attr;
181 static int hf_ac_if_clksrc_attr_type;
182 static int hf_ac_if_clksrc_attr_d2;
183 static int hf_ac_if_clksrc_attr_rsv;
184 static int hf_ac_if_clksrc_controls;
185 static int hf_ac_if_clksrc_controls_freq;
186 static int hf_ac_if_clksrc_controls_validity;
187 static int hf_ac_if_clksrc_controls_rsv;
188 static int hf_ac_if_clksrc_assocterminal;
189 static int hf_ac_if_clksrc_clocksource;
190 static int hf_ac_if_clksel_id;
191 static int hf_ac_if_clksel_nrpins;
192 static int hf_ac_if_clksel_sourceid;
193 static int hf_ac_if_clksel_controls;
194 static int hf_ac_if_clksel_controls_clksel;
195 static int hf_ac_if_clksel_controls_rsv;
196 static int hf_ac_if_clksel_clockselector;
197 static int hf_as_if_desc_subtype;
198 static int hf_ac_if_extunit_id;
199 static int hf_ac_if_extunit_code;
200 static int hf_ac_if_extunit_nrpins;
201 static int hf_ac_if_extunit_sourceid;
202 static int hf_ac_if_extunit_nrchannels;
203 static int hf_ac_if_extunit_bmchannelconfig;
204 static int hf_ac_if_extunit_channelnames;
205 static int hf_ac_if_extunit_bmcontrols;
206 static int hf_ac_if_extunit_bmcontrols_enable_ctrl;
207 static int hf_ac_if_extunit_bmcontrols_cluster_ctrl;
208 static int hf_ac_if_extunit_bmcontrols_underflow_ctrl;
209 static int hf_ac_if_extunit_bmcontrols_overflowflow_ctrl;
210 static int hf_ac_if_extunit_iext;
211 static int hf_as_if_gen_term_link;
212 static int hf_as_if_gen_delay;
213 static int hf_as_if_gen_wformattag;
214 static int hf_as_if_gen_controls;
215 static int hf_as_if_gen_controls_active;
216 static int hf_as_if_gen_controls_valid;
217 static int hf_as_if_gen_controls_rsv;
218 static int hf_as_if_gen_formattype;
219 static int hf_as_if_gen_formats;
220 static int hf_as_if_gen_formats_i_d0;
221 static int hf_as_if_gen_formats_i_d1;
222 static int hf_as_if_gen_formats_i_d2;
223 static int hf_as_if_gen_formats_i_d3;
224 static int hf_as_if_gen_formats_i_d4;
225 static int hf_as_if_gen_formats_i_rsv;
226 static int hf_as_if_gen_formats_i_d31;
227 static int hf_as_if_gen_formats_ii_d0;
228 static int hf_as_if_gen_formats_ii_d1;
229 static int hf_as_if_gen_formats_ii_d2;
230 static int hf_as_if_gen_formats_ii_d3;
231 static int hf_as_if_gen_formats_ii_rsv;
232 static int hf_as_if_gen_formats_ii_d31;
233 static int hf_as_if_gen_formats_iii_d0;
234 static int hf_as_if_gen_formats_iii_d1;
235 static int hf_as_if_gen_formats_iii_d2;
236 static int hf_as_if_gen_formats_iii_d3;
237 static int hf_as_if_gen_formats_iii_d4;
238 static int hf_as_if_gen_formats_iii_d5;
239 static int hf_as_if_gen_formats_iii_d6;
240 static int hf_as_if_gen_formats_iii_d7;
241 static int hf_as_if_gen_formats_iii_d8;
242 static int hf_as_if_gen_formats_iii_d9;
243 static int hf_as_if_gen_formats_iii_d10;
244 static int hf_as_if_gen_formats_iii_d11;
245 static int hf_as_if_gen_formats_iii_d12;
246 static int hf_as_if_gen_formats_iii_rsv;
247 static int hf_as_if_gen_formats_iv_d0;
248 static int hf_as_if_gen_formats_iv_d1;
249 static int hf_as_if_gen_formats_iv_d2;
250 static int hf_as_if_gen_formats_iv_d3;
251 static int hf_as_if_gen_formats_iv_d4;
252 static int hf_as_if_gen_formats_iv_d5;
253 static int hf_as_if_gen_formats_iv_d6;
254 static int hf_as_if_gen_formats_iv_d7;
255 static int hf_as_if_gen_formats_iv_d8;
256 static int hf_as_if_gen_formats_iv_d9;
257 static int hf_as_if_gen_formats_iv_d10;
258 static int hf_as_if_gen_formats_iv_d11;
259 static int hf_as_if_gen_formats_iv_d12;
260 static int hf_as_if_gen_formats_iv_d13;
261 static int hf_as_if_gen_formats_iv_d14;
262 static int hf_as_if_gen_formats_iv_d15;
263 static int hf_as_if_gen_formats_iv_d16;
264 static int hf_as_if_gen_formats_iv_d17;
265 static int hf_as_if_gen_formats_iv_d18;
266 static int hf_as_if_gen_formats_iv_d19;
267 static int hf_as_if_gen_formats_iv_d20;
268 static int hf_as_if_gen_formats_iv_d21;
269 static int hf_as_if_gen_formats_iv_rsv;
270 static int hf_as_if_gen_nrchannels;
271 static int hf_as_if_gen_bmchannelconfig;
272 static int hf_as_if_gen_bmchannelconfig_d0;
273 static int hf_as_if_gen_bmchannelconfig_d1;
274 static int hf_as_if_gen_bmchannelconfig_d2;
275 static int hf_as_if_gen_bmchannelconfig_d3;
276 static int hf_as_if_gen_bmchannelconfig_d4;
277 static int hf_as_if_gen_bmchannelconfig_d5;
278 static int hf_as_if_gen_bmchannelconfig_d6;
279 static int hf_as_if_gen_bmchannelconfig_d7;
280 static int hf_as_if_gen_bmchannelconfig_d8;
281 static int hf_as_if_gen_bmchannelconfig_d9;
282 static int hf_as_if_gen_bmchannelconfig_d10;
283 static int hf_as_if_gen_bmchannelconfig_d11;
284 static int hf_as_if_gen_bmchannelconfig_d12;
285 static int hf_as_if_gen_bmchannelconfig_d13;
286 static int hf_as_if_gen_bmchannelconfig_d14;
287 static int hf_as_if_gen_bmchannelconfig_d15;
288 static int hf_as_if_gen_bmchannelconfig_d16;
289 static int hf_as_if_gen_bmchannelconfig_d17;
290 static int hf_as_if_gen_bmchannelconfig_d18;
291 static int hf_as_if_gen_bmchannelconfig_d19;
292 static int hf_as_if_gen_bmchannelconfig_d20;
293 static int hf_as_if_gen_bmchannelconfig_d21;
294 static int hf_as_if_gen_bmchannelconfig_d22;
295 static int hf_as_if_gen_bmchannelconfig_d23;
296 static int hf_as_if_gen_bmchannelconfig_d24;
297 static int hf_as_if_gen_bmchannelconfig_d25;
298 static int hf_as_if_gen_bmchannelconfig_d26;
299 static int hf_as_if_gen_bmchannelconfig_rsv;
300 static int hf_as_if_gen_bmchannelconfig_d31;
301 static int hf_as_if_gen_channelnames;
302 static int hf_as_if_ft_formattype;
303 static int hf_as_if_ft_maxbitrate;
304 static int hf_as_if_ft_nrchannels;
305 static int hf_as_if_ft_subframesize;
306 static int hf_as_if_ft_subslotsize;
307 static int hf_as_if_ft_bitresolution;
308 static int hf_as_if_ft_samplesperframe;
309 static int hf_as_if_ft_samfreqtype;
310 static int hf_as_if_ft_lowersamfreq;
311 static int hf_as_if_ft_uppersamfreq;
312 static int hf_as_if_ft_samfreq;
313 static int hf_as_ep_desc_subtype;
314 static int hf_as_ep_gen_bmattributes;
315 static int hf_as_ep_gen_bmattributes_d0;
316 static int hf_as_ep_gen_bmattributes_d1;
317 static int hf_as_ep_gen_bmattributes_rsv;
318 static int hf_as_ep_gen_bmattributes_d7;
319 static int hf_as_ep_gen_controls;
320 static int hf_as_ep_gen_controls_pitch;
321 static int hf_as_ep_gen_controls_data_overrun;
322 static int hf_as_ep_gen_controls_data_underrun;
323 static int hf_as_ep_gen_controls_rsv;
324 static int hf_as_ep_gen_lockdelayunits;
325 static int hf_as_ep_gen_lockdelay;
326 static int hf_ms_if_desc_subtype;
327 static int hf_ms_if_hdr_ver;
328 static int hf_ms_if_hdr_total_len;
329 static int hf_ms_if_midi_in_bjacktype;
330 static int hf_ms_if_midi_in_bjackid;
331 static int hf_ms_if_midi_in_ijack;
332 static int hf_ms_if_midi_out_bjacktype;
333 static int hf_ms_if_midi_out_bjackid;
334 static int hf_ms_if_midi_out_bnrinputpins;
335 static int hf_ms_if_midi_out_basourceid;
336 static int hf_ms_if_midi_out_basourcepin;
337 static int hf_ms_if_midi_out_ijack;
338 static int hf_ms_ep_gen_numjacks;
339 static int hf_ms_ep_gen_baassocjackid;
340 static int hf_ms_ep_desc_subtype;
342 static int hf_brequest_v1;
343 static int hf_brequest_v2;
344 static int hf_wvalue;
345 static int hf_wvalue_channel_number;
346 static int hf_wvalue_fu_cs_v1;
347 static int hf_wvalue_clksrc_cs;
348 static int hf_wvalue_clksel_cs;
349 static int hf_windex;
350 static int hf_windex_interface;
351 static int hf_windex_entity_id;
352 static int hf_windex_endpoint;
353 static int hf_wlength;
354 static int hf_parameter_bselector;
355 static int hf_parameter_bmute;
356 static int hf_parameter_wvolume;
357 static int hf_parameter_wnumsubranges;
358 static int hf_parameter_bcur;
359 static int hf_parameter_bmin;
360 static int hf_parameter_bmax;
361 static int hf_parameter_bres;
362 static int hf_parameter_wcur;
363 static int hf_parameter_wmin;
364 static int hf_parameter_wmax;
365 static int hf_parameter_wres;
366 static int hf_parameter_dcur;
367 static int hf_parameter_dmin;
368 static int hf_parameter_dmax;
369 static int hf_parameter_dres;
371 static reassembly_table midi_data_reassembly_table;
373 static int ett_usb_audio;
374 static int ett_usb_audio_desc;
376 static int ett_ac_if_hdr_controls;
377 static int ett_ac_if_fu_controls;
378 static int ett_ac_if_fu_controls0;
379 static int ett_ac_if_fu_controls1;
380 static int ett_ac_if_fu_controls_v2;
381 static int ett_ac_if_fu_control_v2;
382 static int ett_ac_if_su_sourceids;
383 static int ett_ac_if_su_controls;
384 static int ett_ac_if_input_wchannelconfig;
385 static int ett_ac_if_input_bmchannelconfig;
386 static int ett_ac_if_input_controls;
387 static int ett_ac_if_output_controls;
388 static int ett_ac_if_mu_channelconfig;
389 static int ett_ac_if_clksrc_attr;
390 static int ett_ac_if_clksrc_controls;
391 static int ett_ac_if_clksel_controls;
392 static int ett_ac_if_extunit_bmchannelconfig;
393 static int ett_ac_if_extunit_bmcontrols;
394 static int ett_as_if_gen_controls;
395 static int ett_as_if_gen_formats;
396 static int ett_as_if_gen_bmchannelconfig;
397 static int ett_as_ep_gen_attributes;
398 static int ett_as_ep_gen_controls;
399 static int ett_wvalue;
400 static int ett_windex;
401 static int ett_parameter_block;
403 static dissector_handle_t sysex_handle;
404 static dissector_handle_t usb_audio_bulk_handle;
405 static dissector_handle_t usb_audio_descr_handle;
406 static dissector_handle_t usb_audio_control_handle;
409 #define AUDIO_IF_SUBCLASS_UNDEFINED 0x00
410 #define AUDIO_IF_SUBCLASS_AUDIOCONTROL 0x01
411 #define AUDIO_IF_SUBCLASS_AUDIOSTREAMING 0x02
412 #define AUDIO_IF_SUBCLASS_MIDISTREAMING 0x03
414 static const value_string usb_audio_subclass_vals[] = {
415 {AUDIO_IF_SUBCLASS_UNDEFINED, "Undefined"},
416 {AUDIO_IF_SUBCLASS_AUDIOCONTROL, "Audio Control"},
417 {AUDIO_IF_SUBCLASS_AUDIOSTREAMING, "Audio Streaming"},
418 {AUDIO_IF_SUBCLASS_MIDISTREAMING, "MIDI Streaming"},
419 {0,NULL}
421 value_string_ext ext_usb_audio_subclass_vals =
422 VALUE_STRING_EXT_INIT(usb_audio_subclass_vals);
424 #define AUDIO_PROTOCOL_V1 0x00
425 #define AUDIO_PROTOCOL_V2 0x20
427 #define V1_REQUEST_CODE_UNDEFINED 0x00
428 #define V1_REQUEST_SET_CUR 0x01
429 #define V1_REQUEST_SET_MIN 0x02
430 #define V1_REQUEST_SET_MAX 0x03
431 #define V1_REQUEST_SET_RES 0x04
432 #define V1_REQUEST_SET_MEM 0x05
433 #define V1_REQUEST_GET_CUR 0x81
434 #define V1_REQUEST_GET_MIN 0x82
435 #define V1_REQUEST_GET_MAX 0x83
436 #define V1_REQUEST_GET_RES 0x84
437 #define V1_REQUEST_GET_MEM 0x85
438 #define V1_REQUEST_GET_STAT 0xFF
440 static const value_string v1_brequest_vals[] = {
441 {V1_REQUEST_CODE_UNDEFINED, "REQUEST_CODE_UNDEFINED"},
442 {V1_REQUEST_SET_CUR, "SET_CUR"},
443 {V1_REQUEST_SET_MIN, "SET_MIN"},
444 {V1_REQUEST_SET_MAX, "SET_MAX"},
445 {V1_REQUEST_SET_RES, "SET_RES"},
446 {V1_REQUEST_SET_MEM, "SET_MEM"},
447 {V1_REQUEST_GET_CUR, "GET_CUR"},
448 {V1_REQUEST_GET_MIN, "GET_MIN"},
449 {V1_REQUEST_GET_MAX, "GET_MAX"},
450 {V1_REQUEST_GET_RES, "GET_RES"},
451 {V1_REQUEST_GET_MEM, "GET_MEM"},
452 {V1_REQUEST_GET_STAT, "GET_STAT"},
453 {0,NULL}
455 static value_string_ext v1_brequest_vals_ext =
456 VALUE_STRING_EXT_INIT(v1_brequest_vals);
458 /* A.17.7 Feature Unit Control Selectors */
459 #define FU_CONTROL_UNDEFINED 0x00
460 #define MUTE_CONTROL 0x01
461 #define VOLUME_CONTROL 0x02
462 #define BASS_CONTROL 0x03
463 #define MID_CONTROL 0x04
464 #define TREBLE_CONTROL 0x05
465 #define GRAPHIC_EQUALIZER_CONTROL 0x06
466 #define AUTOMATIC_GAIN_CONTROL 0x07
467 #define DELAY_CONTROL 0x08
468 #define BASS_BOOST_CONTROL 0x09
469 #define LOUDNESS_CONTROL 0x0A
471 static const value_string v1_fu_cs_vals[] = {
472 {FU_CONTROL_UNDEFINED, "FU_CONTROL_UNDEFINED"},
473 {MUTE_CONTROL, "MUTE_CONTROL"},
474 {VOLUME_CONTROL, "VOLUME_CONTROL"},
475 {BASS_CONTROL, "BASS_CONTROL"},
476 {MID_CONTROL, "MID_CONTROL"},
477 {TREBLE_CONTROL, "TREBLE_CONTROL"},
478 {GRAPHIC_EQUALIZER_CONTROL, "GRAPHIC_EQUALIZER_CONTROL"},
479 {AUTOMATIC_GAIN_CONTROL, "AUTOMATIC_GAIN_CONTROL"},
480 {DELAY_CONTROL, "DELAY_CONTROL"},
481 {BASS_BOOST_CONTROL, "BASS_BOOST_CONTROL"},
482 {LOUDNESS_CONTROL, "LOUDNESS_CONTROL"},
483 {0,NULL}
485 static value_string_ext v1_fu_cs_vals_ext =
486 VALUE_STRING_EXT_INIT(v1_fu_cs_vals);
488 #define V2_REQUEST_CODE_UNDEFINED 0x00
489 #define V2_REQUEST_CUR 0x01
490 #define V2_REQUEST_RANGE 0x02
491 #define V2_REQUEST_MEM 0x03
493 static const value_string v2_brequest_vals[] = {
494 {V2_REQUEST_CODE_UNDEFINED, "REQUEST_CODE_UNDEFINED"},
495 {V2_REQUEST_CUR, "CUR"},
496 {V2_REQUEST_RANGE, "RANGE"},
497 {V2_REQUEST_MEM, "MEM"},
498 {0,NULL}
500 static value_string_ext v2_brequest_vals_ext =
501 VALUE_STRING_EXT_INIT(v2_brequest_vals);
503 /* A.17.1 Clock Source Control Selectors */
504 #define V2_CS_CONTROL_UNDEFINED 0x00
505 #define V2_CS_SAM_FREQ_CONTROL 0x01
506 #define V2_CS_CLOCK_VALID_CONTROL 0x02
507 static const value_string v2_clksrc_cs_vals[] = {
508 {V2_CS_CONTROL_UNDEFINED, "CS_CONTROL_UNDEFINED"},
509 {V2_CS_SAM_FREQ_CONTROL, "CS_SAM_FREQ_CONTROL"},
510 {V2_CS_CLOCK_VALID_CONTROL, "CS_CLOCK_VALID_CONTROL"},
511 {0,NULL}
514 /* A.17.2 Clock Selector Control Selectors */
515 #define V2_CX_CONTROL_UNDEFINED 0x00
516 #define V2_CX_CLOCK_SELECTOR_CONTROL 0x01
517 static const value_string v2_clksel_cs_vals[] = {
518 {V2_CX_CONTROL_UNDEFINED, "CX_CONTROL_UNDEFINED"},
519 {V2_CX_CLOCK_SELECTOR_CONTROL, "CX_CLOCK_SELECTOR_CONTROL"},
520 {0,NULL}
523 static const value_string code_index_vals[] = {
524 { 0x0, "Miscellaneous (Reserved)" },
525 { 0x1, "Cable events (Reserved)" },
526 { 0x2, "Two-byte System Common message" },
527 { 0x3, "Three-byte System Common message" },
528 { 0x4, "SysEx starts or continues" },
529 { 0x5, "SysEx ends with following single byte/Single-byte System Common Message" },
530 { 0x6, "SysEx ends with following two bytes" },
531 { 0x7, "SysEx ends with following three bytes" },
532 { 0x8, "Note-off" },
533 { 0x9, "Note-on" },
534 { 0xA, "Poly-KeyPress" },
535 { 0xB, "Control Change" },
536 { 0xC, "Program Change" },
537 { 0xD, "Channel Pressure" },
538 { 0xE, "PitchBend Change" },
539 { 0xF, "Single Byte" },
540 { 0, NULL }
543 /* USB audio specification, section A.8 */
544 #define CS_INTERFACE 0x24
545 #define CS_ENDPOINT 0x25
547 static const value_string aud_descriptor_type_vals[] = {
548 {CS_INTERFACE, "audio class interface"},
549 {CS_ENDPOINT, "audio class endpoint"},
550 {0,NULL}
552 static value_string_ext aud_descriptor_type_vals_ext =
553 VALUE_STRING_EXT_INIT(aud_descriptor_type_vals);
555 #define AC_SUBTYPE_HEADER 0x01
556 #define AC_SUBTYPE_INPUT_TERMINAL 0x02
557 #define AC_SUBTYPE_OUTPUT_TERMINAL 0x03
558 #define AC_SUBTYPE_MIXER_UNIT 0x04
559 #define AC_SUBTYPE_SELECTOR_UNIT 0x05
560 #define AC_SUBTYPE_FEATURE_UNIT 0x06
561 #define AC_SUBTYPE_EFFECT_UNIT 0x07
562 #define AC_SUBTYPE_PROCESSING_UNIT 0x08
563 #define AC_SUBTYPE_EXTENSION_UNIT 0x09
564 #define AC_SUBTYPE_CLOCK_SOURCE 0x0A
565 #define AC_SUBTYPE_CLOCK_SELECTOR 0x0B
566 #define AC_SUBTYPE_CLOCK_MULTIPLIER 0x0C
567 #define AC_SUBTYPE_SAMPLE_RATE_CONVERTER 0x0D
569 static const value_string ac_subtype_vals[] = {
570 {AC_SUBTYPE_HEADER, "Header Descriptor"},
571 {AC_SUBTYPE_INPUT_TERMINAL, "Input terminal descriptor"},
572 {AC_SUBTYPE_OUTPUT_TERMINAL, "Output terminal descriptor"},
573 {AC_SUBTYPE_MIXER_UNIT, "Mixer unit descriptor"},
574 {AC_SUBTYPE_SELECTOR_UNIT, "Selector unit descriptor"},
575 {AC_SUBTYPE_FEATURE_UNIT, "Feature unit descriptor"},
576 {AC_SUBTYPE_EFFECT_UNIT, "Effect unit descriptor"},
577 {AC_SUBTYPE_PROCESSING_UNIT, "Processing unit descriptor"},
578 {AC_SUBTYPE_EXTENSION_UNIT, "Extension unit descriptor"},
579 {AC_SUBTYPE_CLOCK_SOURCE, "Clock source descriptor"},
580 {AC_SUBTYPE_CLOCK_SELECTOR, "Clock selector descriptor"},
581 {AC_SUBTYPE_CLOCK_MULTIPLIER, "Clock multiplier descriptor"},
582 {AC_SUBTYPE_SAMPLE_RATE_CONVERTER, "Sample rate converter descriptor"},
583 {0,NULL}
585 static value_string_ext ac_subtype_vals_ext =
586 VALUE_STRING_EXT_INIT(ac_subtype_vals);
588 #define AS_SUBTYPE_GENERAL 0x01
589 #define AS_SUBTYPE_FORMAT_TYPE 0x02
590 #define AS_SUBTYPE_ENCODER 0x03
592 static const value_string as_subtype_vals[] = {
593 {AS_SUBTYPE_GENERAL, "General AS Descriptor"},
594 {AS_SUBTYPE_FORMAT_TYPE, "Format type descriptor"},
595 {AS_SUBTYPE_ENCODER, "Encoder descriptor"},
596 {0,NULL}
598 static value_string_ext as_subtype_vals_ext =
599 VALUE_STRING_EXT_INIT(as_subtype_vals);
601 #define AS_EP_SUBTYPE_GENERAL 0x01
602 static const value_string as_ep_subtype_vals[] = {
603 {AS_EP_SUBTYPE_GENERAL, "General Descriptor"},
604 {0,NULL}
607 #define MS_IF_SUBTYPE_HEADER 0x01
608 #define MS_IF_SUBTYPE_MIDI_IN_JACK 0x02
609 #define MS_IF_SUBTYPE_MIDI_OUT_JACK 0x03
610 #define MS_IF_SUBTYPE_ELEMENT 0x04
611 static const value_string ms_if_subtype_vals[] = {
612 {MS_IF_SUBTYPE_HEADER, "Header Descriptor"},
613 {MS_IF_SUBTYPE_MIDI_IN_JACK, "MIDI IN Jack descriptor"},
614 {MS_IF_SUBTYPE_MIDI_OUT_JACK, "MIDI OUT Jack descriptor"},
615 {MS_IF_SUBTYPE_ELEMENT, "MIDI Element descriptor"},
616 {0,NULL}
618 static value_string_ext ms_if_subtype_vals_ext =
619 VALUE_STRING_EXT_INIT(ms_if_subtype_vals);
621 #define MS_MIDI_JACK_TYPE_EMBEDDED 0x01
622 #define MS_MIDI_JACK_TYPE_EXTERNAL 0x02
623 static const value_string ms_midi_jack_type_vals[] = {
624 {MS_MIDI_JACK_TYPE_EMBEDDED, "Embedded"},
625 {MS_MIDI_JACK_TYPE_EXTERNAL, "External"},
626 {0,NULL}
629 #define MS_EP_SUBTYPE_GENERAL 0x01
630 static const value_string ms_ep_subtype_vals[] = {
631 {MS_EP_SUBTYPE_GENERAL, "General Descriptor"},
632 {0,NULL}
635 /* Table A-7: Audio Function Category Codes */
636 static const value_string audio_function_categories_vals[] = {
637 {0x00, "Undefined"},
638 {0x01, "Desktop speaker"},
639 {0x02, "Home theater"},
640 {0x03, "Microphone"},
641 {0x04, "Headset"},
642 {0x05, "Telephone"},
643 {0x06, "Converter"},
644 {0x07, "Voice/Sound recorder"},
645 {0x08, "I/O box"},
646 {0x09, "Musical instrument"},
647 {0x0A, "Pro-audio"},
648 {0x0B, "Audio/Video"},
649 {0x0C, "Control panel"},
650 {0xFF, "Other"},
651 {0,NULL}
653 static value_string_ext audio_function_categories_vals_ext =
654 VALUE_STRING_EXT_INIT(audio_function_categories_vals);
656 /* Described in 4.7.2 Class-Specific AC Interface Descriptor */
657 static const value_string controls_capabilities_vals[] = {
658 {0x00, "Not present"},
659 {0x01, "Present, read-only"},
660 {0x02, "Value not allowed"},
661 {0x03, "Host programmable"},
662 {0,NULL}
664 static value_string_ext controls_capabilities_vals_ext =
665 VALUE_STRING_EXT_INIT(controls_capabilities_vals);
667 /* Described in 4.9.2 Class-Specific AS Interface Descriptor */
668 static const value_string controls_capabilities_read_only_vals[] = {
669 {0x00, "Not present"},
670 {0x01, "Present, read-only"},
671 {0x02, "Value not allowed"},
672 {0x03, "Value not allowed"},
673 {0,NULL}
675 static value_string_ext controls_capabilities_read_only_vals_ext =
676 VALUE_STRING_EXT_INIT(controls_capabilities_read_only_vals);
678 /* Described in 4.7.2.1 Clock Source Descriptor */
679 static const value_string clock_types_vals[] = {
680 {0x00, "External clock"},
681 {0x01, "Internal fixed clock"},
682 {0x02, "Internal variable clock"},
683 {0x03, "Internal programmable clock"},
684 {0,NULL}
687 static const value_string clock_sync_vals[] = {
688 {0x00, "Free running"},
689 {0x01, "Synchronized to the Start of Frame"},
690 {0,NULL}
693 static const value_string lock_delay_unit_vals[] = {
694 {0, "Undefined"},
695 {1, "Milliseconds"},
696 {2, "Decoded PCM samples"},
697 {0,NULL}
700 /* From https://www.usb.org/sites/default/files/termt10.pdf */
701 static const value_string terminal_types_vals[] = {
702 /* USB Terminal Types */
703 {0x0100, "USB Undefined"},
704 {0x0101, "USB Streaming"},
705 {0x01FF, "USB vendor specific"},
706 /* Input Terminal Types */
707 {0x0200, "Input Undefined"},
708 {0x0201, "Microphone"},
709 {0x0202, "Desktop Microphone"},
710 {0x0203, "Personal microphone"},
711 {0x0204, "Omni-directional microphone"},
712 {0x0205, "Microphone array"},
713 {0x0206, "Processing microphone array"},
714 {0x0300, "Output Undefined"},
715 {0x0301, "Speaker"},
716 {0x0302, "Headphones"},
717 {0x0303, "Head Mounted Display Audio"},
718 {0x0304, "Desktop speaker"},
719 {0x0305, "Room speaker"},
720 {0x0306, "Communication speaker"},
721 {0x0307, "Low frequency effects speaker"},
722 /* Bi-directional Terminal Types */
723 {0x0400, "Bi-directional Undefined"},
724 {0x0401, "Handset"},
725 {0x0402, "Headset"},
726 {0x0403, "Speakerphone, no echoreduction"},
727 {0x0404, "Echo-suppressing speakerphone"},
728 {0x0405, "Echo-canceling speakerphone"},
729 /* Telephony Terminal Types */
730 {0x0500, "Telephony Undefined"},
731 {0x0501, "Phone line"},
732 {0x0502, "Telephone"},
733 {0x0503, "Down Line Pone"},
734 /* External Terminal Types */
735 {0x0600, "External Undefined"},
736 {0x0601, "Analog connector"},
737 {0x0602, "Digital audio interface"},
738 {0x0603, "Line connector"},
739 {0x0604, "Legacy audio connector"},
740 {0x0605, "S/PDIF interface"},
741 {0x0606, "1394 DA stream"},
742 {0x0607, "1394 DV stream soundtrack"},
743 /* Embedded Function Terminal Types */
744 {0x0700, "Embedded Undefined"},
745 {0x0701, "Level Calibration Noise Source"},
746 {0x0702, "Equalization Noise"},
747 {0x0703, "CD player"},
748 {0x0704, "DAT"},
749 {0x0705, "DCC"},
750 {0x0706, "MiniDisk"},
751 {0x0707, "Analog Tape"},
752 {0x0708, "Phonograph"},
753 {0x0709, "VCR Audio"},
754 {0x070A, "Video Disc Audio"},
755 {0x070B, "DVD Audio"},
756 {0x070C, "TV Tuner Audio"},
757 {0x070D, "Satellite Receiver Audio"},
758 {0x070E, "Cable Tuner Audio"},
759 {0x070F, "DSS Audio"},
760 {0x0710, "Radio Receiver"},
761 {0x0711, "Radio Transmitter"},
762 {0x0712, "Multi-track Recorder"},
763 {0x0713, "Synthesizer"},
764 {0,NULL}
766 static value_string_ext terminal_types_vals_ext =
767 VALUE_STRING_EXT_INIT(terminal_types_vals);
769 /* From https://usb.org/sites/default/files/frmts10.pdf */
770 static const value_string audio_data_format_tag_vals[] = {
771 /* Audio Data Format Type I Codes */
772 {0x0000, "Type I Undefined"},
773 {0x0001, "PCM"},
774 {0x0002, "PCM8"},
775 {0x0003, "IEEE Float"},
776 {0x0004, "ALAW"},
777 {0x0005, "MULAW"},
778 /* Audio Data Format Type II Codes */
779 {0x1000, "Type II Undefined"},
780 {0x1001, "MPEG"},
781 {0x1002, "AC-3"},
782 /* Audio Data Format Type III Codes */
783 {0x2000, "Type III Undefined"},
784 {0x2001, "IEC1937 AC-3"},
785 {0x2002, "IEC1937 MPEG-1 Layer1"},
786 {0x2003, "IEC1937 MPEG-1 Layer2/3 or IEC1937 MPEG-2 NOEXT"},
787 {0x2004, "IEC1937 MPEG-2 EXT"},
788 {0x2005, "IEC1937 MPEG-2 Layer1 LS"},
789 {0x2006, "IEC1937 MPEG-2 Layer2/3 LS"},
790 {0,NULL}
792 static value_string_ext audio_data_format_tag_vals_ext =
793 VALUE_STRING_EXT_INIT(audio_data_format_tag_vals);
795 /* Enumerator with arbitrarily chosen values to map IDs to entity types */
796 typedef enum {
797 USB_AUDIO_ENTITY_UNKNOWN,
798 USB_AUDIO_ENTITY_INTERFACE,
799 USB_AUDIO_ENTITY_CLOCK_SOURCE,
800 USB_AUDIO_ENTITY_CLOCK_SELECTOR,
801 USB_AUDIO_ENTITY_CLOCK_MULTIPLIER,
802 USB_AUDIO_ENTITY_TERMINAL,
803 USB_AUDIO_ENTITY_MIXER,
804 USB_AUDIO_ENTITY_SELECTOR,
805 USB_AUDIO_ENTITY_FEATURE_UNIT,
806 USB_AUDIO_ENTITY_PARAMETRIC_EQUALIZER,
807 USB_AUDIO_ENTITY_REVERBERATION,
808 USB_AUDIO_ENTITY_MODULATION_DELAY,
809 USB_AUDIO_ENTITY_DYNAMIC_RANGE_COMPRESSOR,
810 USB_AUDIO_ENTITY_UP_DOWN_MIX,
811 USB_AUDIO_ENTITY_DOLBY_PROLOGIC,
812 USB_AUDIO_ENTITY_STEREO_EXTENDER,
813 USB_AUDIO_ENTITY_EXTENSION_UNIT,
814 USB_AUDIO_ENTITY_AUDIOSTREAMING_INTERFACE,
815 USB_AUDIO_ENTITY_ENCODER,
816 USB_AUDIO_ENTITY_MPEG_DECODER,
817 USB_AUDIO_ENTITY_AC3_DECODER,
818 USB_AUDIO_ENTITY_WMA_DECODER,
819 USB_AUDIO_ENTITY_DTS_DECODER,
820 } usb_audio_entity_t;
822 typedef enum {
823 PARAMETER_LAYOUT_UNKNOWN,
824 PARAMETER_LAYOUT_1,
825 PARAMETER_LAYOUT_2,
826 PARAMETER_LAYOUT_3,
827 } parameter_layout_t;
829 typedef struct _audio_conv_info_t {
830 /* Mapping from entity ID to its type. */
831 usb_audio_entity_t entity_type[256];
832 } audio_conv_info_t;
834 static int hf_sysex_msg_fragments;
835 static int hf_sysex_msg_fragment;
836 static int hf_sysex_msg_fragment_overlap;
837 static int hf_sysex_msg_fragment_overlap_conflicts;
838 static int hf_sysex_msg_fragment_multiple_tails;
839 static int hf_sysex_msg_fragment_too_long_fragment;
840 static int hf_sysex_msg_fragment_error;
841 static int hf_sysex_msg_fragment_count;
842 static int hf_sysex_msg_reassembled_in;
843 static int hf_sysex_msg_reassembled_length;
844 static int hf_sysex_msg_reassembled_data;
846 static int ett_sysex_msg_fragment;
847 static int ett_sysex_msg_fragments;
849 static expert_field ei_usb_audio_undecoded;
850 static expert_field ei_usb_audio_invalid_feature_unit_length;
851 static expert_field ei_usb_audio_invalid_type_3_ft_nrchannels;
852 static expert_field ei_usb_audio_invalid_type_3_ft_subframesize;
853 static expert_field ei_usb_audio_invalid_type_3_ft_bitresolution;
855 static const fragment_items sysex_msg_frag_items = {
856 /* Fragment subtrees */
857 &ett_sysex_msg_fragment,
858 &ett_sysex_msg_fragments,
859 /* Fragment fields */
860 &hf_sysex_msg_fragments,
861 &hf_sysex_msg_fragment,
862 &hf_sysex_msg_fragment_overlap,
863 &hf_sysex_msg_fragment_overlap_conflicts,
864 &hf_sysex_msg_fragment_multiple_tails,
865 &hf_sysex_msg_fragment_too_long_fragment,
866 &hf_sysex_msg_fragment_error,
867 &hf_sysex_msg_fragment_count,
868 /* Reassembled in field */
869 &hf_sysex_msg_reassembled_in,
870 /* Reassembled length field */
871 &hf_sysex_msg_reassembled_length,
872 &hf_sysex_msg_reassembled_data,
873 /* Tag */
874 "Message fragments"
877 static int
878 get_midi_event_size(uint8_t code)
880 switch (code)
882 case 0x0: /* Miscellaneous function codes. Reserved for future extensions. */
883 case 0x1: /* Cable events. Reserved for future expansion. */
884 /* The Event size can be 1, 2 or 3 bytes. Assume 3. */
885 return 3;
886 case 0x5: /* Single-byte System Common Message or SysEx ends with following single byte. */
887 case 0xF: /* Single Byte */
888 return 1;
889 case 0x2: /* 2 Two-byte System Common messages like MTC, SongSelect, etc. */
890 case 0x6: /* SysEx ends with following two bytes. */
891 case 0xC: /* Program Change */
892 case 0xD: /* Channel Pressure */
893 return 2;
894 case 0x3: /* Three-byte System Common messages like SPP, etc. */
895 case 0x4: /* SysEx starts or continues */
896 case 0x7: /* SysEx ends with following three bytes. */
897 case 0x8: /* Note-off */
898 case 0x9: /* Note-on */
899 case 0xA: /* Poly-KeyPress */
900 case 0xB: /* Control Change */
901 case 0xE: /* PitchBend Change */
902 return 3;
903 default:
904 /* Invalid Code Index Number */
905 return 0;
909 static inline bool
910 is_sysex_code(uint8_t code)
912 return (code == 0x04 || code == 0x05 || code == 0x06 || code == 0x07);
915 static bool
916 is_last_sysex_packet_in_tvb(tvbuff_t *tvb, int offset)
918 bool last = true;
919 int length = tvb_reported_length(tvb);
921 offset += 4;
922 while (offset < length)
924 uint8_t code = tvb_get_uint8(tvb, offset);
925 code &= 0x0F;
927 if (is_sysex_code(code))
929 last = false;
930 break;
933 offset += 4;
936 return last;
939 static void
940 dissect_usb_midi_event(tvbuff_t *tvb, packet_info *pinfo,
941 proto_tree *parent_tree,
942 int offset)
944 uint8_t code;
945 uint8_t cable;
946 bool save_fragmented;
947 proto_tree *tree = NULL;
949 code = tvb_get_uint8(tvb, offset);
950 cable = (code & 0xF0) >> 4;
951 code &= 0x0F;
953 if (parent_tree)
955 proto_item *ti;
956 int event_size, padding_size;
958 ti = proto_tree_add_protocol_format(parent_tree, proto_usb_audio, tvb, offset, 4, "USB Midi Event Packet: %s",
959 try_val_to_str(code, code_index_vals));
960 tree = proto_item_add_subtree(ti, ett_usb_audio);
961 proto_tree_add_item(tree, hf_midi_cable_number, tvb, offset, 1, ENC_BIG_ENDIAN);
962 proto_tree_add_item(tree, hf_midi_code_index, tvb, offset, 1, ENC_BIG_ENDIAN);
964 event_size = get_midi_event_size(code);
965 padding_size = 3 - event_size;
966 if (event_size > 0)
968 /* TODO: Create MIDI dissector and pass the event data to it */
969 const uint8_t *event_data = tvb_get_ptr(tvb, offset+1, event_size);
970 proto_tree_add_bytes(tree, hf_midi_event, tvb, offset+1, event_size, event_data);
972 if (padding_size > 0)
974 const uint8_t *padding = tvb_get_ptr(tvb, offset+1+event_size, padding_size);
975 proto_tree_add_bytes(tree, hf_midi_padding, tvb, offset+1+event_size, padding_size, padding);
979 save_fragmented = pinfo->fragmented;
981 /* Reassemble SysEx commands */
982 if (is_sysex_code(code))
984 tvbuff_t* new_tvb = NULL;
985 fragment_head *frag_sysex_msg = NULL;
987 pinfo->fragmented = true;
989 if (code == 0x04)
991 frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table,
992 tvb, offset+1,
993 pinfo,
994 cable, /* ID for fragments belonging together */
995 NULL,
997 true);
999 else
1001 frag_sysex_msg = fragment_add_seq_next(&midi_data_reassembly_table,
1002 tvb, offset+1,
1003 pinfo,
1004 cable, /* ID for fragments belonging together */
1005 NULL,
1006 (int)(code - 4),
1007 false);
1010 if (is_last_sysex_packet_in_tvb(tvb, offset))
1012 new_tvb = process_reassembled_data(tvb, offset+1, pinfo,
1013 "Reassembled Message", frag_sysex_msg, &sysex_msg_frag_items,
1014 NULL, tree);
1016 if (code != 0x04) { /* Reassembled */
1017 col_append_str(pinfo->cinfo, COL_INFO,
1018 " (SysEx Reassembled)");
1019 } else { /* Not last packet of reassembled Short Message */
1020 col_append_str(pinfo->cinfo, COL_INFO,
1021 " (SysEx fragment)");
1024 if (new_tvb)
1026 call_dissector(sysex_handle, new_tvb, pinfo, parent_tree);
1031 pinfo->fragmented = save_fragmented;
1034 static audio_conv_info_t*
1035 allocate_audio_conv_info(void)
1037 audio_conv_info_t *info = wmem_new(wmem_file_scope(), audio_conv_info_t);
1038 info->entity_type[0] = USB_AUDIO_ENTITY_INTERFACE;
1039 for (int i = 1; i < 256; i++) {
1040 info->entity_type[i] = USB_AUDIO_ENTITY_UNKNOWN;
1042 return info;
1045 static void
1046 set_entity_type(urb_info_t *urb, uint8_t id, usb_audio_entity_t type)
1048 audio_conv_info_t *audio_conv_info = (audio_conv_info_t *)urb->conv->class_data;
1049 if (!audio_conv_info) {
1050 audio_conv_info = allocate_audio_conv_info();
1051 urb->conv->class_data = audio_conv_info;
1052 urb->conv->class_data_type = USB_CONV_AUDIO;
1053 } else if (urb->conv->class_data_type != USB_CONV_AUDIO) {
1054 /* XXX: Should this check be changed to assert? */
1055 return;
1058 /* Only set entity type for valid entity IDs */
1059 if (id != 0) {
1060 audio_conv_info->entity_type[id] = type;
1064 static usb_audio_entity_t
1065 get_entity_type(urb_info_t *urb, uint8_t id)
1067 audio_conv_info_t *audio_conv_info = (audio_conv_info_t *)urb->conv->class_data;
1068 if (!audio_conv_info || (urb->conv->class_data_type != USB_CONV_AUDIO)) {
1069 return USB_AUDIO_ENTITY_UNKNOWN;
1071 return audio_conv_info->entity_type[id];
1074 static void
1075 base_volume(char *buf, uint32_t value)
1077 if (value == 0x8000) {
1078 snprintf(buf, ITEM_LABEL_LENGTH, "-infinity dB (silence)");
1079 } else {
1080 double dB = ((double)((int16_t)value)) / 256;
1081 snprintf(buf, ITEM_LABEL_LENGTH, "%.4f dB", dB);
1085 /* dissect the body of an AC interface header descriptor
1086 return the number of bytes dissected (which may be smaller than the
1087 body's length) */
1088 static int
1089 dissect_ac_if_hdr_body(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1090 proto_tree *tree, urb_info_t *urb)
1092 int offset_start;
1093 uint16_t bcdADC;
1094 uint8_t ver_major;
1095 double ver;
1096 uint8_t if_in_collection, i;
1098 static int * const bm_controls[] = {
1099 &hf_ac_if_hdr_controls_latency,
1100 &hf_ac_if_hdr_controls_rsv,
1101 NULL
1104 offset_start = offset;
1106 bcdADC = tvb_get_letohs(tvb, offset);
1107 ver_major = USB_AUDIO_BCD44_TO_DEC(bcdADC>>8);
1108 ver = ver_major + USB_AUDIO_BCD44_TO_DEC(bcdADC&0xFF) / 100.0;
1110 proto_tree_add_double_format_value(tree, hf_ac_if_hdr_ver,
1111 tvb, offset, 2, ver, "%2.2f", ver);
1112 offset += 2;
1114 /* version 1 refers to the Basic Audio Device specification,
1115 version 2 is the Audio Device class specification, see above */
1116 if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V1) {
1117 proto_tree_add_item(tree, hf_ac_if_hdr_total_len,
1118 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1119 offset += 2;
1120 if_in_collection = tvb_get_uint8(tvb, offset);
1121 proto_tree_add_item(tree, hf_ac_if_hdr_bInCollection,
1122 tvb, offset, 1, ENC_LITTLE_ENDIAN);
1123 offset++;
1125 for (i=0; i<if_in_collection; i++) {
1126 proto_tree_add_item(tree, hf_ac_if_hdr_if_num,
1127 tvb, offset, 1, ENC_LITTLE_ENDIAN);
1128 offset++;
1131 else if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2) {
1132 proto_tree_add_item(tree, hf_ac_if_hdr_category,
1133 tvb, offset, 1, ENC_LITTLE_ENDIAN);
1134 offset++;
1135 proto_tree_add_item(tree, hf_ac_if_hdr_total_len,
1136 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1137 offset += 2;
1138 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_hdr_controls,
1139 ett_ac_if_hdr_controls, bm_controls, ENC_LITTLE_ENDIAN);
1140 offset++;
1143 return offset-offset_start;
1146 static int
1147 dissect_ac_if_input_terminal(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1148 proto_tree *tree, urb_info_t *urb)
1150 int offset_start;
1152 static int * const input_wchannelconfig[] = {
1153 &hf_ac_if_input_wchannelconfig_d0,
1154 &hf_ac_if_input_wchannelconfig_d1,
1155 &hf_ac_if_input_wchannelconfig_d2,
1156 &hf_ac_if_input_wchannelconfig_d3,
1157 &hf_ac_if_input_wchannelconfig_d4,
1158 &hf_ac_if_input_wchannelconfig_d5,
1159 &hf_ac_if_input_wchannelconfig_d6,
1160 &hf_ac_if_input_wchannelconfig_d7,
1161 &hf_ac_if_input_wchannelconfig_d8,
1162 &hf_ac_if_input_wchannelconfig_d9,
1163 &hf_ac_if_input_wchannelconfig_d10,
1164 &hf_ac_if_input_wchannelconfig_d11,
1165 &hf_ac_if_input_wchannelconfig_rsv,
1166 NULL
1169 static int * const input_bmchannelconfig[] = {
1170 &hf_ac_if_input_bmchannelconfig_d0,
1171 &hf_ac_if_input_bmchannelconfig_d1,
1172 &hf_ac_if_input_bmchannelconfig_d2,
1173 &hf_ac_if_input_bmchannelconfig_d3,
1174 &hf_ac_if_input_bmchannelconfig_d4,
1175 &hf_ac_if_input_bmchannelconfig_d5,
1176 &hf_ac_if_input_bmchannelconfig_d6,
1177 &hf_ac_if_input_bmchannelconfig_d7,
1178 &hf_ac_if_input_bmchannelconfig_d8,
1179 &hf_ac_if_input_bmchannelconfig_d9,
1180 &hf_ac_if_input_bmchannelconfig_d10,
1181 &hf_ac_if_input_bmchannelconfig_d11,
1182 &hf_ac_if_input_bmchannelconfig_d12,
1183 &hf_ac_if_input_bmchannelconfig_d13,
1184 &hf_ac_if_input_bmchannelconfig_d14,
1185 &hf_ac_if_input_bmchannelconfig_d15,
1186 &hf_ac_if_input_bmchannelconfig_d16,
1187 &hf_ac_if_input_bmchannelconfig_d17,
1188 &hf_ac_if_input_bmchannelconfig_d18,
1189 &hf_ac_if_input_bmchannelconfig_d19,
1190 &hf_ac_if_input_bmchannelconfig_d20,
1191 &hf_ac_if_input_bmchannelconfig_d21,
1192 &hf_ac_if_input_bmchannelconfig_d22,
1193 &hf_ac_if_input_bmchannelconfig_d23,
1194 &hf_ac_if_input_bmchannelconfig_d24,
1195 &hf_ac_if_input_bmchannelconfig_d25,
1196 &hf_ac_if_input_bmchannelconfig_d26,
1197 &hf_ac_if_input_bmchannelconfig_rsv,
1198 &hf_ac_if_input_bmchannelconfig_d31,
1199 NULL
1202 static int * const controls[] = {
1203 &hf_ac_if_input_controls_copy,
1204 &hf_ac_if_input_controls_connector,
1205 &hf_ac_if_input_controls_overload,
1206 &hf_ac_if_input_controls_cluster,
1207 &hf_ac_if_input_controls_underflow,
1208 &hf_ac_if_input_controls_overflow,
1209 &hf_ac_if_input_controls_rsv,
1210 NULL
1213 /* do not try to dissect unknown versions */
1214 if (!((urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V1) ||
1215 (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2)))
1216 return 0;
1218 offset_start = offset;
1220 proto_tree_add_item(tree, hf_ac_if_input_terminalid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1221 offset += 1;
1223 proto_tree_add_item(tree, hf_ac_if_input_terminaltype, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1224 offset += 2;
1226 proto_tree_add_item(tree, hf_ac_if_input_assocterminal, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1227 offset += 1;
1229 if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2) {
1230 proto_tree_add_item(tree, hf_ac_if_input_csourceid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1231 offset += 1;
1234 proto_tree_add_item(tree, hf_ac_if_input_nrchannels, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1235 offset += 1;
1237 if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V1) {
1238 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_input_wchannelconfig, ett_ac_if_input_wchannelconfig, input_wchannelconfig, ENC_LITTLE_ENDIAN);
1239 offset += 2;
1240 } else if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2) {
1241 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_input_bmchannelconfig, ett_ac_if_input_bmchannelconfig, input_bmchannelconfig, ENC_LITTLE_ENDIAN);
1242 offset += 4;
1245 proto_tree_add_item(tree, hf_ac_if_input_channelnames, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1246 offset += 1;
1248 if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2) {
1249 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_input_controls, ett_ac_if_input_controls, controls, ENC_LITTLE_ENDIAN);
1250 offset += 2;
1253 proto_tree_add_item(tree, hf_ac_if_input_terminal, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1254 offset += 1;
1256 return offset-offset_start;
1259 static int
1260 dissect_ac_if_output_terminal(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1261 proto_tree *tree, urb_info_t *urb)
1263 int offset_start;
1265 static int * const controls[] = {
1266 &hf_ac_if_output_controls_copy,
1267 &hf_ac_if_output_controls_connector,
1268 &hf_ac_if_output_controls_overload,
1269 &hf_ac_if_output_controls_underflow,
1270 &hf_ac_if_output_controls_overflow,
1271 &hf_ac_if_output_controls_rsv,
1272 NULL
1275 /* do not try to dissect unknown versions */
1276 if (!((urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V1) ||
1277 (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2)))
1278 return 0;
1280 offset_start = offset;
1282 proto_tree_add_item(tree, hf_ac_if_output_terminalid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1283 offset += 1;
1285 proto_tree_add_item(tree, hf_ac_if_output_terminaltype, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1286 offset += 2;
1288 proto_tree_add_item(tree, hf_ac_if_output_assocterminal, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1289 offset += 1;
1291 proto_tree_add_item(tree, hf_ac_if_output_sourceid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1292 offset += 1;
1294 if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2) {
1295 proto_tree_add_item(tree, hf_ac_if_output_clk_sourceid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1296 offset += 1;
1298 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_output_controls, ett_ac_if_output_controls, controls, ENC_LITTLE_ENDIAN);
1299 offset += 2;
1302 proto_tree_add_item(tree, hf_ac_if_output_terminal, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1303 offset += 1;
1305 return offset-offset_start;
1308 static int
1309 dissect_ac_if_feature_unit(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1310 proto_tree *tree, urb_info_t *urb, uint8_t desc_len)
1312 int offset_start;
1313 int i;
1314 int ch;
1315 uint8_t controlsize;
1316 proto_tree *bitmap_tree;
1317 proto_item *ti;
1319 static int * const fu_controls0[] = {
1320 &hf_ac_if_fu_controls_d0,
1321 &hf_ac_if_fu_controls_d1,
1322 &hf_ac_if_fu_controls_d2,
1323 &hf_ac_if_fu_controls_d3,
1324 &hf_ac_if_fu_controls_d4,
1325 &hf_ac_if_fu_controls_d5,
1326 &hf_ac_if_fu_controls_d6,
1327 &hf_ac_if_fu_controls_d7,
1328 NULL };
1330 static int * const fu_controls1[] = {
1331 &hf_ac_if_fu_controls_d8,
1332 &hf_ac_if_fu_controls_d9,
1333 &hf_ac_if_fu_controls_rsv,
1334 NULL };
1336 static int * const v2_fu_controls[] = {
1337 &hf_ac_if_fu_controls_v2_d0,
1338 &hf_ac_if_fu_controls_v2_d1,
1339 &hf_ac_if_fu_controls_v2_d2,
1340 &hf_ac_if_fu_controls_v2_d3,
1341 &hf_ac_if_fu_controls_v2_d4,
1342 &hf_ac_if_fu_controls_v2_d5,
1343 &hf_ac_if_fu_controls_v2_d6,
1344 &hf_ac_if_fu_controls_v2_d7,
1345 &hf_ac_if_fu_controls_v2_d8,
1346 &hf_ac_if_fu_controls_v2_d9,
1347 &hf_ac_if_fu_controls_v2_d10,
1348 &hf_ac_if_fu_controls_v2_d11,
1349 &hf_ac_if_fu_controls_v2_d12,
1350 &hf_ac_if_fu_controls_v2_d13,
1351 &hf_ac_if_fu_controls_v2_d14,
1352 &hf_ac_if_fu_controls_v2_rsv,
1353 NULL };
1355 /* do not try to dissect unknown versions */
1356 if (!((urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V1) ||
1357 (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2)))
1358 return 0;
1360 offset_start = offset;
1362 if (!PINFO_FD_VISITED(pinfo)) {
1363 set_entity_type(urb, tvb_get_uint8(tvb, offset), USB_AUDIO_ENTITY_FEATURE_UNIT);
1365 proto_tree_add_item(tree, hf_ac_if_fu_unitid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1366 offset += 1;
1368 proto_tree_add_item(tree, hf_ac_if_fu_sourceid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1369 offset += 1;
1371 if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V1) {
1372 proto_tree_add_item(tree, hf_ac_if_fu_controlsize, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1373 controlsize = tvb_get_uint8(tvb, offset);
1374 offset += 1;
1376 /* Descriptor size is 7+(ch+1)*n where n is controlsize, calculate and validate ch */
1377 ch = (controlsize > 0) ? (((desc_len - 7) / (controlsize)) - 1) : 0;
1378 if (((7 + ((ch + 1) * controlsize)) != desc_len) || (ch < 0) || (controlsize == 0)){
1379 /* Report malformed packet, do not attempt further dissection */
1380 proto_tree_add_expert(tree, pinfo, &ei_usb_audio_invalid_feature_unit_length, tvb, offset, desc_len-offset);
1381 offset += desc_len-offset;
1382 return offset-offset_start;
1385 ti = proto_tree_add_item(tree, hf_ac_if_fu_controls, tvb, offset, controlsize * (ch + 1), ENC_NA);
1386 bitmap_tree = proto_item_add_subtree(ti, ett_ac_if_fu_controls);
1388 /* bmaControls has 1 master channel 0 controls, and variable number of logical channel controls */
1389 for (i = 0; i < (ch + 1); i++) {
1390 ti = proto_tree_add_bitmask(bitmap_tree, tvb, offset, hf_ac_if_fu_control, ett_ac_if_fu_controls0, fu_controls0, ENC_LITTLE_ENDIAN);
1391 proto_item_prepend_text(ti, "%s channel %d ", (i == 0) ? "Master" : "Logical", i);
1392 if (controlsize > 1) {
1393 ti = proto_tree_add_bitmask(bitmap_tree, tvb, offset + 1, hf_ac_if_fu_control, ett_ac_if_fu_controls1, fu_controls1, ENC_LITTLE_ENDIAN);
1394 proto_item_prepend_text(ti, "%s channel %d", (i == 0) ? "Master" : "Logical", i);
1396 offset += controlsize;
1399 } else if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2) {
1400 /* Descriptor size is 6+(ch+1)*4, calculate and validate ch */
1401 ch = (desc_len - 6) / 4 - 1;
1402 if (((6 + (ch + 1) * 4) != desc_len) || (ch < 0)) {
1403 /* Report malformed packet, do not attempt further dissection */
1404 proto_tree_add_expert(tree, pinfo, &ei_usb_audio_invalid_feature_unit_length, tvb, offset, desc_len-offset);
1405 offset += desc_len-offset;
1406 return offset-offset_start;
1409 ti = proto_tree_add_item(tree, hf_ac_if_fu_controls_v2, tvb, offset, 4 * (ch + 1), ENC_NA);
1410 bitmap_tree = proto_item_add_subtree(ti, ett_ac_if_fu_controls_v2);
1412 for (i = 0; i < (ch + 1); i++) {
1413 ti = proto_tree_add_bitmask(bitmap_tree, tvb, offset, hf_ac_if_fu_control_v2, ett_ac_if_fu_control_v2, v2_fu_controls, ENC_LITTLE_ENDIAN);
1414 proto_item_prepend_text(ti, "%s channel %d ", (i == 0) ? "Master" : "Logical", i);
1415 offset += 4;
1420 proto_tree_add_item(tree, hf_ac_if_fu_ifeature, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1421 offset += 1;
1423 return offset-offset_start;
1426 static int dissect_ac_if_selector_unit(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, urb_info_t *urb)
1428 int offset_start;
1429 uint32_t nrinpins,i;
1430 uint32_t source_id;
1431 proto_item *ti;
1432 proto_tree *subtree;
1434 static int * const controls[] = {
1435 &hf_ac_if_su_controls_d0,
1436 &hf_ac_if_su_controls_rsv,
1437 NULL
1440 /* do not try to dissect unknown versions */
1441 if (!((urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V1) ||
1442 (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2)))
1443 return 0;
1445 offset_start = offset;
1447 if (!PINFO_FD_VISITED(pinfo)) {
1448 set_entity_type(urb, tvb_get_uint8(tvb, offset), USB_AUDIO_ENTITY_SELECTOR);
1450 proto_tree_add_item(tree, hf_ac_if_su_unitid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1451 offset += 1;
1453 proto_tree_add_item_ret_uint(tree, hf_ac_if_su_nrinpins, tvb, offset, 1, ENC_LITTLE_ENDIAN, &nrinpins);
1454 offset += 1;
1456 ti = proto_tree_add_bytes_format_value(tree, hf_ac_if_su_sourceids, tvb, offset, nrinpins, NULL, "%s", "");
1457 subtree = proto_item_add_subtree(ti, ett_ac_if_su_sourceids);
1459 for (i = 0; i < nrinpins; ++i) {
1460 proto_tree_add_item_ret_uint(subtree, hf_ac_if_su_sourceid, tvb, offset, 1, ENC_LITTLE_ENDIAN, &source_id);
1461 offset += 1;
1462 proto_item_append_text(ti, "%s%d", (i > 0) ? ", " : "", source_id);
1465 if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2) {
1466 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_su_controls, ett_ac_if_su_controls, controls, ENC_LITTLE_ENDIAN);
1467 offset += 1;
1470 proto_tree_add_item(tree, hf_ac_if_su_iselector, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1471 offset += 1;
1473 return offset - offset_start;
1476 static int
1477 dissect_ac_if_mixed_unit(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1478 proto_tree *tree, urb_info_t *urb _U_)
1480 int offset_start;
1481 uint8_t nrinpins;
1483 static int * const mu_channelconfig[] = {
1484 &hf_ac_if_mu_channelconfig_d0,
1485 &hf_ac_if_mu_channelconfig_d1,
1486 &hf_ac_if_mu_channelconfig_d2,
1487 &hf_ac_if_mu_channelconfig_d3,
1488 &hf_ac_if_mu_channelconfig_d4,
1489 &hf_ac_if_mu_channelconfig_d5,
1490 &hf_ac_if_mu_channelconfig_d6,
1491 &hf_ac_if_mu_channelconfig_d7,
1492 &hf_ac_if_mu_channelconfig_d8,
1493 &hf_ac_if_mu_channelconfig_d9,
1494 &hf_ac_if_mu_channelconfig_d10,
1495 &hf_ac_if_mu_channelconfig_d11,
1496 &hf_ac_if_mu_channelconfig_rsv,
1497 NULL
1500 offset_start = offset;
1502 proto_tree_add_item(tree, hf_ac_if_mu_unitid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1503 offset += 1;
1505 proto_tree_add_item(tree, hf_ac_if_mu_nrinpins, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1506 nrinpins = tvb_get_uint8(tvb, offset);
1507 offset += 1;
1509 while(nrinpins){
1510 proto_tree_add_item(tree, hf_ac_if_mu_sourceid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1511 nrinpins--;
1512 offset += 1;
1515 proto_tree_add_item(tree, hf_ac_if_mu_nrchannels, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1516 offset += 1;
1518 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_mu_channelconfig, ett_ac_if_mu_channelconfig, mu_channelconfig, ENC_LITTLE_ENDIAN);
1519 offset += 2;
1521 proto_tree_add_item(tree, hf_ac_if_mu_channelnames, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1522 offset += 1;
1524 proto_tree_add_item(tree, hf_ac_if_mu_controls, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1525 offset += 1;
1527 proto_tree_add_item(tree, hf_ac_if_mu_imixer, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1528 offset += 1;
1530 return offset-offset_start;
1533 static int
1534 dissect_ac_if_clock_source(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1535 proto_tree *tree, urb_info_t *urb)
1537 int offset_start;
1538 static int * const cs_attributes[] = {
1539 &hf_ac_if_clksrc_attr_type,
1540 &hf_ac_if_clksrc_attr_d2,
1541 &hf_ac_if_clksrc_attr_rsv,
1542 NULL
1544 static int * const cs_controls[] = {
1545 &hf_ac_if_clksrc_controls_freq,
1546 &hf_ac_if_clksrc_controls_validity,
1547 &hf_ac_if_clksrc_controls_rsv,
1548 NULL
1550 offset_start = offset;
1552 if (!PINFO_FD_VISITED(pinfo)) {
1553 set_entity_type(urb, tvb_get_uint8(tvb, offset), USB_AUDIO_ENTITY_CLOCK_SOURCE);
1555 proto_tree_add_item(tree, hf_ac_if_clksrc_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1556 offset += 1;
1558 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_clksrc_attr, ett_ac_if_clksrc_attr, cs_attributes, ENC_LITTLE_ENDIAN);
1559 offset += 1;
1561 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_clksrc_controls, ett_ac_if_clksrc_controls, cs_controls, ENC_LITTLE_ENDIAN);
1562 offset += 1;
1564 proto_tree_add_item(tree, hf_ac_if_clksrc_assocterminal, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1565 offset += 1;
1567 proto_tree_add_item(tree, hf_ac_if_clksrc_clocksource, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1568 offset += 1;
1570 return offset-offset_start;
1573 static int
1574 dissect_ac_if_clock_selector(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1575 proto_tree *tree, urb_info_t *urb)
1577 int offset_start;
1578 uint8_t nrinpins;
1579 static int * const cs_controls[] = {
1580 &hf_ac_if_clksel_controls_clksel,
1581 &hf_ac_if_clksel_controls_rsv,
1582 NULL
1584 offset_start = offset;
1586 if (!PINFO_FD_VISITED(pinfo)) {
1587 set_entity_type(urb, tvb_get_uint8(tvb, offset), USB_AUDIO_ENTITY_CLOCK_SELECTOR);
1589 proto_tree_add_item(tree, hf_ac_if_clksel_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1590 offset += 1;
1592 proto_tree_add_item(tree, hf_ac_if_clksel_nrpins, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1593 nrinpins = tvb_get_uint8(tvb, offset);
1594 offset += 1;
1596 while (nrinpins) {
1597 proto_tree_add_item(tree, hf_ac_if_clksel_sourceid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1598 nrinpins--;
1599 offset += 1;
1602 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_clksel_controls, ett_ac_if_clksel_controls, cs_controls, ENC_LITTLE_ENDIAN);
1603 offset += 1;
1605 proto_tree_add_item(tree, hf_ac_if_clksel_clockselector, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1606 offset += 1;
1608 return offset-offset_start;
1611 static int
1612 dissect_ac_if_extension_unit(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1613 proto_tree *tree, urb_info_t *urb)
1615 int offset_start;
1616 uint8_t nrinpins;
1617 offset_start = offset;
1619 static int * const v2_channels[] = {
1620 &hf_as_if_gen_bmchannelconfig_d0,
1621 &hf_as_if_gen_bmchannelconfig_d1,
1622 &hf_as_if_gen_bmchannelconfig_d2,
1623 &hf_as_if_gen_bmchannelconfig_d3,
1624 &hf_as_if_gen_bmchannelconfig_d4,
1625 &hf_as_if_gen_bmchannelconfig_d5,
1626 &hf_as_if_gen_bmchannelconfig_d6,
1627 &hf_as_if_gen_bmchannelconfig_d7,
1628 &hf_as_if_gen_bmchannelconfig_d8,
1629 &hf_as_if_gen_bmchannelconfig_d9,
1630 &hf_as_if_gen_bmchannelconfig_d10,
1631 &hf_as_if_gen_bmchannelconfig_d11,
1632 &hf_as_if_gen_bmchannelconfig_d12,
1633 &hf_as_if_gen_bmchannelconfig_d13,
1634 &hf_as_if_gen_bmchannelconfig_d14,
1635 &hf_as_if_gen_bmchannelconfig_d15,
1636 &hf_as_if_gen_bmchannelconfig_d16,
1637 &hf_as_if_gen_bmchannelconfig_d17,
1638 &hf_as_if_gen_bmchannelconfig_d18,
1639 &hf_as_if_gen_bmchannelconfig_d19,
1640 &hf_as_if_gen_bmchannelconfig_d20,
1641 &hf_as_if_gen_bmchannelconfig_d21,
1642 &hf_as_if_gen_bmchannelconfig_d22,
1643 &hf_as_if_gen_bmchannelconfig_d23,
1644 &hf_as_if_gen_bmchannelconfig_d24,
1645 &hf_as_if_gen_bmchannelconfig_d25,
1646 &hf_as_if_gen_bmchannelconfig_d26,
1647 &hf_as_if_gen_bmchannelconfig_rsv,
1648 &hf_as_if_gen_bmchannelconfig_d31,
1649 NULL
1651 static int *const eu_bmcontrols[] = {
1652 &hf_ac_if_extunit_bmcontrols_enable_ctrl,
1653 &hf_ac_if_extunit_bmcontrols_cluster_ctrl,
1654 &hf_ac_if_extunit_bmcontrols_underflow_ctrl,
1655 &hf_ac_if_extunit_bmcontrols_overflowflow_ctrl,
1656 NULL
1659 if (!PINFO_FD_VISITED(pinfo)) {
1660 set_entity_type(urb, tvb_get_uint8(tvb, offset), USB_AUDIO_ENTITY_EXTENSION_UNIT);
1662 proto_tree_add_item(tree, hf_ac_if_extunit_id, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1663 offset += 1;
1664 proto_tree_add_item(tree, hf_ac_if_extunit_code, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1665 offset += 2;
1667 proto_tree_add_item(tree, hf_ac_if_extunit_nrpins, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1668 nrinpins = tvb_get_uint8(tvb, offset);
1669 offset += 1;
1671 while (nrinpins) {
1672 proto_tree_add_item(tree, hf_ac_if_extunit_sourceid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1673 nrinpins--;
1674 offset += 1;
1677 proto_tree_add_item(tree, hf_ac_if_extunit_nrchannels, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1678 offset += 1;
1680 // TODO:
1681 // desc_tree = proto_tree_add_subtree(tree, tvb, offset, ???)
1682 // offset += dissect_as_if_general_body(tvb, offset, pinfo, desc_tree, urb);
1683 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_extunit_bmchannelconfig, ett_ac_if_extunit_bmchannelconfig, v2_channels, ENC_LITTLE_ENDIAN);
1684 offset += 4;
1686 proto_tree_add_item(tree, hf_ac_if_extunit_channelnames, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1687 offset += 1;
1689 proto_tree_add_bitmask(tree, tvb, offset, hf_ac_if_extunit_bmcontrols, ett_ac_if_extunit_bmcontrols, eu_bmcontrols, ENC_LITTLE_ENDIAN);
1690 offset += 1;
1692 proto_tree_add_item(tree, hf_ac_if_extunit_iext, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1693 offset += 1;
1695 return offset - offset_start;
1698 static int
1699 dissect_as_if_general_body(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1700 proto_tree *tree, urb_info_t *urb)
1702 int offset_start;
1704 static int * const v2_controls[] = {
1705 &hf_as_if_gen_controls_active,
1706 &hf_as_if_gen_controls_valid,
1707 &hf_as_if_gen_controls_rsv,
1708 NULL
1711 static int * const v2_formats_type_i[] = {
1712 &hf_as_if_gen_formats_i_d0,
1713 &hf_as_if_gen_formats_i_d1,
1714 &hf_as_if_gen_formats_i_d2,
1715 &hf_as_if_gen_formats_i_d3,
1716 &hf_as_if_gen_formats_i_d4,
1717 &hf_as_if_gen_formats_i_rsv,
1718 &hf_as_if_gen_formats_i_d31,
1719 NULL
1722 static int * const v2_formats_type_ii[] = {
1723 &hf_as_if_gen_formats_ii_d0,
1724 &hf_as_if_gen_formats_ii_d1,
1725 &hf_as_if_gen_formats_ii_d2,
1726 &hf_as_if_gen_formats_ii_d3,
1727 &hf_as_if_gen_formats_ii_rsv,
1728 &hf_as_if_gen_formats_ii_d31,
1729 NULL
1732 static int * const v2_formats_type_iii[] = {
1733 &hf_as_if_gen_formats_iii_d0,
1734 &hf_as_if_gen_formats_iii_d1,
1735 &hf_as_if_gen_formats_iii_d2,
1736 &hf_as_if_gen_formats_iii_d3,
1737 &hf_as_if_gen_formats_iii_d4,
1738 &hf_as_if_gen_formats_iii_d5,
1739 &hf_as_if_gen_formats_iii_d6,
1740 &hf_as_if_gen_formats_iii_d7,
1741 &hf_as_if_gen_formats_iii_d8,
1742 &hf_as_if_gen_formats_iii_d9,
1743 &hf_as_if_gen_formats_iii_d10,
1744 &hf_as_if_gen_formats_iii_d11,
1745 &hf_as_if_gen_formats_iii_d12,
1746 &hf_as_if_gen_formats_iii_rsv,
1747 NULL
1750 static int * const v2_formats_type_iv[] = {
1751 &hf_as_if_gen_formats_iv_d0,
1752 &hf_as_if_gen_formats_iv_d1,
1753 &hf_as_if_gen_formats_iv_d2,
1754 &hf_as_if_gen_formats_iv_d3,
1755 &hf_as_if_gen_formats_iv_d4,
1756 &hf_as_if_gen_formats_iv_d5,
1757 &hf_as_if_gen_formats_iv_d6,
1758 &hf_as_if_gen_formats_iv_d7,
1759 &hf_as_if_gen_formats_iv_d8,
1760 &hf_as_if_gen_formats_iv_d9,
1761 &hf_as_if_gen_formats_iv_d10,
1762 &hf_as_if_gen_formats_iv_d11,
1763 &hf_as_if_gen_formats_iv_d12,
1764 &hf_as_if_gen_formats_iv_d13,
1765 &hf_as_if_gen_formats_iv_d14,
1766 &hf_as_if_gen_formats_iv_d15,
1767 &hf_as_if_gen_formats_iv_d16,
1768 &hf_as_if_gen_formats_iv_d17,
1769 &hf_as_if_gen_formats_iv_d18,
1770 &hf_as_if_gen_formats_iv_d19,
1771 &hf_as_if_gen_formats_iv_d20,
1772 &hf_as_if_gen_formats_iv_d21,
1773 &hf_as_if_gen_formats_iv_rsv,
1774 NULL
1777 static int * const v2_channels[] = {
1778 &hf_as_if_gen_bmchannelconfig_d0,
1779 &hf_as_if_gen_bmchannelconfig_d1,
1780 &hf_as_if_gen_bmchannelconfig_d2,
1781 &hf_as_if_gen_bmchannelconfig_d3,
1782 &hf_as_if_gen_bmchannelconfig_d4,
1783 &hf_as_if_gen_bmchannelconfig_d5,
1784 &hf_as_if_gen_bmchannelconfig_d6,
1785 &hf_as_if_gen_bmchannelconfig_d7,
1786 &hf_as_if_gen_bmchannelconfig_d8,
1787 &hf_as_if_gen_bmchannelconfig_d9,
1788 &hf_as_if_gen_bmchannelconfig_d10,
1789 &hf_as_if_gen_bmchannelconfig_d11,
1790 &hf_as_if_gen_bmchannelconfig_d12,
1791 &hf_as_if_gen_bmchannelconfig_d13,
1792 &hf_as_if_gen_bmchannelconfig_d14,
1793 &hf_as_if_gen_bmchannelconfig_d15,
1794 &hf_as_if_gen_bmchannelconfig_d16,
1795 &hf_as_if_gen_bmchannelconfig_d17,
1796 &hf_as_if_gen_bmchannelconfig_d18,
1797 &hf_as_if_gen_bmchannelconfig_d19,
1798 &hf_as_if_gen_bmchannelconfig_d20,
1799 &hf_as_if_gen_bmchannelconfig_d21,
1800 &hf_as_if_gen_bmchannelconfig_d22,
1801 &hf_as_if_gen_bmchannelconfig_d23,
1802 &hf_as_if_gen_bmchannelconfig_d24,
1803 &hf_as_if_gen_bmchannelconfig_d25,
1804 &hf_as_if_gen_bmchannelconfig_d26,
1805 &hf_as_if_gen_bmchannelconfig_rsv,
1806 &hf_as_if_gen_bmchannelconfig_d31,
1807 NULL
1810 offset_start = offset;
1812 if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V1) {
1813 proto_tree_add_item(tree, hf_as_if_gen_term_link, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1814 offset++;
1815 proto_tree_add_item(tree, hf_as_if_gen_delay, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1816 offset++;
1817 proto_tree_add_item(tree, hf_as_if_gen_wformattag, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1818 offset += 2;
1819 } else if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2) {
1820 uint8_t format_type;
1821 int * const *formats_bitmask;
1823 proto_tree_add_item(tree, hf_as_if_gen_term_link, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1824 offset++;
1825 proto_tree_add_bitmask(tree, tvb, offset, hf_as_if_gen_controls, ett_as_if_gen_controls, v2_controls, ENC_LITTLE_ENDIAN);
1826 offset++;
1827 proto_tree_add_item(tree, hf_as_if_gen_formattype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1828 format_type = tvb_get_uint8(tvb, offset);
1829 offset++;
1830 switch(format_type)
1832 case 1:
1833 formats_bitmask = v2_formats_type_i;
1834 break;
1835 case 2:
1836 formats_bitmask = v2_formats_type_ii;
1837 break;
1838 case 3:
1839 formats_bitmask = v2_formats_type_iii;
1840 break;
1841 case 4:
1842 formats_bitmask = v2_formats_type_iv;
1843 break;
1844 default:
1845 formats_bitmask = NULL;
1846 break;
1848 if (formats_bitmask) {
1849 proto_tree_add_bitmask(tree, tvb, offset, hf_as_if_gen_formats, ett_as_if_gen_formats, formats_bitmask, ENC_LITTLE_ENDIAN);
1850 } else {
1851 proto_tree_add_item(tree, hf_as_if_gen_formats, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1853 offset += 4;
1854 proto_tree_add_item(tree, hf_as_if_gen_nrchannels, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1855 offset++;
1856 proto_tree_add_bitmask(tree, tvb, offset, hf_as_if_gen_bmchannelconfig, ett_as_if_gen_bmchannelconfig, v2_channels, ENC_LITTLE_ENDIAN);
1857 offset += 4;
1858 proto_tree_add_item(tree, hf_as_if_gen_channelnames, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1859 offset++;
1862 return offset-offset_start;
1865 static int
1866 dissect_as_if_format_type_ver1_body(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1867 proto_tree *tree, urb_info_t *urb _U_)
1869 int offset_start;
1870 uint8_t SamFreqType;
1871 uint8_t format_type;
1872 uint32_t nrchannels;
1873 uint32_t subframesize;
1874 uint32_t bitresolution;
1875 proto_item *desc_tree_item;
1877 offset_start = offset;
1879 proto_tree_add_item(tree, hf_as_if_ft_formattype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1880 format_type = tvb_get_uint8(tvb, offset);
1881 offset++;
1884 switch(format_type){
1885 case 1:
1886 proto_tree_add_item(tree, hf_as_if_ft_nrchannels, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1887 offset += 1;
1889 proto_tree_add_item(tree, hf_as_if_ft_subframesize, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1890 offset += 1;
1892 proto_tree_add_item(tree, hf_as_if_ft_bitresolution, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1893 offset += 1;
1895 proto_tree_add_item(tree, hf_as_if_ft_samfreqtype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1896 SamFreqType = tvb_get_uint8(tvb, offset);
1897 offset++;
1899 if(SamFreqType == 0){
1900 proto_tree_add_item(tree, hf_as_if_ft_lowersamfreq, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1901 offset += 3;
1902 proto_tree_add_item(tree, hf_as_if_ft_uppersamfreq, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1903 offset += 3;
1904 }else {
1905 while(SamFreqType){
1906 proto_tree_add_item(tree, hf_as_if_ft_samfreq, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1907 offset += 3;
1908 SamFreqType--;
1911 break;
1912 case 2:
1913 proto_tree_add_item(tree, hf_as_if_ft_maxbitrate, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1914 offset += 2;
1916 proto_tree_add_item(tree, hf_as_if_ft_samplesperframe, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1917 offset += 2;
1919 proto_tree_add_item(tree, hf_as_if_ft_samfreqtype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1920 SamFreqType = tvb_get_uint8(tvb, offset);
1921 offset++;
1923 if(SamFreqType == 0){
1924 proto_tree_add_item(tree, hf_as_if_ft_lowersamfreq, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1925 offset += 3;
1926 proto_tree_add_item(tree, hf_as_if_ft_uppersamfreq, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1927 offset += 3;
1928 }else {
1929 while(SamFreqType){
1930 proto_tree_add_item(tree, hf_as_if_ft_samfreq, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1931 offset += 3;
1932 SamFreqType--;
1935 break;
1936 case 3:
1937 desc_tree_item = proto_tree_add_item_ret_uint(tree, hf_as_if_ft_nrchannels, tvb, offset, 1, ENC_LITTLE_ENDIAN, &nrchannels);
1938 offset += 1;
1940 if(nrchannels != 2){
1941 expert_add_info(pinfo, desc_tree_item, &ei_usb_audio_invalid_type_3_ft_nrchannels);
1944 desc_tree_item = proto_tree_add_item_ret_uint(tree, hf_as_if_ft_subframesize, tvb, offset, 1, ENC_LITTLE_ENDIAN, &subframesize);
1945 offset += 1;
1947 if(subframesize != 2){
1948 expert_add_info(pinfo, desc_tree_item, &ei_usb_audio_invalid_type_3_ft_subframesize);
1951 desc_tree_item = proto_tree_add_item_ret_uint(tree, hf_as_if_ft_bitresolution, tvb, offset, 1, ENC_LITTLE_ENDIAN, &bitresolution);
1952 offset += 1;
1954 if(bitresolution != 16){
1955 expert_add_info(pinfo, desc_tree_item, &ei_usb_audio_invalid_type_3_ft_bitresolution);
1958 proto_tree_add_item(tree, hf_as_if_ft_samfreqtype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1959 SamFreqType = tvb_get_uint8(tvb, offset);
1960 offset++;
1962 if(SamFreqType == 0){
1963 proto_tree_add_item(tree, hf_as_if_ft_lowersamfreq, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1964 offset += 3;
1965 proto_tree_add_item(tree, hf_as_if_ft_uppersamfreq, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1966 offset += 3;
1967 }else {
1968 while(SamFreqType){
1969 proto_tree_add_item(tree, hf_as_if_ft_samfreq, tvb, offset, 3, ENC_LITTLE_ENDIAN);
1970 offset += 3;
1971 SamFreqType--;
1974 break;
1975 default:
1976 break;
1979 return offset-offset_start;
1982 static int
1983 dissect_as_if_format_type_ver2_body(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1984 proto_tree *tree, urb_info_t *urb _U_)
1986 int offset_start;
1987 uint8_t format_type;
1989 offset_start = offset;
1991 proto_tree_add_item(tree, hf_as_if_ft_formattype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1992 format_type = tvb_get_uint8(tvb, offset);
1993 offset++;
1995 if (format_type==1) {
1996 proto_tree_add_item(tree, hf_as_if_ft_subslotsize, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1997 offset += 1;
1999 proto_tree_add_item(tree, hf_as_if_ft_bitresolution, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2000 offset += 1;
2003 return offset-offset_start;
2006 static int
2007 dissect_as_if_format_type_body(tvbuff_t *tvb, int offset, packet_info *pinfo,
2008 proto_tree *tree, urb_info_t *urb)
2010 if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V1) {
2011 return dissect_as_if_format_type_ver1_body(tvb, offset, pinfo, tree, urb);
2012 } else if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2) {
2013 return dissect_as_if_format_type_ver2_body(tvb, offset, pinfo, tree, urb);
2016 return 0;
2019 static int
2020 dissect_as_ep_general_body(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2021 proto_tree *tree, urb_info_t *urb)
2023 int offset_start = offset;
2025 static int * const v1_attributes[] = {
2026 &hf_as_ep_gen_bmattributes_d0,
2027 &hf_as_ep_gen_bmattributes_d1,
2028 &hf_as_ep_gen_bmattributes_rsv,
2029 &hf_as_ep_gen_bmattributes_d7,
2030 NULL
2032 static int * const v2_attributes[] = {
2033 &hf_as_ep_gen_bmattributes_d7,
2034 NULL
2036 static int * const controls[] = {
2037 &hf_as_ep_gen_controls_pitch,
2038 &hf_as_ep_gen_controls_data_overrun,
2039 &hf_as_ep_gen_controls_data_underrun,
2040 &hf_as_ep_gen_controls_rsv,
2041 NULL
2044 /* do not try to dissect unknown versions */
2045 if (!((urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V1) ||
2046 (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2)))
2047 return 0;
2049 if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V1) {
2050 proto_tree_add_bitmask(tree, tvb, offset, hf_as_ep_gen_bmattributes, ett_as_ep_gen_attributes, v1_attributes, ENC_LITTLE_ENDIAN);
2051 offset++;
2052 } else if (urb->conv->interfaceProtocol == AUDIO_PROTOCOL_V2) {
2053 proto_tree_add_bitmask(tree, tvb, offset, hf_as_ep_gen_bmattributes, ett_as_ep_gen_attributes, v2_attributes, ENC_LITTLE_ENDIAN);
2054 offset++;
2055 proto_tree_add_bitmask(tree, tvb, offset, hf_as_ep_gen_controls, ett_as_ep_gen_controls, controls, ENC_LITTLE_ENDIAN);
2056 offset++;
2059 proto_tree_add_item(tree, hf_as_ep_gen_lockdelayunits, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2060 offset += 1;
2061 proto_tree_add_item(tree, hf_as_ep_gen_lockdelay, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2062 offset += 2;
2064 return offset-offset_start;
2067 static int
2068 dissect_ms_if_hdr_body(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2069 proto_tree *tree, urb_info_t *urb _U_)
2071 int offset_start;
2072 uint16_t bcdADC;
2073 uint8_t ver_major;
2074 double ver;
2076 offset_start = offset;
2078 bcdADC = tvb_get_letohs(tvb, offset);
2079 ver_major = USB_AUDIO_BCD44_TO_DEC(bcdADC>>8);
2080 ver = ver_major + USB_AUDIO_BCD44_TO_DEC(bcdADC&0xFF) / 100.0;
2082 proto_tree_add_double_format_value(tree, hf_ms_if_hdr_ver,
2083 tvb, offset, 2, ver, "%2.2f", ver);
2084 offset += 2;
2086 proto_tree_add_item(tree, hf_ms_if_hdr_total_len,
2087 tvb, offset, 2, ENC_LITTLE_ENDIAN);
2088 offset += 2;
2090 return offset-offset_start;
2093 static int
2094 dissect_ms_if_midi_in_body(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2095 proto_tree *tree, urb_info_t *urb _U_)
2097 int offset_start = offset;
2099 proto_tree_add_item(tree, hf_ms_if_midi_in_bjacktype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2100 offset += 1;
2101 proto_tree_add_item(tree, hf_ms_if_midi_in_bjackid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2102 offset += 1;
2103 proto_tree_add_item(tree, hf_ms_if_midi_in_ijack, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2104 offset += 1;
2106 return offset-offset_start;
2109 static int
2110 dissect_ms_if_midi_out_body(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2111 proto_tree *tree, urb_info_t *urb _U_)
2113 int offset_start = offset;
2114 uint8_t nrinputpins;
2116 proto_tree_add_item(tree, hf_ms_if_midi_out_bjacktype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2117 offset += 1;
2118 proto_tree_add_item(tree, hf_ms_if_midi_out_bjackid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2119 offset += 1;
2121 proto_tree_add_item(tree, hf_ms_if_midi_out_bnrinputpins, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2122 nrinputpins = tvb_get_uint8(tvb, offset);
2123 offset += 1;
2124 while (nrinputpins)
2126 proto_tree_add_item(tree, hf_ms_if_midi_out_basourceid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2127 offset += 1;
2128 proto_tree_add_item(tree, hf_ms_if_midi_out_basourcepin, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2129 offset += 1;
2130 nrinputpins--;
2133 proto_tree_add_item(tree, hf_ms_if_midi_out_ijack, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2134 offset += 1;
2136 return offset-offset_start;
2139 static int
2140 dissect_ms_ep_general_body(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2141 proto_tree *tree, urb_info_t *urb _U_)
2143 int offset_start = offset;
2144 uint8_t numjacks;
2146 proto_tree_add_item(tree, hf_ms_ep_gen_numjacks, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2147 numjacks = tvb_get_uint8(tvb, offset);
2148 offset += 1;
2149 while (numjacks)
2151 proto_tree_add_item(tree, hf_ms_ep_gen_baassocjackid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2152 offset += 1;
2153 numjacks--;
2156 return offset-offset_start;
2159 static int
2160 dissect_usb_audio_descriptor(tvbuff_t *tvb, packet_info *pinfo,
2161 proto_tree *tree, void *data)
2163 int offset = 0;
2164 int bytes_dissected = 0;
2165 urb_info_t *urb;
2166 proto_tree *desc_tree = NULL;
2167 proto_item *desc_tree_item;
2168 uint8_t desc_len;
2169 uint8_t desc_type;
2170 uint8_t desc_subtype;
2171 const char *subtype_str;
2173 urb = (urb_info_t *)data;
2174 if (!urb || !urb->conv || urb->conv->interfaceClass!=IF_CLASS_AUDIO)
2175 return 0;
2177 desc_len = tvb_get_uint8(tvb, offset);
2178 desc_type = tvb_get_uint8(tvb, offset+1);
2180 if (desc_type == CS_INTERFACE) {
2181 /* Switch to interface specific usb_conv_info */
2182 urb = wmem_new(pinfo->pool, urb_info_t);
2183 memcpy(urb, data, sizeof(urb_info_t));
2184 urb->conv = get_usb_iface_conv_info(pinfo, urb->conv->interfaceNum);
2187 if (desc_type==CS_INTERFACE &&
2188 urb->conv->interfaceSubclass==AUDIO_IF_SUBCLASS_AUDIOCONTROL) {
2190 desc_tree = proto_tree_add_subtree(tree, tvb, offset, desc_len,
2191 ett_usb_audio_desc, &desc_tree_item,
2192 "Class-specific Audio Control Interface Descriptor");
2194 dissect_usb_descriptor_header(desc_tree, tvb, offset,
2195 &aud_descriptor_type_vals_ext);
2196 offset += 2;
2198 desc_subtype = tvb_get_uint8(tvb, offset);
2199 proto_tree_add_item(desc_tree, hf_ac_if_desc_subtype,
2200 tvb, offset, 1, ENC_LITTLE_ENDIAN);
2201 subtype_str = try_val_to_str_ext(desc_subtype, &ac_subtype_vals_ext);
2202 if (subtype_str)
2203 proto_item_append_text(desc_tree_item, ": %s", subtype_str);
2204 offset++;
2206 bytes_dissected = offset;
2207 switch(desc_subtype) {
2208 case AC_SUBTYPE_HEADER:
2209 /* these subfunctions return the number of bytes dissected,
2210 this is not necessarily the length of the body
2211 as some components are not yet dissected
2212 we rely on the descriptor's length byte instead */
2213 bytes_dissected += dissect_ac_if_hdr_body(tvb, offset, pinfo, desc_tree, urb);
2214 break;
2215 case AC_SUBTYPE_INPUT_TERMINAL:
2216 bytes_dissected += dissect_ac_if_input_terminal(tvb, offset, pinfo, desc_tree, urb);
2217 break;
2218 case AC_SUBTYPE_OUTPUT_TERMINAL:
2219 bytes_dissected += dissect_ac_if_output_terminal(tvb, offset, pinfo, desc_tree, urb);
2220 break;
2221 case AC_SUBTYPE_MIXER_UNIT:
2222 bytes_dissected += dissect_ac_if_mixed_unit(tvb, offset, pinfo, desc_tree, urb);
2223 break;
2224 case AC_SUBTYPE_SELECTOR_UNIT:
2225 bytes_dissected += dissect_ac_if_selector_unit(tvb, offset, pinfo, desc_tree, urb);
2226 break;
2227 case AC_SUBTYPE_FEATURE_UNIT:
2228 bytes_dissected += dissect_ac_if_feature_unit(tvb, offset, pinfo, desc_tree, urb, desc_len);
2229 break;
2230 case AC_SUBTYPE_CLOCK_SOURCE:
2231 bytes_dissected += dissect_ac_if_clock_source(tvb, offset, pinfo, desc_tree, urb);
2232 break;
2233 case AC_SUBTYPE_CLOCK_SELECTOR:
2234 bytes_dissected += dissect_ac_if_clock_selector(tvb, offset, pinfo, desc_tree, urb);
2235 break;
2236 case AC_SUBTYPE_EXTENSION_UNIT:
2237 bytes_dissected += dissect_ac_if_extension_unit(tvb, offset, pinfo, desc_tree, urb);
2238 break;
2239 default:
2240 break;
2243 else if (desc_type==CS_INTERFACE &&
2244 urb->conv->interfaceSubclass==AUDIO_IF_SUBCLASS_AUDIOSTREAMING) {
2246 desc_tree = proto_tree_add_subtree(tree, tvb, offset, desc_len,
2247 ett_usb_audio_desc, &desc_tree_item,
2248 "Class-specific Audio Streaming Interface Descriptor");
2250 dissect_usb_descriptor_header(desc_tree, tvb, offset,
2251 &aud_descriptor_type_vals_ext);
2252 offset += 2;
2254 desc_subtype = tvb_get_uint8(tvb, offset);
2255 proto_tree_add_item(desc_tree, hf_as_if_desc_subtype,
2256 tvb, offset, 1, ENC_LITTLE_ENDIAN);
2257 subtype_str = try_val_to_str_ext(desc_subtype, &as_subtype_vals_ext);
2258 if (subtype_str)
2259 proto_item_append_text(desc_tree_item, ": %s", subtype_str);
2260 offset++;
2262 bytes_dissected = offset;
2263 switch(desc_subtype) {
2264 case AS_SUBTYPE_GENERAL:
2265 bytes_dissected += dissect_as_if_general_body(tvb, offset, pinfo,
2266 desc_tree, urb);
2267 break;
2268 case AS_SUBTYPE_FORMAT_TYPE:
2269 bytes_dissected += dissect_as_if_format_type_body(tvb, offset, pinfo,
2270 desc_tree, urb);
2271 break;
2272 default:
2273 break;
2276 /* there are no class-specific endpoint descriptors for audio control */
2277 else if (desc_type == CS_ENDPOINT &&
2278 urb->conv->interfaceSubclass==AUDIO_IF_SUBCLASS_AUDIOSTREAMING) {
2280 desc_tree = proto_tree_add_subtree(tree, tvb, offset, desc_len,
2281 ett_usb_audio_desc, &desc_tree_item,
2282 "Class-specific Audio Streaming Endpoint Descriptor");
2284 dissect_usb_descriptor_header(desc_tree, tvb, offset,
2285 &aud_descriptor_type_vals_ext);
2286 offset += 2;
2288 desc_subtype = tvb_get_uint8(tvb, offset);
2289 proto_tree_add_item(desc_tree, hf_as_ep_desc_subtype,
2290 tvb, offset, 1, ENC_LITTLE_ENDIAN);
2291 offset++;
2293 bytes_dissected = offset;
2294 switch(desc_subtype) {
2295 case AS_EP_SUBTYPE_GENERAL:
2296 bytes_dissected += dissect_as_ep_general_body(tvb, offset, pinfo,
2297 desc_tree, urb);
2298 break;
2299 default:
2300 break;
2303 else if (desc_type==CS_INTERFACE &&
2304 urb->conv->interfaceSubclass==AUDIO_IF_SUBCLASS_MIDISTREAMING) {
2305 desc_tree = proto_tree_add_subtree(tree, tvb, offset, desc_len,
2306 ett_usb_audio_desc, &desc_tree_item,
2307 "Class-specific MIDI Streaming Interface Descriptor");
2309 dissect_usb_descriptor_header(desc_tree, tvb, offset,
2310 &aud_descriptor_type_vals_ext);
2311 offset += 2;
2313 desc_subtype = tvb_get_uint8(tvb, offset);
2314 proto_tree_add_item(desc_tree, hf_ms_if_desc_subtype,
2315 tvb, offset, 1, ENC_LITTLE_ENDIAN);
2316 subtype_str = try_val_to_str_ext(desc_subtype, &ms_if_subtype_vals_ext);
2317 if (subtype_str)
2318 proto_item_append_text(desc_tree_item, ": %s", subtype_str);
2319 offset++;
2321 bytes_dissected = offset;
2322 switch(desc_subtype) {
2323 case MS_IF_SUBTYPE_HEADER:
2324 bytes_dissected += dissect_ms_if_hdr_body(tvb, offset, pinfo,
2325 desc_tree, urb);
2326 break;
2327 case MS_IF_SUBTYPE_MIDI_IN_JACK:
2328 bytes_dissected += dissect_ms_if_midi_in_body(tvb, offset, pinfo,
2329 desc_tree, urb);
2330 break;
2331 case MS_IF_SUBTYPE_MIDI_OUT_JACK:
2332 bytes_dissected += dissect_ms_if_midi_out_body(tvb, offset, pinfo,
2333 desc_tree, urb);
2334 break;
2335 default:
2336 break;
2339 else if (desc_type==CS_ENDPOINT &&
2340 urb->conv->interfaceSubclass==AUDIO_IF_SUBCLASS_MIDISTREAMING) {
2341 desc_tree = proto_tree_add_subtree(tree, tvb, offset, desc_len,
2342 ett_usb_audio_desc, &desc_tree_item,
2343 "Class-specific MIDI Streaming Endpoint Descriptor");
2345 dissect_usb_descriptor_header(desc_tree, tvb, offset,
2346 &aud_descriptor_type_vals_ext);
2347 offset += 2;
2349 desc_subtype = tvb_get_uint8(tvb, offset);
2350 proto_tree_add_item(desc_tree, hf_ms_ep_desc_subtype,
2351 tvb, offset, 1, ENC_LITTLE_ENDIAN);
2352 offset++;
2354 bytes_dissected = offset;
2355 switch(desc_subtype) {
2356 case MS_EP_SUBTYPE_GENERAL:
2357 bytes_dissected += dissect_ms_ep_general_body(tvb, offset, pinfo,
2358 desc_tree, urb);
2359 break;
2360 default:
2361 break;
2364 else
2365 return 0;
2367 if (bytes_dissected < desc_len) {
2368 proto_tree_add_expert(desc_tree, pinfo, &ei_usb_audio_undecoded, tvb, bytes_dissected, desc_len-bytes_dissected);
2370 return desc_len;
2373 static usb_audio_entity_t
2374 get_addressed_entity_type(urb_info_t *urb)
2376 usb_audio_entity_t entity = USB_AUDIO_ENTITY_UNKNOWN;
2378 if (USB_RECIPIENT(urb->usb_trans_info->setup.requesttype) == RQT_SETUP_RECIPIENT_INTERFACE) {
2379 int8_t id = (urb->usb_trans_info->setup.wIndex & 0xFF00) >> 8;
2380 entity = get_entity_type(urb, id);
2383 return entity;
2386 static bool
2387 has_data_stage(urb_info_t *urb)
2389 /* If the two conditions are fulfilled, then URB we got should contain data stage */
2390 return (urb->usb_trans_info->setup.wLength > 0) &&
2391 (urb->usb_trans_info->setup.requesttype & USB_DIR_IN) == (urb->is_request ? USB_DIR_OUT : USB_DIR_IN);
2394 static int
2395 dissect_windex_and_wlength(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
2396 proto_tree *tree, urb_info_t *urb)
2398 int offset_start = offset;
2399 static int * const windex_interface[] = {
2400 &hf_windex_interface,
2401 &hf_windex_entity_id,
2402 NULL
2404 static int * const windex_endpoint[] = {
2405 &hf_windex_endpoint,
2406 NULL
2409 if (USB_RECIPIENT(urb->usb_trans_info->setup.requesttype) == RQT_SETUP_RECIPIENT_INTERFACE) {
2410 proto_tree_add_bitmask(tree, tvb, offset, hf_windex, ett_windex, windex_interface, ENC_LITTLE_ENDIAN);
2411 } else if (USB_RECIPIENT(urb->usb_trans_info->setup.requesttype) == RQT_SETUP_RECIPIENT_ENDPOINT) {
2412 proto_tree_add_bitmask(tree, tvb, offset, hf_windex, ett_windex, windex_endpoint, ENC_LITTLE_ENDIAN);
2414 offset += 2;
2416 proto_tree_add_item(tree, hf_wlength, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2417 offset += 2;
2419 return offset - offset_start;
2422 static int
2423 dissect_v1_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
2424 proto_tree *tree, urb_info_t *urb)
2426 int offset_start = offset;
2427 proto_item *ti;
2428 const char *request_str;
2429 uint8_t bRequest;
2430 usb_audio_entity_t entity = get_addressed_entity_type(urb);
2431 const value_string *control_selector_vals = NULL;
2432 uint8_t control_selector;
2433 const char *str;
2434 const char *title = "Unknown Parameter Block";
2435 int *parameter_hf = NULL;
2436 int attribute_size;
2437 int *wvalue_fields[] = {
2438 NULL, /* Channel number or zero */
2439 NULL, /* Control selector if known */
2440 NULL
2443 bRequest = urb->usb_trans_info->setup.request;
2444 request_str = try_val_to_str_ext(bRequest, &v1_brequest_vals_ext);
2445 if (request_str)
2446 col_set_str(pinfo->cinfo, COL_INFO, request_str);
2448 control_selector = (urb->usb_trans_info->setup.wValue & 0xFF00) >> 8;
2450 switch (entity) {
2451 case USB_AUDIO_ENTITY_SELECTOR:
2452 col_append_str(pinfo->cinfo, COL_INFO, " SELECTOR");
2453 parameter_hf = &hf_parameter_bselector;
2454 attribute_size = 1;
2455 title = "Selector Control Parameter Block";
2456 break;
2457 case USB_AUDIO_ENTITY_FEATURE_UNIT:
2458 wvalue_fields[0] = &hf_wvalue_channel_number;
2459 wvalue_fields[1] = &hf_wvalue_fu_cs_v1;
2460 control_selector_vals = v1_fu_cs_vals;
2461 if (control_selector == MUTE_CONTROL) {
2462 parameter_hf = &hf_parameter_bmute;
2463 attribute_size = 1;
2464 title = "Mute Control Parameter Block";
2465 } else if (control_selector == VOLUME_CONTROL) {
2466 parameter_hf = &hf_parameter_wvolume;
2467 attribute_size = 2;
2468 title = "Volume Control Parameter Block";
2470 break;
2471 default:
2472 break;
2475 str = control_selector_vals ? try_val_to_str(control_selector, control_selector_vals) : NULL;
2476 if (str) {
2477 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", str);
2480 if (urb->is_request) {
2481 proto_tree_add_item(tree, hf_brequest_v1, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2482 offset++;
2484 if (wvalue_fields[0]) {
2485 proto_tree_add_bitmask(tree, tvb, offset, hf_wvalue, ett_wvalue, wvalue_fields, ENC_LITTLE_ENDIAN);
2486 } else {
2487 ti = proto_tree_add_item(tree, hf_wvalue, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2488 /* Selector doesn't use wValue (must be zero), all others do use it */
2489 if (entity != USB_AUDIO_ENTITY_SELECTOR) {
2490 expert_add_info(pinfo, ti, &ei_usb_audio_undecoded);
2493 offset += 2;
2495 offset += dissect_windex_and_wlength(tvb, offset, pinfo, tree, urb);
2499 if (has_data_stage(urb)) {
2500 proto_tree *subtree;
2501 proto_item *subtree_item;
2503 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_parameter_block, &subtree_item, title);
2505 if (parameter_hf) {
2506 proto_tree_add_item(subtree, *parameter_hf, tvb, offset, attribute_size, ENC_LITTLE_ENDIAN);
2507 offset += attribute_size;
2510 if (tvb_captured_length_remaining(tvb, offset)) {
2511 expert_add_info(pinfo, subtree_item, &ei_usb_audio_undecoded);
2512 offset += tvb_captured_length_remaining(tvb, offset);
2516 return offset - offset_start;
2519 static int
2520 dissect_v2_control_cur_range(tvbuff_t *tvb, int offset, packet_info *pinfo,
2521 proto_tree *tree, urb_info_t *urb)
2523 int offset_start = offset;
2524 proto_item *ti;
2525 usb_audio_entity_t entity = get_addressed_entity_type(urb);
2526 const value_string *control_selector_vals = NULL;
2527 uint8_t control_selector, channel_number;
2528 parameter_layout_t layout = PARAMETER_LAYOUT_UNKNOWN;
2529 const char *parameter_str = NULL;
2530 const char *str;
2531 int *wvalue_fields[] = {
2532 &hf_wvalue_channel_number,
2533 NULL, /* Control selector if known */
2534 NULL
2537 control_selector = (urb->usb_trans_info->setup.wValue & 0xFF00) >> 8;
2538 channel_number = urb->usb_trans_info->setup.wValue & 0x00FF;
2540 switch (entity) {
2541 case USB_AUDIO_ENTITY_CLOCK_SOURCE:
2542 wvalue_fields[1] = &hf_wvalue_clksrc_cs;
2543 control_selector_vals = v2_clksrc_cs_vals;
2544 if ((control_selector == V2_CS_SAM_FREQ_CONTROL) && (channel_number == 0)) {
2545 layout = PARAMETER_LAYOUT_3;
2546 parameter_str = "Frequency [Hz]";
2547 } else if (control_selector == V2_CS_CLOCK_VALID_CONTROL) {
2548 layout = PARAMETER_LAYOUT_1;
2549 parameter_str = "Clock Validity";
2551 break;
2552 case USB_AUDIO_ENTITY_CLOCK_SELECTOR:
2553 wvalue_fields[1] = &hf_wvalue_clksel_cs;
2554 control_selector_vals = v2_clksel_cs_vals;
2555 if ((control_selector == V2_CX_CLOCK_SELECTOR_CONTROL) && (channel_number == 0)) {
2556 layout = PARAMETER_LAYOUT_1;
2557 parameter_str = "Clock Input Pin";
2559 break;
2560 default:
2561 break;
2564 str = control_selector_vals ? try_val_to_str(control_selector, control_selector_vals) : NULL;
2565 if (str) {
2566 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", str);
2569 if (urb->is_request) {
2570 ti = proto_tree_add_bitmask(tree, tvb, offset, hf_wvalue, ett_wvalue, wvalue_fields, ENC_LITTLE_ENDIAN);
2571 if (wvalue_fields[1] == NULL) {
2572 /* Control selector not handled, mark as undecoded */
2573 expert_add_info(pinfo, ti, &ei_usb_audio_undecoded);
2575 offset += 2;
2577 offset += dissect_windex_and_wlength(tvb, offset, pinfo, tree, urb);
2580 if (has_data_stage(urb)) {
2581 proto_tree *subtree;
2582 proto_item *subtree_item;
2583 const char *title;
2584 uint32_t n;
2585 int attribute_size;
2586 int cur_hf, min_hf, max_hf, res_hf;
2588 switch (layout) {
2589 case PARAMETER_LAYOUT_1:
2590 title = "Layout 1 Parameter Block";
2591 attribute_size = 1;
2592 cur_hf = hf_parameter_bcur;
2593 min_hf = hf_parameter_bmin;
2594 max_hf = hf_parameter_bmax;
2595 res_hf = hf_parameter_bres;
2596 break;
2597 case PARAMETER_LAYOUT_2:
2598 title = "Layout 2 Parameter Block";
2599 attribute_size = 2;
2600 cur_hf = hf_parameter_wcur;
2601 min_hf = hf_parameter_wmin;
2602 max_hf = hf_parameter_wmax;
2603 res_hf = hf_parameter_wres;
2604 break;
2605 case PARAMETER_LAYOUT_3:
2606 title = "Layout 3 Parameter Block";
2607 attribute_size = 4;
2608 cur_hf = hf_parameter_dcur;
2609 min_hf = hf_parameter_dmin;
2610 max_hf = hf_parameter_dmax;
2611 res_hf = hf_parameter_dres;
2612 break;
2613 default:
2614 title = "Unknown Layout Parameter Block";
2615 attribute_size = 0;
2616 cur_hf = min_hf = max_hf = res_hf = 0;
2617 break;
2620 subtree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_parameter_block, &subtree_item, title);
2621 if (parameter_str) {
2622 proto_item_append_text(subtree_item, ": %s", parameter_str);
2625 if (urb->usb_trans_info->setup.request == V2_REQUEST_RANGE) {
2626 uint32_t max_n;
2628 proto_tree_add_item_ret_uint(subtree, hf_parameter_wnumsubranges, tvb, offset, 2, ENC_LITTLE_ENDIAN, &n);
2629 offset += 2;
2631 if (attribute_size == 0) {
2632 max_n = 0;
2633 } else if (urb->usb_trans_info->setup.wLength >= 2 + n * attribute_size) {
2634 /* Host requested enough bytes to contain all data */
2635 max_n = n;
2636 } else if (urb->usb_trans_info->setup.wLength > 2) {
2637 /* Host requested less, this is not Malformed in any way */
2638 max_n = (urb->usb_trans_info->setup.wLength - 2) / (3 * attribute_size);
2639 } else {
2640 max_n = 0;
2643 for (uint32_t i = 0; i < max_n; i++) {
2644 proto_tree_add_item(subtree, min_hf, tvb, offset, attribute_size, ENC_LITTLE_ENDIAN);
2645 offset += attribute_size;
2646 proto_tree_add_item(subtree, max_hf, tvb, offset, attribute_size, ENC_LITTLE_ENDIAN);
2647 offset += attribute_size;
2648 proto_tree_add_item(subtree, res_hf, tvb, offset, attribute_size, ENC_LITTLE_ENDIAN);
2649 offset += attribute_size;
2651 } else if (attribute_size) {
2652 proto_tree_add_item(subtree, cur_hf, tvb, offset, attribute_size, ENC_LITTLE_ENDIAN);
2653 offset += attribute_size;
2654 } else {
2655 expert_add_info(pinfo, subtree_item, &ei_usb_audio_undecoded);
2656 offset += tvb_captured_length_remaining(tvb, offset);
2660 return offset - offset_start;
2663 static int
2664 dissect_v2_control(tvbuff_t *tvb, int offset, packet_info *pinfo,
2665 proto_tree *tree, urb_info_t *urb)
2667 int offset_start = offset;
2668 const char *request_str;
2669 uint8_t bRequest;
2671 bRequest = urb->usb_trans_info->setup.request;
2672 request_str = try_val_to_str_ext(bRequest, &v2_brequest_vals_ext);
2673 if (request_str)
2674 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", request_str);
2676 if (urb->is_request) {
2677 proto_tree_add_item(tree, hf_brequest_v2, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2678 offset++;
2681 if ((bRequest == V2_REQUEST_CUR) || (bRequest == V2_REQUEST_RANGE)) {
2682 offset += dissect_v2_control_cur_range(tvb, offset, pinfo, tree, urb);
2685 return offset - offset_start;
2688 static int
2689 dissect_usb_audio_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
2691 urb_info_t *urb = (urb_info_t *)data;
2692 int offset, length;
2694 /* Reject the packet if data is NULL */
2695 if ((urb == NULL) || (urb->conv == NULL))
2696 return 0;
2698 /* Dissect only Class requests directed to interface or endpoint */
2699 if ((urb->usb_trans_info == NULL) ||
2700 (USB_TYPE(urb->usb_trans_info->setup.requesttype) != RQT_SETUP_TYPE_CLASS) ||
2701 !(USB_RECIPIENT(urb->usb_trans_info->setup.requesttype) == RQT_SETUP_RECIPIENT_INTERFACE ||
2702 USB_RECIPIENT(urb->usb_trans_info->setup.requesttype) == RQT_SETUP_RECIPIENT_ENDPOINT)) {
2703 return 0;
2706 col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBAUDIO");
2707 col_set_str(pinfo->cinfo, COL_INFO, urb->usb_trans_info->setup.requesttype & USB_DIR_IN ? "GET" : "SET");
2709 length = tvb_reported_length(tvb);
2710 offset = 0;
2712 if ((urb->conv->interfaceClass == IF_CLASS_AUDIO) &&
2713 (urb->conv->interfaceSubclass == AUDIO_IF_SUBCLASS_AUDIOCONTROL)) {
2714 switch (urb->conv->interfaceProtocol) {
2715 case AUDIO_PROTOCOL_V1:
2716 offset += dissect_v1_control(tvb, offset, pinfo, parent_tree, urb);
2717 break;
2718 case AUDIO_PROTOCOL_V2:
2719 offset += dissect_v2_control(tvb, offset, pinfo, parent_tree, urb);
2720 break;
2721 default:
2722 break;
2726 if (!urb->is_request &&
2727 (((urb->usb_trans_info->setup.requesttype & USB_DIR_IN) == USB_DIR_OUT) ||
2728 (urb->usb_trans_info->setup.wLength == 0))) {
2729 /* We are dissecting URB status information, it is not really a "response" */
2730 col_append_str(pinfo->cinfo, COL_INFO, " status");
2731 } else {
2732 col_append_str(pinfo->cinfo, COL_INFO, urb->is_request ? " request" : " response");
2735 if (offset < length) {
2736 proto_tree_add_expert(parent_tree, pinfo, &ei_usb_audio_undecoded, tvb, offset, length - offset);
2739 return length;
2742 /* dissector for usb midi bulk data */
2743 static int
2744 dissect_usb_audio_bulk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data)
2746 urb_info_t *urb = (urb_info_t *)data;
2747 int offset, length;
2748 int i;
2750 /* Reject the packet if data is NULL */
2751 if ((urb == NULL) || (urb->conv == NULL))
2752 return 0;
2754 col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBAUDIO");
2756 length = tvb_reported_length(tvb);
2757 offset = 0;
2759 switch (urb->conv->interfaceSubclass)
2761 case AUDIO_IF_SUBCLASS_MIDISTREAMING:
2762 col_set_str(pinfo->cinfo, COL_INFO, "USB-MIDI Event Packets");
2764 for (i = 0; i < length / 4; i++)
2766 dissect_usb_midi_event(tvb, pinfo, parent_tree, offset);
2767 offset += 4;
2769 break;
2770 default:
2771 proto_tree_add_expert(parent_tree, pinfo, &ei_usb_audio_undecoded, tvb, offset, length);
2774 return length;
2777 void
2778 proto_register_usb_audio(void)
2780 static hf_register_info hf[] = {
2781 { &hf_midi_cable_number,
2782 { "Cable Number", "usbaudio.midi.cable_number", FT_UINT8, BASE_HEX,
2783 NULL, 0xF0, NULL, HFILL }},
2784 { &hf_midi_code_index,
2785 { "Code Index", "usbaudio.midi.code_index", FT_UINT8, BASE_HEX,
2786 VALS(code_index_vals), 0x0F, NULL, HFILL }},
2787 { &hf_midi_event,
2788 { "MIDI Event", "usbaudio.midi.event", FT_BYTES, BASE_NONE,
2789 NULL, 0x0, NULL, HFILL }},
2790 { &hf_midi_padding,
2791 { "Padding", "usbaudio.midi.padding", FT_BYTES, BASE_NONE,
2792 NULL, 0x0, "Must be zero", HFILL }},
2794 { &hf_ac_if_desc_subtype,
2795 { "Subtype", "usbaudio.ac_if_subtype", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
2796 &ac_subtype_vals_ext, 0x0, "bDescriptorSubtype", HFILL }},
2797 { &hf_ac_if_hdr_ver,
2798 { "Version", "usbaudio.ac_if_hdr.bcdADC",
2799 FT_DOUBLE, BASE_NONE, NULL, 0, "bcdADC", HFILL }},
2800 { &hf_ac_if_hdr_total_len,
2801 { "Total length", "usbaudio.ac_if_hdr.wTotalLength",
2802 FT_UINT16, BASE_DEC, NULL, 0x0, "wTotalLength", HFILL }},
2803 { &hf_ac_if_hdr_bInCollection,
2804 { "Total number of interfaces", "usbaudio.ac_if_hdr.bInCollection",
2805 FT_UINT8, BASE_DEC, NULL, 0x0, "bInCollection", HFILL }},
2806 { &hf_ac_if_hdr_if_num,
2807 { "Interface number", "usbaudio.ac_if_hdr.baInterfaceNr",
2808 FT_UINT8, BASE_DEC, NULL, 0x0, "baInterfaceNr", HFILL }},
2809 { &hf_ac_if_hdr_category,
2810 { "Category", "usbaudio.ac_if_hdr.bCategory",
2811 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &audio_function_categories_vals_ext, 0x00, "bCategory", HFILL }},
2812 { &hf_ac_if_hdr_controls,
2813 { "Controls", "usbaudio.ac_if_hdr.bmControls",
2814 FT_UINT8, BASE_HEX, NULL, 0x0, "bmControls", HFILL }},
2815 { &hf_ac_if_hdr_controls_latency,
2816 { "Latency Control", "usbaudio.ac_if_hdr.bmControls.latency",
2817 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x03, NULL, HFILL }},
2818 { &hf_ac_if_hdr_controls_rsv,
2819 { "Reserved", "usbaudio.ac_if_hdr.bmControls.rsv",
2820 FT_UINT8, BASE_HEX, NULL, 0xFC, "Must be zero", HFILL }},
2821 { &hf_ac_if_input_terminalid,
2822 { "Terminal ID", "usbaudio.ac_if_input.bTerminalID",
2823 FT_UINT8, BASE_DEC, NULL, 0x0, "bTerminalID", HFILL }},
2824 { &hf_ac_if_input_terminaltype,
2825 { "Terminal Type", "usbaudio.ac_if_input.wTerminalType", FT_UINT16,
2826 BASE_HEX|BASE_EXT_STRING, &terminal_types_vals_ext, 0x00, "wTerminalType", HFILL }},
2827 { &hf_ac_if_input_assocterminal,
2828 { "Assoc Terminal", "usbaudio.ac_if_input.bAssocTerminal",
2829 FT_UINT8, BASE_DEC, NULL, 0x0, "bAssocTerminal", HFILL }},
2830 { &hf_ac_if_input_csourceid,
2831 { "Connected Clock Entity", "usbaudio.ac_if_input.bCSourceID",
2832 FT_UINT8, BASE_DEC, NULL, 0x0, "bCSourceID", HFILL }},
2833 { &hf_ac_if_input_nrchannels,
2834 { "Number Channels", "usbaudio.ac_if_input.bNrChannels",
2835 FT_UINT8, BASE_DEC, NULL, 0x0, "bNrChannels", HFILL }},
2836 { &hf_ac_if_input_wchannelconfig,
2837 { "Channel Config", "usbaudio.ac_if_input.wChannelConfig",
2838 FT_UINT16, BASE_HEX, NULL, 0x0, "wChannelConfig", HFILL }},
2839 { &hf_ac_if_input_wchannelconfig_d0,
2840 { "Left Front", "usbaudio.ac_if_input.wChannelConfig.d0",
2841 FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL }},
2842 { &hf_ac_if_input_wchannelconfig_d1,
2843 { "Right Front", "usbaudio.ac_if_input.wChannelConfig.d1",
2844 FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL }},
2845 { &hf_ac_if_input_wchannelconfig_d2,
2846 { "Center Front", "usbaudio.ac_if_input.wChannelConfig.d2",
2847 FT_BOOLEAN, 16, NULL, 0x0004, NULL, HFILL }},
2848 { &hf_ac_if_input_wchannelconfig_d3,
2849 { "Low Frequency Enhancement", "usbaudio.ac_if_input.wChannelConfig.d3",
2850 FT_BOOLEAN, 16, NULL, 0x0008, NULL, HFILL }},
2851 { &hf_ac_if_input_wchannelconfig_d4,
2852 { "Left Surround", "usbaudio.ac_if_input.wChannelConfig.d4",
2853 FT_BOOLEAN, 16, NULL, 0x0010, NULL, HFILL }},
2854 { &hf_ac_if_input_wchannelconfig_d5,
2855 { "Right Surround", "usbaudio.ac_if_input.wChannelConfig.d5",
2856 FT_BOOLEAN, 16, NULL, 0x0020, NULL, HFILL }},
2857 { &hf_ac_if_input_wchannelconfig_d6,
2858 { "Left of Center", "usbaudio.ac_if_input.wChannelConfig.d6",
2859 FT_BOOLEAN, 16, NULL, 0x0040, NULL, HFILL }},
2860 { &hf_ac_if_input_wchannelconfig_d7,
2861 { "Right of Center", "usbaudio.ac_if_input.wChannelConfig.d7",
2862 FT_BOOLEAN, 16, NULL, 0x0080, NULL, HFILL }},
2863 { &hf_ac_if_input_wchannelconfig_d8,
2864 { "Surround", "usbaudio.ac_if_input.wChannelConfig.d8",
2865 FT_BOOLEAN, 16, NULL, 0x0100, NULL, HFILL }},
2866 { &hf_ac_if_input_wchannelconfig_d9,
2867 { "Side Left", "usbaudio.ac_if_input.wChannelConfig.d9",
2868 FT_BOOLEAN, 16, NULL, 0x0200, NULL, HFILL }},
2869 { &hf_ac_if_input_wchannelconfig_d10,
2870 { "Side Right", "usbaudio.ac_if_input.wChannelConfig.d10",
2871 FT_BOOLEAN, 16, NULL, 0x0400, NULL, HFILL }},
2872 { &hf_ac_if_input_wchannelconfig_d11,
2873 { "Top", "usbaudio.ac_if_input.wChannelConfig.d11",
2874 FT_BOOLEAN, 16, NULL, 0x0800, NULL, HFILL }},
2875 { &hf_ac_if_input_wchannelconfig_rsv,
2876 { "Reserved", "usbaudio.ac_if_input.wChannelConfig.rsv",
2877 FT_UINT16, BASE_HEX, NULL, 0xF000, NULL, HFILL }},
2878 { &hf_ac_if_input_bmchannelconfig,
2879 { "Channel Config", "usbaudio.ac_if_input.bmChannelConfig",
2880 FT_UINT32, BASE_HEX, NULL, 0x0, "bmChannelConfig", HFILL }},
2881 { &hf_ac_if_input_bmchannelconfig_d0,
2882 { "Front Left", "usbaudio.ac_if_input.bmChannelConfig.d0",
2883 FT_BOOLEAN, 32, NULL, (1u << 0), NULL, HFILL }},
2884 { &hf_ac_if_input_bmchannelconfig_d1,
2885 { "Front Right", "usbaudio.ac_if_input.bmChannelConfig.d1",
2886 FT_BOOLEAN, 32, NULL, (1u << 1), NULL, HFILL }},
2887 { &hf_ac_if_input_bmchannelconfig_d2,
2888 { "Front Center", "usbaudio.ac_if_input.bmChannelConfig.d2",
2889 FT_BOOLEAN, 32, NULL, (1u << 2), NULL, HFILL }},
2890 { &hf_ac_if_input_bmchannelconfig_d3,
2891 { "Low Frequency Effects", "usbaudio.ac_if_input.bmChannelConfig.d3",
2892 FT_BOOLEAN, 32, NULL, (1u << 3), NULL, HFILL }},
2893 { &hf_ac_if_input_bmchannelconfig_d4,
2894 { "Back Left", "usbaudio.ac_if_input.bmChannelConfig.d4",
2895 FT_BOOLEAN, 32, NULL, (1u << 4), NULL, HFILL }},
2896 { &hf_ac_if_input_bmchannelconfig_d5,
2897 { "Back Right", "usbaudio.ac_if_input.bmChannelConfig.d5",
2898 FT_BOOLEAN, 32, NULL, (1u << 5), NULL, HFILL }},
2899 { &hf_ac_if_input_bmchannelconfig_d6,
2900 { "Front Left of Center", "usbaudio.ac_if_input.bmChannelConfig.d6",
2901 FT_BOOLEAN, 32, NULL, (1u << 6), NULL, HFILL }},
2902 { &hf_ac_if_input_bmchannelconfig_d7,
2903 { "Front Right of Center", "usbaudio.ac_if_input.bmChannelConfig.d7",
2904 FT_BOOLEAN, 32, NULL, (1u << 7), NULL, HFILL }},
2905 { &hf_ac_if_input_bmchannelconfig_d8,
2906 { "Back Center", "usbaudio.ac_if_input.bmChannelConfig.d8",
2907 FT_BOOLEAN, 32, NULL, (1u << 8), NULL, HFILL }},
2908 { &hf_ac_if_input_bmchannelconfig_d9,
2909 { "Side Left", "usbaudio.ac_if_input.bmChannelConfig.d9",
2910 FT_BOOLEAN, 32, NULL, (1u << 9), NULL, HFILL }},
2911 { &hf_ac_if_input_bmchannelconfig_d10,
2912 { "Side Right", "usbaudio.ac_if_input.bmChannelConfig.d10",
2913 FT_BOOLEAN, 32, NULL, (1u << 10), NULL, HFILL }},
2914 { &hf_ac_if_input_bmchannelconfig_d11,
2915 { "Top Center", "usbaudio.ac_if_input.bmChannelConfig.d11",
2916 FT_BOOLEAN, 32, NULL, (1u << 11), NULL, HFILL }},
2917 { &hf_ac_if_input_bmchannelconfig_d12,
2918 { "Top Front Left", "usbaudio.ac_if_input.bmChannelConfig.d12",
2919 FT_BOOLEAN, 32, NULL, (1u << 12), NULL, HFILL }},
2920 { &hf_ac_if_input_bmchannelconfig_d13,
2921 { "Top Front Center", "usbaudio.ac_if_input.bmChannelConfig.d13",
2922 FT_BOOLEAN, 32, NULL, (1u << 13), NULL, HFILL }},
2923 { &hf_ac_if_input_bmchannelconfig_d14,
2924 { "Top Front Right", "usbaudio.ac_if_input.bmChannelConfig.d14",
2925 FT_BOOLEAN, 32, NULL, (1u << 14), NULL, HFILL }},
2926 { &hf_ac_if_input_bmchannelconfig_d15,
2927 { "Top Back Left", "usbaudio.ac_if_input.bmChannelConfig.d15",
2928 FT_BOOLEAN, 32, NULL, (1u << 15), NULL, HFILL }},
2929 { &hf_ac_if_input_bmchannelconfig_d16,
2930 { "Top Back Center", "usbaudio.ac_if_input.bmChannelConfig.d16",
2931 FT_BOOLEAN, 32, NULL, (1u << 16), NULL, HFILL }},
2932 { &hf_ac_if_input_bmchannelconfig_d17,
2933 { "Top Back Right", "usbaudio.ac_if_input.bmChannelConfig.d17",
2934 FT_BOOLEAN, 32, NULL, (1u << 17), NULL, HFILL }},
2935 { &hf_ac_if_input_bmchannelconfig_d18,
2936 { "Top Front Left of Center", "usbaudio.ac_if_input.bmChannelConfig.d18",
2937 FT_BOOLEAN, 32, NULL, (1u << 18), NULL, HFILL }},
2938 { &hf_ac_if_input_bmchannelconfig_d19,
2939 { "Top Front Right of Center", "usbaudio.ac_if_input.bmChannelConfig.d19",
2940 FT_BOOLEAN, 32, NULL, (1u << 19), NULL, HFILL }},
2941 { &hf_ac_if_input_bmchannelconfig_d20,
2942 { "Left Low Frequency Effects", "usbaudio.ac_if_input.bmChannelConfig.d20",
2943 FT_BOOLEAN, 32, NULL, (1u << 20), NULL, HFILL }},
2944 { &hf_ac_if_input_bmchannelconfig_d21,
2945 { "Right Low Frequency Effects", "usbaudio.ac_if_input.bmChannelConfig.d21",
2946 FT_BOOLEAN, 32, NULL, (1u << 21), NULL, HFILL }},
2947 { &hf_ac_if_input_bmchannelconfig_d22,
2948 { "Top Side Left", "usbaudio.ac_if_input.bmChannelConfig.d22",
2949 FT_BOOLEAN, 32, NULL, (1u << 22), NULL, HFILL }},
2950 { &hf_ac_if_input_bmchannelconfig_d23,
2951 { "Top Side Right", "usbaudio.ac_if_input.bmChannelConfig.d23",
2952 FT_BOOLEAN, 32, NULL, (1u << 23), NULL, HFILL }},
2953 { &hf_ac_if_input_bmchannelconfig_d24,
2954 { "Bottom Center", "usbaudio.ac_if_input.bmChannelConfig.d24",
2955 FT_BOOLEAN, 32, NULL, (1u << 24), NULL, HFILL }},
2956 { &hf_ac_if_input_bmchannelconfig_d25,
2957 { "Back Left of Center", "usbaudio.ac_if_input.bmChannelConfig.d25",
2958 FT_BOOLEAN, 32, NULL, (1u << 25), NULL, HFILL }},
2959 { &hf_ac_if_input_bmchannelconfig_d26,
2960 { "Back Right of Center", "usbaudio.ac_if_input.bmChannelConfig.d26",
2961 FT_BOOLEAN, 32, NULL, (1u << 26), NULL, HFILL }},
2962 { &hf_ac_if_input_bmchannelconfig_rsv,
2963 { "Reserved", "usbaudio.ac_if_input.bmChannelConfig.rsv",
2964 FT_BOOLEAN, 32, NULL, (0xFu << 27), NULL, HFILL }},
2965 { &hf_ac_if_input_bmchannelconfig_d31,
2966 { "Raw Data", "usbaudio.ac_if_input.bmChannelConfig.d31",
2967 FT_BOOLEAN, 32, NULL, (1u << 31), NULL, HFILL }},
2968 { &hf_ac_if_input_channelnames,
2969 { "Channel Names", "usbaudio.ac_if_input.iChannelNames",
2970 FT_UINT8, BASE_DEC, NULL, 0x0, "iChannelNames", HFILL }},
2971 { &hf_ac_if_input_controls,
2972 { "Controls", "usbaudio.ac_if_input.bmControls",
2973 FT_UINT16, BASE_HEX, NULL, 0x0, "bmControls", HFILL }},
2974 { &hf_ac_if_input_controls_copy,
2975 { "Copy Protect Control", "usbaudio.ac_if_input.bmControls.copy", FT_UINT16,
2976 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x0003, NULL, HFILL }},
2977 { &hf_ac_if_input_controls_connector,
2978 { "Connector Control", "usbaudio.ac_if_input.bmControls.connector", FT_UINT16,
2979 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x000C, NULL, HFILL }},
2980 { &hf_ac_if_input_controls_overload,
2981 { "Overload Control", "usbaudio.ac_if_input.bmControls.overload", FT_UINT16,
2982 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x0030, NULL, HFILL }},
2983 { &hf_ac_if_input_controls_cluster,
2984 { "Cluster Control", "usbaudio.ac_if_input.bmControls.cluster", FT_UINT16,
2985 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x00C0, NULL, HFILL }},
2986 { &hf_ac_if_input_controls_underflow,
2987 { "Underflow Control", "usbaudio.ac_if_input.bmControls.underflow", FT_UINT16,
2988 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x0300, NULL, HFILL }},
2989 { &hf_ac_if_input_controls_overflow,
2990 { "Overflow Control", "usbaudio.ac_if_input.bmControls.overflow", FT_UINT16,
2991 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x0C00, NULL, HFILL }},
2992 { &hf_ac_if_input_controls_rsv,
2993 { "Reserved", "usbaudio.ac_if_input.bmControls.rsv",
2994 FT_UINT16, BASE_HEX, NULL, 0xF000, "Must be zero", HFILL }},
2995 { &hf_ac_if_input_terminal,
2996 { "String descriptor index", "usbaudio.ac_if_input.iTerminal",
2997 FT_UINT8, BASE_DEC, NULL, 0x0, "iTerminal", HFILL }},
2998 { &hf_ac_if_output_terminalid,
2999 { "Terminal ID", "usbaudio.ac_if_output.bTerminalID",
3000 FT_UINT8, BASE_DEC, NULL, 0x0, "bTerminalID", HFILL }},
3001 { &hf_ac_if_output_terminaltype,
3002 { "Terminal Type", "usbaudio.ac_if_output.wTerminalType", FT_UINT16,
3003 BASE_HEX|BASE_EXT_STRING, &terminal_types_vals_ext, 0x00, "wTerminalType", HFILL }},
3004 { &hf_ac_if_output_assocterminal,
3005 { "Assoc Terminal", "usbaudio.ac_if_output.bAssocTerminal",
3006 FT_UINT8, BASE_DEC, NULL, 0x0, "bAssocTerminal", HFILL }},
3007 { &hf_ac_if_output_sourceid,
3008 { "Source ID", "usbaudio.ac_if_output.bSourceID",
3009 FT_UINT8, BASE_DEC, NULL, 0x0, "bSourceID", HFILL }},
3010 { &hf_ac_if_output_clk_sourceid,
3011 { "Connected Clock Entity", "usbaudio.ac_if_output.bCSourceID",
3012 FT_UINT8, BASE_DEC, NULL, 0x0, "bCSourceID", HFILL }},
3013 { &hf_ac_if_output_controls,
3014 { "Controls", "usbaudio.ac_if_output.bmControls",
3015 FT_UINT16, BASE_HEX, NULL, 0x0, "bmControls", HFILL }},
3016 { &hf_ac_if_output_controls_copy,
3017 { "Copy Protect Control", "usbaudio.ac_if_output.bmControls.copy", FT_UINT16,
3018 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x0003, NULL, HFILL }},
3019 { &hf_ac_if_output_controls_connector,
3020 { "Connector Control", "usbaudio.ac_if_output.bmControls.connector", FT_UINT16,
3021 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x000C, NULL, HFILL }},
3022 { &hf_ac_if_output_controls_overload,
3023 { "Overload Control", "usbaudio.ac_if_output.bmControls.overload", FT_UINT16,
3024 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x0030, NULL, HFILL }},
3025 { &hf_ac_if_output_controls_underflow,
3026 { "Underflow Control", "usbaudio.ac_if_output.bmControls.underflow", FT_UINT16,
3027 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x00C0, NULL, HFILL }},
3028 { &hf_ac_if_output_controls_overflow,
3029 { "Overflow Control", "usbaudio.ac_if_output.bmControls.overflow", FT_UINT16,
3030 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x0300, NULL, HFILL }},
3031 { &hf_ac_if_output_controls_rsv,
3032 { "Reserved", "usbaudio.ac_if_output.bmControls.rsv",
3033 FT_UINT16, BASE_HEX, NULL, 0xFC00, "Must be zero", HFILL }},
3034 { &hf_ac_if_output_terminal,
3035 { "String descriptor index", "usbaudio.ac_if_output.iTerminal",
3036 FT_UINT8, BASE_DEC, NULL, 0x0, "iTerminal", HFILL }},
3037 { &hf_ac_if_fu_unitid,
3038 { "Unit ID", "usbaudio.ac_if_fu.bUnitID",
3039 FT_UINT8, BASE_DEC, NULL, 0x0, "bUnitID", HFILL }},
3040 { &hf_ac_if_fu_sourceid,
3041 { "Source ID", "usbaudio.ac_if_fu.bSourceID",
3042 FT_UINT8, BASE_DEC, NULL, 0x0, "bSourceID", HFILL }},
3043 { &hf_ac_if_fu_controlsize,
3044 { "Control Size", "usbaudio.ac_if_fu.bControlSize",
3045 FT_UINT8, BASE_DEC, NULL, 0x0, "bControlSize", HFILL }},
3046 { &hf_ac_if_fu_controls,
3047 { "Controls", "usbaudio.ac_if_fu.bmaControls",
3048 FT_BYTES, BASE_NONE, NULL, 0x0, "bmaControls", HFILL }},
3049 { &hf_ac_if_fu_control,
3050 { "Control", "usbaudio.ac_if_fu.bmaControl",
3051 FT_UINT8, BASE_HEX, NULL, 0x0, "bmaControls", HFILL }},
3052 { &hf_ac_if_fu_controls_d0,
3053 { "Mute", "usbaudio.ac_if_fu.bmaControls.d0",
3054 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
3055 { &hf_ac_if_fu_controls_d1,
3056 { "Volume", "usbaudio.ac_if_fu.bmaControls.d1",
3057 FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
3058 { &hf_ac_if_fu_controls_d2,
3059 { "Bass", "usbaudio.ac_if_fu.bmaControls.d2",
3060 FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
3061 { &hf_ac_if_fu_controls_d3,
3062 { "Mid", "usbaudio.ac_if_fu.bmaControls.d3",
3063 FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
3064 { &hf_ac_if_fu_controls_d4,
3065 { "Treble", "usbaudio.ac_if_fu.bmaControls.d4",
3066 FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
3067 { &hf_ac_if_fu_controls_d5,
3068 { "Graphic Equalizer", "usbaudio.ac_if_fu.bmaControls.d5",
3069 FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }},
3070 { &hf_ac_if_fu_controls_d6,
3071 { "Automatic Gain", "usbaudio.ac_if_fu.bmaControls.d6",
3072 FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }},
3073 { &hf_ac_if_fu_controls_d7,
3074 { "Delay", "usbaudio.ac_if_fu.bmaControls.d7",
3075 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
3076 { &hf_ac_if_fu_controls_d8,
3077 { "Bass Boost", "usbaudio.ac_if_fu.bmaControls.d8",
3078 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
3079 { &hf_ac_if_fu_controls_d9,
3080 { "Loudness", "usbaudio.ac_if_fu.bmaControls.d9",
3081 FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
3082 { &hf_ac_if_fu_controls_rsv,
3083 { "Reserved", "usbaudio.ac_if_fu.bmaControls.rsv",
3084 FT_UINT8, BASE_HEX, NULL, 0xFC, "Must be zero", HFILL }},
3085 { &hf_ac_if_fu_controls_v2,
3086 { "Controls", "usbaudio.ac_if_fu.bmaControls_v2",
3087 FT_BYTES, BASE_NONE, NULL, 0x0, "bmaControls", HFILL }},
3088 { &hf_ac_if_fu_control_v2,
3089 { "Control", "usbaudio.ac_if_fu.bmaControl_v2",
3090 FT_UINT32, BASE_HEX, NULL, 0x0, "bmaControls", HFILL }},
3091 { &hf_ac_if_fu_controls_v2_d0,
3092 { "Mute", "usbaudio.ac_if_fu.bmaControls_v2.d0", FT_UINT32,
3093 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 0), NULL, HFILL }},
3094 { &hf_ac_if_fu_controls_v2_d1,
3095 { "Volume", "usbaudio.ac_if_fu.bmaControls_v2.d1", FT_UINT32,
3096 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 2), NULL, HFILL }},
3097 { &hf_ac_if_fu_controls_v2_d2,
3098 { "Bass", "usbaudio.ac_if_fu.bmaControls_v2.d2", FT_UINT32,
3099 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 4), NULL, HFILL }},
3100 { &hf_ac_if_fu_controls_v2_d3,
3101 { "Mid", "usbaudio.ac_if_fu.bmaControls_v2.d3", FT_UINT32,
3102 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 6), NULL, HFILL }},
3103 { &hf_ac_if_fu_controls_v2_d4,
3104 { "Treble", "usbaudio.ac_if_fu.bmaControls_v2.d4", FT_UINT32,
3105 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 8), NULL, HFILL }},
3106 { &hf_ac_if_fu_controls_v2_d5,
3107 { "Graphic Equalizer", "usbaudio.ac_if_fu.bmaControls_v2.d5", FT_UINT32,
3108 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 10), NULL, HFILL }},
3109 { &hf_ac_if_fu_controls_v2_d6,
3110 { "Automatic Gain", "usbaudio.ac_if_fu.bmaControls_v2.d6", FT_UINT32,
3111 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 12), NULL, HFILL }},
3112 { &hf_ac_if_fu_controls_v2_d7,
3113 { "Delay", "usbaudio.ac_if_fu.bmaControl_v2s.d7", FT_UINT32,
3114 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 14), NULL, HFILL }},
3115 { &hf_ac_if_fu_controls_v2_d8,
3116 { "Bass Boost", "usbaudio.ac_if_fu.bmaControls_v2.d8", FT_UINT32,
3117 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 16), NULL, HFILL }},
3118 { &hf_ac_if_fu_controls_v2_d9,
3119 { "Loudness", "usbaudio.ac_if_fu.bmaControls_v2.d9", FT_UINT32,
3120 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 18), NULL, HFILL }},
3121 { &hf_ac_if_fu_controls_v2_d10,
3122 { "Input Gain", "usbaudio.ac_if_fu.bmaControls_v2.d10", FT_UINT32,
3123 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 20), NULL, HFILL }},
3124 { &hf_ac_if_fu_controls_v2_d11,
3125 { "Input Gain Pad", "usbaudio.ac_if_fu.bmaControls_v2.d11", FT_UINT32,
3126 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 22), NULL, HFILL }},
3127 { &hf_ac_if_fu_controls_v2_d12,
3128 { "Phase Inverter", "usbaudio.ac_if_fu.bmaControls_v2.d12", FT_UINT32,
3129 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 24), NULL, HFILL }},
3130 { &hf_ac_if_fu_controls_v2_d13,
3131 { "Underflow", "usbaudio.ac_if_fu.bmaControls_v2.d13", FT_UINT32,
3132 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 26), NULL, HFILL }},
3133 { &hf_ac_if_fu_controls_v2_d14,
3134 { "Overflow", "usbaudio.ac_if_fu.bmaControls_v2.d14", FT_UINT32,
3135 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, (3u << 28), NULL, HFILL }},
3136 { &hf_ac_if_fu_controls_v2_rsv,
3137 { "Reserved", "usbaudio.ac_if_fu.bmaControls_v2.rsv", FT_UINT32,
3138 BASE_HEX, NULL, (3u << 30), "Must be zero", HFILL }},
3139 { &hf_ac_if_fu_ifeature,
3140 { "Feature", "usbaudio.ac_if_fu.iFeature",
3141 FT_UINT8, BASE_DEC, NULL, 0x0, "iFeature", HFILL }},
3142 { &hf_ac_if_su_unitid,
3143 { "Unit ID", "usbaudio.ac_if_su.bUnitID",
3144 FT_UINT8, BASE_DEC, NULL, 0x0, "bUnitID", HFILL }},
3145 { &hf_ac_if_su_nrinpins,
3146 { "Input Pins", "usbaudio.ac_if_su.bNrInPins",
3147 FT_UINT8, BASE_DEC, NULL, 0x0, "bNrInPins", HFILL }},
3148 { &hf_ac_if_su_sourceids,
3149 { "Source IDs", "usbaudio.ac_if_su.baSourceIDs",
3150 FT_BYTES, BASE_NONE, NULL, 0x0, "baSourceIDs", HFILL }},
3151 { &hf_ac_if_su_sourceid,
3152 { "Source ID", "usbaudio.ac_if_su.baSourceID",
3153 FT_UINT8, BASE_DEC, NULL, 0x0, "baSourceID", HFILL}},
3154 { &hf_ac_if_su_controls,
3155 { "Controls", "usbaudio.ac_if_su.bmControls",
3156 FT_UINT8, BASE_HEX, NULL, 0x0, "bmControls", HFILL}},
3157 { &hf_ac_if_su_controls_d0,
3158 { "Selector Control", "usbaudio.ac_if_su.bmControls.d0",
3159 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x03, NULL, HFILL}},
3160 { &hf_ac_if_su_controls_rsv,
3161 { "Reserved", "usbaudio.ac_if_su.bmControls.rsv",
3162 FT_UINT8, BASE_HEX, NULL, 0xFC, "Must be zero", HFILL}},
3163 { &hf_ac_if_su_iselector,
3164 { "Selector Index", "usbaudio.ac_if_su.iSelector",
3165 FT_UINT8, BASE_DEC, NULL, 0x0, "iSelector", HFILL }},
3166 { &hf_ac_if_mu_unitid,
3167 { "Unit ID", "usbaudio.ac_if_mu.bUnitID",
3168 FT_UINT8, BASE_DEC, NULL, 0x0, "bUnitID", HFILL }},
3169 { &hf_ac_if_mu_nrinpins,
3170 { "Number In Pins", "usbaudio.ac_if_mu.bNrInPins",
3171 FT_UINT8, BASE_DEC, NULL, 0x0, "bNrInPins", HFILL }},
3172 { &hf_ac_if_mu_sourceid,
3173 { "Source ID", "usbaudio.ac_if_mu.baSourceID",
3174 FT_UINT8, BASE_DEC, NULL, 0x0, "baSourceID", HFILL }},
3175 { &hf_ac_if_mu_nrchannels,
3176 { "Number Channels", "usbaudio.ac_if_mu.bNrChannels",
3177 FT_UINT8, BASE_DEC, NULL, 0x0, "bNrChannels", HFILL }},
3178 { &hf_ac_if_mu_channelconfig,
3179 { "Channel Config", "usbaudio.ac_if_mu.wChannelConfig",
3180 FT_UINT16, BASE_HEX, NULL, 0x0, "wChannelConfig", HFILL }},
3181 { &hf_ac_if_mu_channelconfig_d0,
3182 { "Left Front", "usbaudio.ac_if_mu.wChannelConfig.d0",
3183 FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL }},
3184 { &hf_ac_if_mu_channelconfig_d1,
3185 { "Right Front", "usbaudio.ac_if_mu.wChannelConfig.d1",
3186 FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL }},
3187 { &hf_ac_if_mu_channelconfig_d2,
3188 { "Center Front", "usbaudio.ac_if_mu.wChannelConfig.d2",
3189 FT_BOOLEAN, 16, NULL, 0x0004, NULL, HFILL }},
3190 { &hf_ac_if_mu_channelconfig_d3,
3191 { "Low Frequency Enhancement", "usbaudio.ac_if_mu.wChannelConfig.d3",
3192 FT_BOOLEAN, 16, NULL, 0x0008, NULL, HFILL }},
3193 { &hf_ac_if_mu_channelconfig_d4,
3194 { "Left Surround", "usbaudio.ac_if_mu.wChannelConfig.d4",
3195 FT_BOOLEAN, 16, NULL, 0x0010, NULL, HFILL }},
3196 { &hf_ac_if_mu_channelconfig_d5,
3197 { "Right Surround", "usbaudio.ac_if_mu.wChannelConfig.d5",
3198 FT_BOOLEAN, 16, NULL, 0x0020, NULL, HFILL }},
3199 { &hf_ac_if_mu_channelconfig_d6,
3200 { "Left of Center", "usbaudio.ac_if_mu.wChannelConfig.d6",
3201 FT_BOOLEAN, 16, NULL, 0x0040, NULL, HFILL }},
3202 { &hf_ac_if_mu_channelconfig_d7,
3203 { "Right of Center", "usbaudio.ac_if_mu.wChannelConfig.d7",
3204 FT_BOOLEAN, 16, NULL, 0x0080, NULL, HFILL }},
3205 { &hf_ac_if_mu_channelconfig_d8,
3206 { "Surround", "usbaudio.ac_if_mu.wChannelConfig.d8",
3207 FT_BOOLEAN, 16, NULL, 0x0100, NULL, HFILL }},
3208 { &hf_ac_if_mu_channelconfig_d9,
3209 { "Side Left", "usbaudio.ac_if_mu.wChannelConfig.d9",
3210 FT_BOOLEAN, 16, NULL, 0x0200, NULL, HFILL }},
3211 { &hf_ac_if_mu_channelconfig_d10,
3212 { "Side Right", "usbaudio.ac_if_mu.wChannelConfig.d10",
3213 FT_BOOLEAN, 16, NULL, 0x0400, NULL, HFILL }},
3214 { &hf_ac_if_mu_channelconfig_d11,
3215 { "Top", "usbaudio.ac_if_mu.wChannelConfig.d11",
3216 FT_BOOLEAN, 16, NULL, 0x0800, NULL, HFILL }},
3217 { &hf_ac_if_mu_channelconfig_rsv,
3218 { "Reserved", "usbaudio.ac_if_mu.wChannelConfig.rsv",
3219 FT_UINT16, BASE_HEX, NULL, 0xF000, NULL, HFILL }},
3220 { &hf_ac_if_mu_channelnames,
3221 { "Channel Names", "usbaudio.ac_if_mu.iChannelNames",
3222 FT_UINT8, BASE_DEC, NULL, 0x0, "iChannelNames", HFILL }},
3223 { &hf_ac_if_mu_controls,
3224 { "Controls", "usbaudio.ac_if_mu.bmControls",
3225 FT_UINT8, BASE_HEX, NULL, 0x0, "bmControls", HFILL }},
3226 { &hf_ac_if_mu_imixer,
3227 { "Mixer", "usbaudio.ac_if_mu.iMixer",
3228 FT_UINT8, BASE_DEC, NULL, 0x0, "iMixer", HFILL }},
3229 { &hf_ac_if_clksrc_id,
3230 { "Clock Source Entity", "usbaudio.ac_if_clksrc.bClockID",
3231 FT_UINT8, BASE_DEC, NULL, 0x0, "bClockID", HFILL }},
3232 { &hf_ac_if_clksrc_attr,
3233 { "Attributes", "usbaudio.ac_if_clksrc.bmAttributes",
3234 FT_UINT8, BASE_HEX, NULL, 0x0, "bmAttributes", HFILL }},
3235 { &hf_ac_if_clksrc_attr_type,
3236 { "Type", "usbaudio.ac_if_clksrc.bmAttributes.type", FT_UINT8,
3237 BASE_HEX, VALS(clock_types_vals), 0x03, NULL, HFILL }},
3238 { &hf_ac_if_clksrc_attr_d2,
3239 { "Synchronization", "usbaudio.ac_if_clksrc.bmAttributes.d2", FT_UINT8,
3240 BASE_HEX, VALS(clock_sync_vals), 0x04, NULL, HFILL }},
3241 { &hf_ac_if_clksrc_attr_rsv,
3242 { "Reserved", "usbaudio.ac_if_clksrc.bmAttributes.rsv",
3243 FT_UINT8, BASE_HEX, NULL, 0xF8, "Must be zero", HFILL }},
3244 { &hf_ac_if_clksrc_controls,
3245 { "Controls", "usbaudio.ac_if_clksrc.bmControls",
3246 FT_UINT8, BASE_HEX, NULL, 0x0, "bmControls", HFILL }},
3247 { &hf_ac_if_clksrc_controls_freq,
3248 { "Clock Frequency Control", "usbaudio.ac_if_clksrc.bmControls.freq", FT_UINT8,
3249 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x03, NULL, HFILL }},
3250 { &hf_ac_if_clksrc_controls_validity,
3251 { "Clock Validity Control", "usbaudio.ac_if_clksrc.bmControls.validity", FT_UINT8,
3252 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x0C, NULL, HFILL }},
3253 { &hf_ac_if_clksrc_controls_rsv,
3254 { "Reserved", "usbaudio.ac_if_clksrc.bmControls.rsv",
3255 FT_UINT8, BASE_HEX, NULL, 0xF0, "Must be zero", HFILL }},
3256 { &hf_ac_if_clksrc_assocterminal,
3257 { "Terminal", "usbaudio.ac_if_clksrc.bAssocTerminal",
3258 FT_UINT8, BASE_DEC, NULL, 0x0, "bAssocTerminal", HFILL }},
3259 { &hf_ac_if_clksrc_clocksource,
3260 { "String descriptor index", "usbaudio.ac_if_clksrc.iClockSource",
3261 FT_UINT8, BASE_DEC, NULL, 0x0, "iClockSource", HFILL }},
3262 { &hf_ac_if_clksel_id,
3263 { "Clock Selector Entity", "usbaudio.ac_if_clksel.bClockID",
3264 FT_UINT8, BASE_DEC, NULL, 0x0, "bClockID", HFILL }},
3265 { &hf_ac_if_clksel_nrpins,
3266 { "Number of Input Pins", "usbaudio.ac_if_clksel.bNrInPins",
3267 FT_UINT8, BASE_DEC, NULL, 0x0, "bNrInPins", HFILL }},
3268 { &hf_ac_if_clksel_sourceid,
3269 { "Connected Clock Entity", "usbaudio.ac_if_clksel.baCSourceID",
3270 FT_UINT8, BASE_DEC, NULL, 0x0, "baCSourceID", HFILL }},
3271 { &hf_ac_if_clksel_controls,
3272 { "Controls", "usbaudio.ac_if_clksel.bmControls",
3273 FT_UINT8, BASE_HEX, NULL, 0x0, "bmControls", HFILL }},
3274 { &hf_ac_if_clksel_controls_clksel,
3275 { "Clock Selector Control", "usbaudio.ac_if_clksel.bmControls.clksel", FT_UINT8,
3276 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_vals_ext, 0x03, NULL, HFILL }},
3277 { &hf_ac_if_clksel_controls_rsv,
3278 { "Reserved", "usbaudio.ac_if_clksel.bmControls.rsv",
3279 FT_UINT8, BASE_HEX, NULL, 0xFC, "Must be zero", HFILL }},
3280 { &hf_ac_if_clksel_clockselector,
3281 { "String descriptor index", "usbaudio.ac_if_clksel.iClockSelector",
3282 FT_UINT8, BASE_DEC, NULL, 0x0, "iClockSelector", HFILL }},
3284 { &hf_ac_if_extunit_id,
3285 { "Extension Unit", "usbaudio.ac_if_extunit.bUnitID",
3286 FT_UINT8, BASE_DEC, NULL, 0x0, "bUnitID", HFILL }},
3287 { &hf_ac_if_extunit_code,
3288 { "Extension Code", "usbaudio.ac_if_extunit.wExtensionCode", FT_UINT16,
3289 BASE_HEX, NULL, 0x00, "wExtensionCode", HFILL }},
3290 { &hf_ac_if_extunit_nrpins,
3291 {"Number of Input Pins", "usbaudio.ac_if_extunit.bNrInPins",
3292 FT_UINT8, BASE_DEC, NULL, 0x0, "bNrInPins", HFILL }},
3293 { &hf_ac_if_extunit_sourceid,
3294 {"Unit or Terminal Entity", "usbaudio.ac_if_extunit.baSourceID",
3295 FT_UINT8, BASE_DEC, NULL, 0x0, "baSourceID", HFILL }},
3296 { &hf_ac_if_extunit_nrchannels,
3297 {"Number Channels", "usbaudio.ac_if_extunit.bNrChannels",
3298 FT_UINT8, BASE_DEC, NULL, 0x0, "bNrChannels", HFILL }},
3299 { &hf_ac_if_extunit_bmchannelconfig,
3300 {"Channel Config", "usbaudio.ac_if_extunit.bmChannelConfig",
3301 FT_UINT32, BASE_HEX, NULL, 0x0, "bmChannelConfig", HFILL }},
3302 // TODO: add channel config vars
3303 { &hf_ac_if_extunit_channelnames,
3304 {"Channel Names", "usbaudio.ac_if_extunit.iChannelNames",
3305 FT_UINT8, BASE_DEC, NULL, 0x0, "iChannelNames", HFILL }},
3306 { &hf_ac_if_extunit_bmcontrols,
3307 {"Controls", "usbaudio.ac_if_extunit.bmControls",
3308 FT_UINT8, BASE_HEX, NULL, 0x0, "bmControls", HFILL }},
3309 { &hf_ac_if_extunit_bmcontrols_enable_ctrl,
3310 {"Enable Control", "usbaudio.ac_if_extunit.bmControls.enableCtrl",
3311 FT_UINT8, BASE_HEX, NULL, 0x03, NULL, HFILL }},
3312 { &hf_ac_if_extunit_bmcontrols_cluster_ctrl,
3313 {"Cluster Control", "usbaudio.ac_if_extunit.bmControls.clusterCtrl",
3314 FT_UINT8, BASE_HEX, NULL, 0x0C, NULL, HFILL }},
3315 { &hf_ac_if_extunit_bmcontrols_underflow_ctrl,
3316 {"Underflow Control", "usbaudio.ac_if_extunit.bmControls.underflowCtrl",
3317 FT_UINT8, BASE_HEX, NULL, 0x30, NULL, HFILL }},
3318 { &hf_ac_if_extunit_bmcontrols_overflowflow_ctrl,
3319 {"Overflow Control", "usbaudio.ac_if_extunit.bmControls.overflowCtrl",
3320 FT_UINT8, BASE_HEX, NULL, 0xC0, NULL, HFILL }},
3321 { &hf_ac_if_extunit_iext,
3322 {"Extension", "usbaudio.ac_if_extunit.iExtension",
3323 FT_UINT8, BASE_DEC, NULL, 0x0, "iExtension", HFILL }},
3325 { &hf_as_if_desc_subtype,
3326 { "Subtype", "usbaudio.as_if_subtype", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
3327 &as_subtype_vals_ext, 0x0, "bDescriptorSubtype", HFILL }},
3328 { &hf_as_if_gen_term_link,
3329 { "Connected Terminal ID", "usbaudio.as_if_gen.bTerminalLink",
3330 FT_UINT8, BASE_DEC, NULL, 0x0, "bTerminalLink", HFILL }},
3331 { &hf_as_if_gen_delay,
3332 { "Interface delay in frames", "usbaudio.as_if_gen.bDelay",
3333 FT_UINT8, BASE_DEC, NULL, 0x0, "bDelay", HFILL }},
3334 { &hf_as_if_gen_wformattag,
3335 { "Format", "usbaudio.as_if_gen.wFormatTag", FT_UINT16, BASE_HEX|BASE_EXT_STRING,
3336 &audio_data_format_tag_vals_ext, 0x0, "wFormatTag", HFILL }},
3337 { &hf_as_if_gen_controls,
3338 { "Controls", "usbaudio.as_if_gen.bmControls",
3339 FT_UINT8, BASE_HEX, NULL, 0x0, "bmControls", HFILL }},
3340 { &hf_as_if_gen_controls_active,
3341 { "Active Alternate Setting Control", "usbaudio.as_if_gen.bmControls.active", FT_UINT8,
3342 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_read_only_vals_ext, 0x03, NULL, HFILL }},
3343 { &hf_as_if_gen_controls_valid,
3344 { "Valid Alternate Settings Control", "usbaudio.as_if_gen.bmControls.valid", FT_UINT8,
3345 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_read_only_vals_ext, 0x0C, NULL, HFILL }},
3346 { &hf_as_if_gen_controls_rsv,
3347 { "Reserved", "usbaudio.as_if_gen.bmControls.rsv",
3348 FT_UINT8, BASE_HEX, NULL, 0xF0, "Must be zero", HFILL }},
3349 { &hf_as_if_gen_formattype,
3350 { "Format Type", "usbaudio.as_if_gen.bFormatType",
3351 FT_UINT8, BASE_DEC, NULL, 0x0, "bFormatType", HFILL }},
3352 { &hf_as_if_gen_formats,
3353 { "Formats", "usbaudio.as_if_gen.bmFormats",
3354 FT_UINT32, BASE_HEX, NULL, 0x0, "bmFormats", HFILL }},
3356 { &hf_as_if_gen_formats_i_d0,
3357 { "PCM", "usbaudio.as_if_gen.bmFormats.d0",
3358 FT_BOOLEAN, 32, NULL, (1u << 0), NULL, HFILL }},
3359 { &hf_as_if_gen_formats_i_d1,
3360 { "PCM8", "usbaudio.as_if_gen.bmFormats.d1",
3361 FT_BOOLEAN, 32, NULL, (1u << 1), NULL, HFILL }},
3362 { &hf_as_if_gen_formats_i_d2,
3363 { "IEEE Float", "usbaudio.as_if_gen.bmFormats.d2",
3364 FT_BOOLEAN, 32, NULL, (1u << 2), NULL, HFILL }},
3365 { &hf_as_if_gen_formats_i_d3,
3366 { "ALAW", "usbaudio.as_if_gen.bmFormats.d3",
3367 FT_BOOLEAN, 32, NULL, (1u << 3), NULL, HFILL }},
3368 { &hf_as_if_gen_formats_i_d4,
3369 { "MULAW", "usbaudio.as_if_gen.bmFormats.d4",
3370 FT_BOOLEAN, 32, NULL, (1u << 4), NULL, HFILL }},
3371 { &hf_as_if_gen_formats_i_rsv,
3372 { "Reserved", "usbaudio.as_if_gen.bmFormats.rsv",
3373 FT_UINT32, BASE_HEX, NULL, (0x7FFFFFE0u), "Must be zero", HFILL }},
3374 { &hf_as_if_gen_formats_i_d31,
3375 { "Type I Raw Data", "usbaudio.as_if_gen.bmFormats.d31",
3376 FT_BOOLEAN, 32, NULL, (1u << 31), NULL, HFILL }},
3378 { &hf_as_if_gen_formats_ii_d0,
3379 { "MPEG", "usbaudio.as_if_gen.bmFormats.d0",
3380 FT_BOOLEAN, 32, NULL, (1u << 0), NULL, HFILL }},
3381 { &hf_as_if_gen_formats_ii_d1,
3382 { "AC-3", "usbaudio.as_if_gen.bmFormats.d1",
3383 FT_BOOLEAN, 32, NULL, (1u << 1), NULL, HFILL }},
3384 { &hf_as_if_gen_formats_ii_d2,
3385 { "WMA", "usbaudio.as_if_gen.bmFormats.d2",
3386 FT_BOOLEAN, 32, NULL, (1u << 2), NULL, HFILL }},
3387 { &hf_as_if_gen_formats_ii_d3,
3388 { "DTS", "usbaudio.as_if_gen.bmFormats.d3",
3389 FT_BOOLEAN, 32, NULL, (1u << 3), NULL, HFILL }},
3390 { &hf_as_if_gen_formats_ii_rsv,
3391 { "Reserved", "usbaudio.as_if_gen.bmFormats.rsv",
3392 FT_UINT32, BASE_HEX, NULL, (0x7FFFFFF0u), "Must be zero", HFILL }},
3393 { &hf_as_if_gen_formats_ii_d31,
3394 { "Type II Raw Data", "usbaudio.as_if_gen.bmFormats.d31",
3395 FT_BOOLEAN, 32, NULL, (1u << 31), NULL, HFILL }},
3397 { &hf_as_if_gen_formats_iii_d0,
3398 { "IEC61937 AC-3", "usbaudio.as_if_gen.bmFormats.d0",
3399 FT_BOOLEAN, 32, NULL, (1u << 0), NULL, HFILL }},
3400 { &hf_as_if_gen_formats_iii_d1,
3401 { "IEC61937 MPEG-1 Layer1", "usbaudio.as_if_gen.bmFormats.d1",
3402 FT_BOOLEAN, 32, NULL, (1u << 1), NULL, HFILL }},
3403 { &hf_as_if_gen_formats_iii_d2,
3404 { "IEC61937 MPEG-1 Layer2/3 or IEC61937 MPEG-2 NOEXT", "usbaudio.as_if_gen.bmFormats.d2",
3405 FT_BOOLEAN, 32, NULL, (1u << 2), NULL, HFILL }},
3406 { &hf_as_if_gen_formats_iii_d3,
3407 { "IEC61937 MPEG-2 EXT", "usbaudio.as_if_gen.bmFormats.d3",
3408 FT_BOOLEAN, 32, NULL, (1u << 3), NULL, HFILL }},
3409 { &hf_as_if_gen_formats_iii_d4,
3410 { "IEC61937 MPEG-2 AAC ADTS", "usbaudio.as_if_gen.bmFormats.d4",
3411 FT_BOOLEAN, 32, NULL, (1u << 4), NULL, HFILL }},
3412 { &hf_as_if_gen_formats_iii_d5,
3413 { "IEC61937 MPEG-2 Layer1 LS", "usbaudio.as_if_gen.bmFormats.d5",
3414 FT_BOOLEAN, 32, NULL, (1u << 5), NULL, HFILL }},
3415 { &hf_as_if_gen_formats_iii_d6,
3416 { "IEC61937 MPEG-2 Layer2/3 LS", "usbaudio.as_if_gen.bmFormats.d6",
3417 FT_BOOLEAN, 32, NULL, (1u << 6), NULL, HFILL }},
3418 { &hf_as_if_gen_formats_iii_d7,
3419 { "IEC61937 DTS-I", "usbaudio.as_if_gen.bmFormats.d7",
3420 FT_BOOLEAN, 32, NULL, (1u << 7), NULL, HFILL }},
3421 { &hf_as_if_gen_formats_iii_d8,
3422 { "IEC61937 DTS-II", "usbaudio.as_if_gen.bmFormats.d8",
3423 FT_BOOLEAN, 32, NULL, (1u << 8), NULL, HFILL }},
3424 { &hf_as_if_gen_formats_iii_d9,
3425 { "IEC61937 DTS-III", "usbaudio.as_if_gen.bmFormats.d9",
3426 FT_BOOLEAN, 32, NULL, (1u << 9), NULL, HFILL }},
3427 { &hf_as_if_gen_formats_iii_d10,
3428 { "IEC61937 ATRAC", "usbaudio.as_if_gen.bmFormats.d10",
3429 FT_BOOLEAN, 32, NULL, (1u << 10), NULL, HFILL }},
3430 { &hf_as_if_gen_formats_iii_d11,
3431 { "IEC61937 ATRAC2/3", "usbaudio.as_if_gen.bmFormats.d11",
3432 FT_BOOLEAN, 32, NULL, (1u << 11), NULL, HFILL }},
3433 { &hf_as_if_gen_formats_iii_d12,
3434 { "Type III WMA", "usbaudio.as_if_gen.bmFormats.d12",
3435 FT_BOOLEAN, 32, NULL, (1u << 12), NULL, HFILL }},
3436 { &hf_as_if_gen_formats_iii_rsv,
3437 { "Reserved", "usbaudio.as_if_gen.bmFormats.rsv",
3438 FT_UINT32, BASE_HEX, NULL, (0xFFFFE000u), "Must be zero", HFILL }},
3440 { &hf_as_if_gen_formats_iv_d0,
3441 { "PCM", "usbaudio.as_if_gen.bmFormats.d0",
3442 FT_BOOLEAN, 32, NULL, (1u << 0), NULL, HFILL }},
3443 { &hf_as_if_gen_formats_iv_d1,
3444 { "PCM8", "usbaudio.as_if_gen.bmFormats.d1",
3445 FT_BOOLEAN, 32, NULL, (1u << 1), NULL, HFILL }},
3446 { &hf_as_if_gen_formats_iv_d2,
3447 { "IEEE Float", "usbaudio.as_if_gen.bmFormats.d2",
3448 FT_BOOLEAN, 32, NULL, (1u << 2), NULL, HFILL }},
3449 { &hf_as_if_gen_formats_iv_d3,
3450 { "ALAW", "usbaudio.as_if_gen.bmFormats.d3",
3451 FT_BOOLEAN, 32, NULL, (1u << 3), NULL, HFILL }},
3452 { &hf_as_if_gen_formats_iv_d4,
3453 { "MULAW", "usbaudio.as_if_gen.bmFormats.d4",
3454 FT_BOOLEAN, 32, NULL, (1u << 4), NULL, HFILL }},
3455 { &hf_as_if_gen_formats_iv_d5,
3456 { "MPEG", "usbaudio.as_if_gen.bmFormats.d5",
3457 FT_BOOLEAN, 32, NULL, (1u << 5), NULL, HFILL }},
3458 { &hf_as_if_gen_formats_iv_d6,
3459 { "AC-3", "usbaudio.as_if_gen.bmFormats.d6",
3460 FT_BOOLEAN, 32, NULL, (1u << 6), NULL, HFILL }},
3461 { &hf_as_if_gen_formats_iv_d7,
3462 { "WMA", "usbaudio.as_if_gen.bmFormats.d7",
3463 FT_BOOLEAN, 32, NULL, (1u << 7), NULL, HFILL }},
3464 { &hf_as_if_gen_formats_iv_d8,
3465 { "IEC61937 AC-3", "usbaudio.as_if_gen.bmFormats.d8",
3466 FT_BOOLEAN, 32, NULL, (1u << 8), NULL, HFILL }},
3467 { &hf_as_if_gen_formats_iv_d9,
3468 { "IEC61937 MPEG-1 Layer1", "usbaudio.as_if_gen.bmFormats.d9",
3469 FT_BOOLEAN, 32, NULL, (1u << 9), NULL, HFILL }},
3470 { &hf_as_if_gen_formats_iv_d10,
3471 { "IEC61937 MPEG-1 Layer2/3 or IEC61937 MPEG-2 NOEXT", "usbaudio.as_if_gen.bmFormats.d10",
3472 FT_BOOLEAN, 32, NULL, (1u << 10), NULL, HFILL }},
3473 { &hf_as_if_gen_formats_iv_d11,
3474 { "IEC61937 MPEG-2 EXT", "usbaudio.as_if_gen.bmFormats.d11",
3475 FT_BOOLEAN, 32, NULL, (1u << 11), NULL, HFILL }},
3476 { &hf_as_if_gen_formats_iv_d12,
3477 { "IEC61937 MPEG-2 AAC ADTS", "usbaudio.as_if_gen.bmFormats.d12",
3478 FT_BOOLEAN, 32, NULL, (1u << 12), NULL, HFILL }},
3479 { &hf_as_if_gen_formats_iv_d13,
3480 { "IEC61937 MPEG-2 Layer1 LS", "usbaudio.as_if_gen.bmFormats.d13",
3481 FT_BOOLEAN, 32, NULL, (1u << 13), NULL, HFILL }},
3482 { &hf_as_if_gen_formats_iv_d14,
3483 { "IEC61937 MPEG-2 Layer2/3 LS", "usbaudio.as_if_gen.bmFormats.d14",
3484 FT_BOOLEAN, 32, NULL, (1u << 14), NULL, HFILL }},
3485 { &hf_as_if_gen_formats_iv_d15,
3486 { "IEC61937 DTS-I", "usbaudio.as_if_gen.bmFormats.d15",
3487 FT_BOOLEAN, 32, NULL, (1u << 15), NULL, HFILL }},
3488 { &hf_as_if_gen_formats_iv_d16,
3489 { "IEC61937 DTS-II", "usbaudio.as_if_gen.bmFormats.d16",
3490 FT_BOOLEAN, 32, NULL, (1u << 16), NULL, HFILL }},
3491 { &hf_as_if_gen_formats_iv_d17,
3492 { "IEC61937 DTS-III", "usbaudio.as_if_gen.bmFormats.d17",
3493 FT_BOOLEAN, 32, NULL, (1u << 17), NULL, HFILL }},
3494 { &hf_as_if_gen_formats_iv_d18,
3495 { "IEC61937 ATRAC", "usbaudio.as_if_gen.bmFormats.d18",
3496 FT_BOOLEAN, 32, NULL, (1u << 18), NULL, HFILL }},
3497 { &hf_as_if_gen_formats_iv_d19,
3498 { "IEC61937 ATRAC2/3", "usbaudio.as_if_gen.bmFormats.d19",
3499 FT_BOOLEAN, 32, NULL, (1u << 19), NULL, HFILL }},
3500 { &hf_as_if_gen_formats_iv_d20,
3501 { "Type III WMA", "usbaudio.as_if_gen.bmFormats.d20",
3502 FT_BOOLEAN, 32, NULL, (1u << 20), NULL, HFILL }},
3503 { &hf_as_if_gen_formats_iv_d21,
3504 { "IEC60958 PCM", "usbaudio.as_if_gen.bmFormats.d21",
3505 FT_BOOLEAN, 32, NULL, (1u << 21), NULL, HFILL }},
3506 { &hf_as_if_gen_formats_iv_rsv,
3507 { "Reserved", "usbaudio.as_if_gen.bmFormats.rsv",
3508 FT_UINT32, BASE_HEX, NULL, (0xFFE00000u), "Must be zero", HFILL }},
3510 { &hf_as_if_gen_nrchannels,
3511 { "Number of channels", "usbaudio.as_if_gen.bNrChannels",
3512 FT_UINT8, BASE_DEC, NULL, 0x00, "bNrChannels", HFILL }},
3513 { &hf_as_if_gen_bmchannelconfig,
3514 { "Channel Config", "usbaudio.as_if_gen.bmChannelConfig",
3515 FT_UINT32, BASE_HEX, NULL, 0x0, "bmChannelConfig", HFILL }},
3516 { &hf_as_if_gen_bmchannelconfig_d0,
3517 { "Front Left", "usbaudio.as_if_gen.bmChannelConfig.d0",
3518 FT_BOOLEAN, 32, NULL, (1u << 0), NULL, HFILL }},
3519 { &hf_as_if_gen_bmchannelconfig_d1,
3520 { "Front Right", "usbaudio.as_if_gen.bmChannelConfig.d1",
3521 FT_BOOLEAN, 32, NULL, (1u << 1), NULL, HFILL }},
3522 { &hf_as_if_gen_bmchannelconfig_d2,
3523 { "Front Center", "usbaudio.as_if_gen.bmChannelConfig.d2",
3524 FT_BOOLEAN, 32, NULL, (1u << 2), NULL, HFILL }},
3525 { &hf_as_if_gen_bmchannelconfig_d3,
3526 { "Low Frequency Effects", "usbaudio.as_if_gen.bmChannelConfig.d3",
3527 FT_BOOLEAN, 32, NULL, (1u << 3), NULL, HFILL }},
3528 { &hf_as_if_gen_bmchannelconfig_d4,
3529 { "Back Left", "usbaudio.as_if_gen.bmChannelConfig.d4",
3530 FT_BOOLEAN, 32, NULL, (1u << 4), NULL, HFILL }},
3531 { &hf_as_if_gen_bmchannelconfig_d5,
3532 { "Back Right", "usbaudio.as_if_gen.bmChannelConfig.d5",
3533 FT_BOOLEAN, 32, NULL, (1u << 5), NULL, HFILL }},
3534 { &hf_as_if_gen_bmchannelconfig_d6,
3535 { "Front Left of Center", "usbaudio.as_if_gen.bmChannelConfig.d6",
3536 FT_BOOLEAN, 32, NULL, (1u << 6), NULL, HFILL }},
3537 { &hf_as_if_gen_bmchannelconfig_d7,
3538 { "Front Right of Center", "usbaudio.as_if_gen.bmChannelConfig.d7",
3539 FT_BOOLEAN, 32, NULL, (1u << 7), NULL, HFILL }},
3540 { &hf_as_if_gen_bmchannelconfig_d8,
3541 { "Back Center", "usbaudio.as_if_gen.bmChannelConfig.d8",
3542 FT_BOOLEAN, 32, NULL, (1u << 8), NULL, HFILL }},
3543 { &hf_as_if_gen_bmchannelconfig_d9,
3544 { "Side Left", "usbaudio.as_if_gen.bmChannelConfig.d9",
3545 FT_BOOLEAN, 32, NULL, (1u << 9), NULL, HFILL }},
3546 { &hf_as_if_gen_bmchannelconfig_d10,
3547 { "Side Right", "usbaudio.as_if_gen.bmChannelConfig.d10",
3548 FT_BOOLEAN, 32, NULL, (1u << 10), NULL, HFILL }},
3549 { &hf_as_if_gen_bmchannelconfig_d11,
3550 { "Top Center", "usbaudio.as_if_gen.bmChannelConfig.d11",
3551 FT_BOOLEAN, 32, NULL, (1u << 11), NULL, HFILL }},
3552 { &hf_as_if_gen_bmchannelconfig_d12,
3553 { "Top Front Left", "usbaudio.as_if_gen.bmChannelConfig.d12",
3554 FT_BOOLEAN, 32, NULL, (1u << 12), NULL, HFILL }},
3555 { &hf_as_if_gen_bmchannelconfig_d13,
3556 { "Top Front Center", "usbaudio.as_if_gen.bmChannelConfig.d13",
3557 FT_BOOLEAN, 32, NULL, (1u << 13), NULL, HFILL }},
3558 { &hf_as_if_gen_bmchannelconfig_d14,
3559 { "Top Front Right", "usbaudio.as_if_gen.bmChannelConfig.d14",
3560 FT_BOOLEAN, 32, NULL, (1u << 14), NULL, HFILL }},
3561 { &hf_as_if_gen_bmchannelconfig_d15,
3562 { "Top Back Left", "usbaudio.as_if_gen.bmChannelConfig.d15",
3563 FT_BOOLEAN, 32, NULL, (1u << 15), NULL, HFILL }},
3564 { &hf_as_if_gen_bmchannelconfig_d16,
3565 { "Top Back Center", "usbaudio.as_if_gen.bmChannelConfig.d16",
3566 FT_BOOLEAN, 32, NULL, (1u << 16), NULL, HFILL }},
3567 { &hf_as_if_gen_bmchannelconfig_d17,
3568 { "Top Back Right", "usbaudio.as_if_gen.bmChannelConfig.d17",
3569 FT_BOOLEAN, 32, NULL, (1u << 17), NULL, HFILL }},
3570 { &hf_as_if_gen_bmchannelconfig_d18,
3571 { "Top Front Left of Center", "usbaudio.as_if_gen.bmChannelConfig.d18",
3572 FT_BOOLEAN, 32, NULL, (1u << 18), NULL, HFILL }},
3573 { &hf_as_if_gen_bmchannelconfig_d19,
3574 { "Top Front Right of Center", "usbaudio.as_if_gen.bmChannelConfig.d19",
3575 FT_BOOLEAN, 32, NULL, (1u << 19), NULL, HFILL }},
3576 { &hf_as_if_gen_bmchannelconfig_d20,
3577 { "Left Low Frequency Effects", "usbaudio.as_if_gen.bmChannelConfig.d20",
3578 FT_BOOLEAN, 32, NULL, (1u << 20), NULL, HFILL }},
3579 { &hf_as_if_gen_bmchannelconfig_d21,
3580 { "Right Low Frequency Effects", "usbaudio.as_if_gen.bmChannelConfig.d21",
3581 FT_BOOLEAN, 32, NULL, (1u << 21), NULL, HFILL }},
3582 { &hf_as_if_gen_bmchannelconfig_d22,
3583 { "Top Side Left", "usbaudio.as_if_gen.bmChannelConfig.d22",
3584 FT_BOOLEAN, 32, NULL, (1u << 22), NULL, HFILL }},
3585 { &hf_as_if_gen_bmchannelconfig_d23,
3586 { "Top Side Right", "usbaudio.as_if_gen.bmChannelConfig.d23",
3587 FT_BOOLEAN, 32, NULL, (1u << 23), NULL, HFILL }},
3588 { &hf_as_if_gen_bmchannelconfig_d24,
3589 { "Bottom Center", "usbaudio.as_if_gen.bmChannelConfig.d24",
3590 FT_BOOLEAN, 32, NULL, (1u << 24), NULL, HFILL }},
3591 { &hf_as_if_gen_bmchannelconfig_d25,
3592 { "Back Left of Center", "usbaudio.as_if_gen.bmChannelConfig.d25",
3593 FT_BOOLEAN, 32, NULL, (1u << 25), NULL, HFILL }},
3594 { &hf_as_if_gen_bmchannelconfig_d26,
3595 { "Back Right of Center", "usbaudio.as_if_gen.bmChannelConfig.d26",
3596 FT_BOOLEAN, 32, NULL, (1u << 26), NULL, HFILL }},
3597 { &hf_as_if_gen_bmchannelconfig_rsv,
3598 { "Reserved", "usbaudio.as_if_gen.bmChannelConfig.rsv",
3599 FT_BOOLEAN, 32, NULL, (0xFu << 27), NULL, HFILL }},
3600 { &hf_as_if_gen_bmchannelconfig_d31,
3601 { "Raw Data", "usbaudio.as_if_gen.bmChannelConfig.d31",
3602 FT_BOOLEAN, 32, NULL, (1u << 31), NULL, HFILL }},
3603 { &hf_as_if_gen_channelnames,
3604 { "String descriptor index", "usbaudio.as_if_gen.iChannelNames",
3605 FT_UINT8, BASE_DEC, NULL, 0x00, "iChannelNames", HFILL }},
3607 { &hf_as_if_ft_formattype,
3608 { "FormatType", "usbaudio.as_if_ft.bFormatType",
3609 FT_UINT8, BASE_DEC, NULL, 0x00, "wFormatType", HFILL }},
3610 { &hf_as_if_ft_maxbitrate,
3611 { "Max Bit Rate", "usbaudio.as_if_ft.wMaxBitRate",
3612 FT_UINT16, BASE_DEC, NULL, 0x00, "wMaxBitRate", HFILL }},
3613 { &hf_as_if_ft_nrchannels,
3614 { "Number Channels", "usbaudio.as_if_ft.bNrChannels",
3615 FT_UINT8, BASE_DEC, NULL, 0x00, "bNrChannels", HFILL }},
3616 { &hf_as_if_ft_subframesize,
3617 { "Subframe Size", "usbaudio.as_if_ft.bSubframeSize",
3618 FT_UINT8, BASE_DEC, NULL, 0x00, "bSubframeSize", HFILL }},
3619 { &hf_as_if_ft_subslotsize,
3620 { "Subslot Size", "usbaudio.as_if_ft.bSubslotSize",
3621 FT_UINT8, BASE_DEC, NULL, 0x00, "bSubslotSize", HFILL }},
3622 { &hf_as_if_ft_bitresolution,
3623 { "Bit Resolution", "usbaudio.as_if_ft.bBitResolution",
3624 FT_UINT8, BASE_DEC, NULL, 0x00, "bBitResolution", HFILL }},
3625 { &hf_as_if_ft_samplesperframe,
3626 { "Samples Per Frame", "usbaudio.as_if_ft.wSamplesPerFrame",
3627 FT_UINT16, BASE_DEC, NULL, 0x00, "wSamplesPerFrame", HFILL }},
3628 { &hf_as_if_ft_samfreqtype,
3629 { "Samples Frequence Type", "usbaudio.as_if_ft.bSamFreqType",
3630 FT_UINT8, BASE_DEC, NULL, 0x00, "bSamFreqType", HFILL }},
3631 { &hf_as_if_ft_lowersamfreq,
3632 { "Lower Samples Frequence", "usbaudio.as_if_ft.tLowerSamFreq",
3633 FT_UINT24, BASE_DEC, NULL, 0x00, "tLowerSamFreq", HFILL }},
3634 { &hf_as_if_ft_uppersamfreq,
3635 { "Upper Samples Frequence", "usbaudio.as_if_ft.tUpperSamFreq",
3636 FT_UINT24, BASE_DEC, NULL, 0x00, "tUpperSamFreq", HFILL }},
3637 { &hf_as_if_ft_samfreq,
3638 { "Samples Frequence", "usbaudio.as_if_ft.tSamFreq",
3639 FT_UINT24, BASE_DEC, NULL, 0x00, "tSamFreq", HFILL }},
3640 { &hf_as_ep_desc_subtype,
3641 { "Subtype", "usbaudio.as_ep_subtype", FT_UINT8,
3642 BASE_HEX, VALS(as_ep_subtype_vals), 0x00, "bDescriptorSubtype", HFILL }},
3643 { &hf_as_ep_gen_bmattributes,
3644 { "Attributes", "usbaudio.as_ep_gen.bmAttributes", FT_UINT8,
3645 BASE_HEX, NULL, 0x00, "bmAttributes", HFILL }},
3646 { &hf_as_ep_gen_bmattributes_d0,
3647 { "Sampling Frequency Control", "usbaudio.as_ep_gen.bmAttributes.d0", FT_BOOLEAN,
3648 8, NULL, (1u << 0), NULL, HFILL }},
3649 { &hf_as_ep_gen_bmattributes_d1,
3650 { "Pitch Control", "usbaudio.as_ep_gen.bmAttributes.d1", FT_BOOLEAN,
3651 8, NULL, (1u << 1), NULL, HFILL }},
3652 { &hf_as_ep_gen_bmattributes_rsv,
3653 { "Reserved", "usbaudio.as_ep_gen.bmAttributes.rsv", FT_UINT8,
3654 BASE_HEX, NULL, 0x7C, NULL, HFILL }},
3655 { &hf_as_ep_gen_bmattributes_d7,
3656 { "MaxPacketsOnly", "usbaudio.as_ep_gen.bmAttributes.d7", FT_BOOLEAN,
3657 8, NULL, (1u << 7), NULL, HFILL }},
3658 { &hf_as_ep_gen_controls,
3659 { "Controls", "usbaudio.as_ep_gen.bmControls",
3660 FT_UINT8, BASE_HEX, NULL, 0x00, "bmControls", HFILL }},
3661 { &hf_as_ep_gen_controls_pitch,
3662 { "Pitch Control", "usbaudio.as_ep_gen.bmControls.pitch", FT_UINT8,
3663 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_read_only_vals_ext, 0x03, NULL, HFILL }},
3664 { &hf_as_ep_gen_controls_data_overrun,
3665 { "Data Overrun Control", "usbaudio.as_ep_gen.bmControls.overrun", FT_UINT8,
3666 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_read_only_vals_ext, 0x0C, NULL, HFILL }},
3667 { &hf_as_ep_gen_controls_data_underrun,
3668 { "Valid Alternate Settings Control", "usbaudio.as_ep_gen.bmControls.underrun", FT_UINT8,
3669 BASE_HEX|BASE_EXT_STRING, &controls_capabilities_read_only_vals_ext, 0x30, NULL, HFILL }},
3670 { &hf_as_ep_gen_controls_rsv,
3671 { "Reserved", "usbaudio.as_ep_gen.bmControls.bmControls.rsv",
3672 FT_UINT8, BASE_HEX, NULL, 0xC0, "Must be zero", HFILL }},
3673 { &hf_as_ep_gen_lockdelayunits,
3674 { "Lock Delay Units", "usbaudio.as_ep_gen.bLockDelayUnits",
3675 FT_UINT8, BASE_DEC, VALS(lock_delay_unit_vals), 0x00, NULL, HFILL }},
3676 { &hf_as_ep_gen_lockdelay,
3677 { "Lock Delay", "usbaudio.as_ep_gen.wLockDelay",
3678 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3680 { &hf_ms_if_desc_subtype,
3681 { "Subtype", "usbaudio.ms_if_subtype", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
3682 &ms_if_subtype_vals_ext, 0x0, "bDescriptorSubtype", HFILL }},
3683 { &hf_ms_if_hdr_ver,
3684 { "Version", "usbaudio.ms_if_hdr.bcdADC",
3685 FT_DOUBLE, BASE_NONE, NULL, 0, "bcdADC", HFILL }},
3686 { &hf_ms_if_hdr_total_len,
3687 { "Total length", "usbaudio.ms_if_hdr.wTotalLength",
3688 FT_UINT16, BASE_DEC, NULL, 0x00, "wTotalLength", HFILL }},
3689 { &hf_ms_if_midi_in_bjacktype,
3690 { "Jack Type", "usbaudio.ms_if_midi_in.bJackType",
3691 FT_UINT8, BASE_HEX, VALS(ms_midi_jack_type_vals), 0x00, "bJackType", HFILL }},
3692 { &hf_ms_if_midi_in_bjackid,
3693 { "Jack ID", "usbaudio.ms_if_midi_in.bJackID",
3694 FT_UINT8, BASE_DEC, NULL, 0x00, "bJackID", HFILL }},
3695 { &hf_ms_if_midi_in_ijack,
3696 { "String descriptor index", "usbaudio.ms_if_midi_in.iJack",
3697 FT_UINT8, BASE_DEC, NULL, 0x00, "iJack", HFILL }},
3698 { &hf_ms_if_midi_out_bjacktype,
3699 { "Jack Type", "usbaudio.ms_if_midi_out.bJackType",
3700 FT_UINT8, BASE_HEX, VALS(ms_midi_jack_type_vals), 0x00, "bJackType", HFILL }},
3701 { &hf_ms_if_midi_out_bjackid,
3702 { "Jack ID", "usbaudio.ms_if_midi_out.bJackID",
3703 FT_UINT8, BASE_DEC, NULL, 0x00, "bJackID", HFILL }},
3704 { &hf_ms_if_midi_out_bnrinputpins,
3705 { "Number of Input Pins", "usbaudio.ms_if_midi_out.bNrInputPins",
3706 FT_UINT8, BASE_DEC, NULL, 0x00, "bNrInputPins", HFILL }},
3707 { &hf_ms_if_midi_out_basourceid,
3708 { "Connected MIDI Entity", "usbaudio.ms_if_midi_out.baSourceID",
3709 FT_UINT8, BASE_DEC, NULL, 0x00, "baSourceID", HFILL }},
3710 { &hf_ms_if_midi_out_basourcepin,
3711 { "Entity Output Pin", "usbaudio.ms_if_midi_out.BaSourcePin",
3712 FT_UINT8, BASE_DEC, NULL, 0x00, "BaSourcePin", HFILL }},
3713 { &hf_ms_if_midi_out_ijack,
3714 { "String descriptor index", "usbaudio.ms_if_midi_out.iJack",
3715 FT_UINT8, BASE_DEC, NULL, 0x00, "iJack", HFILL }},
3717 { &hf_ms_ep_desc_subtype,
3718 { "Subtype", "usbaudio.ms_ep_subtype", FT_UINT8,
3719 BASE_HEX, VALS(ms_ep_subtype_vals), 0x00, "bDescriptorSubtype", HFILL }},
3720 { &hf_ms_ep_gen_numjacks,
3721 { "Number of Embedded MIDI Jacks", "usbaudio.ms_ep_gen.bNumEmbMIDIJack", FT_UINT8,
3722 BASE_DEC, NULL, 0x00, "bNumEmbMIDIJack", HFILL }},
3723 { &hf_ms_ep_gen_baassocjackid,
3724 { "Associated Embedded Jack ID", "usbaudio.ms_ep_gen.baAssocJackID", FT_UINT8,
3725 BASE_DEC, NULL, 0x00, "baAssocJackID", HFILL }},
3727 { &hf_brequest_v1,
3728 { "bRequest", "usbaudio.bRequest",
3729 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &v1_brequest_vals_ext, 0x0, NULL, HFILL }},
3730 { &hf_brequest_v2,
3731 { "bRequest", "usbaudio.bRequest",
3732 FT_UINT8, BASE_HEX|BASE_EXT_STRING, &v2_brequest_vals_ext, 0x0, NULL, HFILL }},
3733 { &hf_wvalue,
3734 { "wValue", "usbaudio.wValue", FT_UINT16, BASE_HEX,
3735 NULL, 0x0, NULL, HFILL }},
3736 { &hf_wvalue_channel_number,
3737 { "Channel Number", "usbaudio.wValue.channel_number",
3738 FT_UINT16, BASE_HEX, NULL, 0x00FF, NULL, HFILL }},
3739 { &hf_wvalue_fu_cs_v1,
3740 { "Feature Unit Control Selector", "usbaudio.wValue.fu_cs",
3741 FT_UINT16, BASE_HEX|BASE_EXT_STRING, &v1_fu_cs_vals_ext, 0xFF00, NULL, HFILL }},
3742 { &hf_wvalue_clksrc_cs,
3743 { "Clock Source Control Selector", "usbaudio.wValue.clksrc_cs",
3744 FT_UINT16, BASE_HEX, VALS(v2_clksrc_cs_vals), 0xFF00, NULL, HFILL }},
3745 { &hf_wvalue_clksel_cs,
3746 { "Clock Selector Control Selector", "usbaudio.wValue.clksel_cs",
3747 FT_UINT16, BASE_HEX, VALS(v2_clksel_cs_vals), 0xFF00, NULL, HFILL }},
3748 { &hf_windex,
3749 { "wIndex", "usbaudio.wIndex",
3750 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3751 { &hf_windex_interface,
3752 { "Interface Number", "usbaudio.wIndex.interface",
3753 FT_UINT16, BASE_DEC, NULL, 0x00FF, NULL, HFILL }},
3754 { &hf_windex_entity_id,
3755 { "Entity ID", "usbaudio.wIndex.entity_id",
3756 FT_UINT16, BASE_DEC, NULL, 0xFF00, NULL, HFILL }},
3757 { &hf_windex_endpoint,
3758 { "Endpoint Number", "usbaudio.wIndex.endpoint",
3759 FT_UINT16, BASE_HEX, NULL, 0x008F, NULL, HFILL }},
3760 { &hf_wlength,
3761 { "wLength", "usbaudio.wLength",
3762 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3763 { &hf_parameter_bselector,
3764 { "bSelector", "usbaudio.bSelector",
3765 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3766 { &hf_parameter_bmute,
3767 { "bMute", "usbaudio.bMute",
3768 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3769 { &hf_parameter_wvolume,
3770 { "wVolume", "usbaudio.wVolume",
3771 FT_UINT16, BASE_CUSTOM, CF_FUNC(base_volume), 0x0, NULL, HFILL }},
3772 { &hf_parameter_wnumsubranges,
3773 { "wNumSubRanges", "usbaudio.wNumSubRanges",
3774 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3775 { &hf_parameter_bcur,
3776 { "bCUR", "usbaudio.bCUR",
3777 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3778 { &hf_parameter_bmin,
3779 { "bMIN", "usbaudio.bMIN",
3780 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3781 { &hf_parameter_bmax,
3782 { "bMAX", "usbaudio.bMAX",
3783 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3784 { &hf_parameter_bres,
3785 { "bRES", "usbaudio.bRES",
3786 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3787 { &hf_parameter_wcur,
3788 { "wCUR", "usbaudio.wCUR",
3789 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3790 { &hf_parameter_wmin,
3791 { "wMIN", "usbaudio.wMIN",
3792 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3793 { &hf_parameter_wmax,
3794 { "wMAX", "usbaudio.wMAX",
3795 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3796 { &hf_parameter_wres,
3797 { "wRES", "usbaudio.wRES",
3798 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3799 { &hf_parameter_dcur,
3800 { "dCUR", "usbaudio.bCUR",
3801 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3802 { &hf_parameter_dmin,
3803 { "dMIN", "usbaudio.dMIN",
3804 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3805 { &hf_parameter_dmax,
3806 { "dMAX", "usbaudio.dMAX",
3807 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3808 { &hf_parameter_dres,
3809 { "dRES", "usbaudio.dRES",
3810 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3812 { &hf_sysex_msg_fragments,
3813 { "Message fragments", "usbaudio.sysex.fragments",
3814 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3815 { &hf_sysex_msg_fragment,
3816 { "Message fragment", "usbaudio.sysex.fragment",
3817 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3818 { &hf_sysex_msg_fragment_overlap,
3819 { "Message fragment overlap", "usbaudio.sysex.fragment.overlap",
3820 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3821 { &hf_sysex_msg_fragment_overlap_conflicts,
3822 { "Message fragment overlapping with conflicting data",
3823 "usbaudio.sysex.fragment.overlap.conflicts",
3824 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3825 { &hf_sysex_msg_fragment_multiple_tails,
3826 { "Message has multiple tail fragments",
3827 "usbaudio.sysex.fragment.multiple_tails",
3828 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3829 { &hf_sysex_msg_fragment_too_long_fragment,
3830 { "Message fragment too long", "usbaudio.sysex.fragment.too_long_fragment",
3831 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3832 { &hf_sysex_msg_fragment_error,
3833 { "Message defragmentation error", "usbaudio.sysex.fragment.error",
3834 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3835 { &hf_sysex_msg_fragment_count,
3836 { "Message fragment count", "usbaudio.sysex.fragment.count",
3837 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }},
3838 { &hf_sysex_msg_reassembled_in,
3839 { "Reassembled in", "usbaudio.sysex.reassembled.in",
3840 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL }},
3841 { &hf_sysex_msg_reassembled_length,
3842 { "Reassembled length", "usbaudio.sysex.reassembled.length",
3843 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL }},
3844 { &hf_sysex_msg_reassembled_data,
3845 { "Reassembled data", "usbaudio.sysex.reassembled.data",
3846 FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL }}
3849 static int *usb_audio_subtrees[] = {
3850 &ett_usb_audio,
3851 &ett_usb_audio_desc,
3852 &ett_sysex_msg_fragment,
3853 &ett_sysex_msg_fragments,
3854 &ett_ac_if_hdr_controls,
3855 &ett_ac_if_fu_controls,
3856 &ett_ac_if_fu_controls0,
3857 &ett_ac_if_fu_controls1,
3858 &ett_ac_if_fu_controls_v2,
3859 &ett_ac_if_fu_control_v2,
3860 &ett_ac_if_su_sourceids,
3861 &ett_ac_if_su_controls,
3862 &ett_ac_if_input_wchannelconfig,
3863 &ett_ac_if_input_bmchannelconfig,
3864 &ett_ac_if_input_controls,
3865 &ett_ac_if_output_controls,
3866 &ett_ac_if_mu_channelconfig,
3867 &ett_ac_if_clksrc_attr,
3868 &ett_ac_if_clksrc_controls,
3869 &ett_ac_if_clksel_controls,
3870 &ett_as_if_gen_controls,
3871 &ett_as_if_gen_formats,
3872 &ett_as_if_gen_bmchannelconfig,
3873 &ett_as_ep_gen_attributes,
3874 &ett_as_ep_gen_controls,
3875 &ett_wvalue,
3876 &ett_windex,
3877 &ett_parameter_block,
3880 static ei_register_info ei[] = {
3881 { &ei_usb_audio_undecoded, { "usbaudio.undecoded", PI_UNDECODED, PI_WARN, "Not dissected yet (report to wireshark.org)", EXPFILL }},
3882 { &ei_usb_audio_invalid_feature_unit_length, { "usbaudio.ac_if_fu.invalid_length", PI_MALFORMED, PI_ERROR, "Descriptor size is not 7+(ch+1)*n where n=bControlSize", EXPFILL }},
3883 { &ei_usb_audio_invalid_type_3_ft_nrchannels, { "usbaudio.as_if_ft.bNrChannels.invalid_value", PI_MALFORMED, PI_ERROR, "bNrChannels must be 2 for Type III Format Type descriptors", EXPFILL }},
3884 { &ei_usb_audio_invalid_type_3_ft_subframesize, { "usbaudio.as_if_ft.subframesize.invalid_value", PI_MALFORMED, PI_ERROR, "bSubFrameSize must be 2 for Type III Format Type descriptors", EXPFILL }},
3885 { &ei_usb_audio_invalid_type_3_ft_bitresolution, { "usbaudio.hf_as_if_ft_bitresolution.invalid_value", PI_MALFORMED, PI_ERROR, "bBitResolution must be 16 for Type III Format Type descriptors", EXPFILL }},
3888 expert_module_t *expert_usb_audio;
3890 proto_usb_audio = proto_register_protocol("USB Audio", "USBAUDIO", "usbaudio");
3891 proto_register_field_array(proto_usb_audio, hf, array_length(hf));
3892 proto_register_subtree_array(usb_audio_subtrees, array_length(usb_audio_subtrees));
3893 expert_usb_audio = expert_register_protocol(proto_usb_audio);
3894 expert_register_field_array(expert_usb_audio, ei, array_length(ei));
3895 reassembly_table_register(&midi_data_reassembly_table,
3896 &addresses_reassembly_table_functions);
3898 usb_audio_bulk_handle = register_dissector("usbaudio", dissect_usb_audio_bulk, proto_usb_audio);
3899 usb_audio_descr_handle = register_dissector("usbaudio.bulk", dissect_usb_audio_descriptor, proto_usb_audio);
3900 usb_audio_control_handle = register_dissector("usbaudio.control", dissect_usb_audio_control, proto_usb_audio);
3903 void
3904 proto_reg_handoff_usb_audio(void)
3906 dissector_add_uint("usb.descriptor", IF_CLASS_AUDIO, usb_audio_descr_handle);
3907 dissector_add_uint("usb.bulk", IF_CLASS_AUDIO, usb_audio_bulk_handle);
3908 dissector_add_uint("usb.control", IF_CLASS_AUDIO, usb_audio_control_handle);
3910 sysex_handle = find_dissector_add_dependency("sysex", proto_usb_audio);
3913 * Editor modelines
3915 * Local Variables:
3916 * c-basic-offset: 4
3917 * tab-width: 8
3918 * indent-tabs-mode: nil
3919 * End:
3921 * ex: set shiftwidth=4 tabstop=8 expandtab:
3922 * :indentSize=4:tabSize=8:noTabs=true: