Coverage Report

Created: 2026-01-02 06:13

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