/src/wireshark/epan/dissectors/packet-evs.c
Line | Count | Source |
1 | | /* packet-evs.c |
2 | | * Routines for EVS dissection |
3 | | * Copyright 2018, Anders Broman <anders.broman[at]ericsson.com> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | * |
11 | | * References: |
12 | | * 3GPP TS 26.445 A.2 EVS RTP Payload Format |
13 | | */ |
14 | | |
15 | | #include "config.h" |
16 | | |
17 | | #include <epan/packet.h> |
18 | | #include <epan/prefs.h> |
19 | | #include <epan/proto_data.h> |
20 | | #include <epan/tfs.h> |
21 | | #include <wsutil/str_util.h> |
22 | | #include <wsutil/utf8_entities.h> |
23 | | #include "packet-rtp.h" |
24 | | |
25 | | void proto_register_evs(void); |
26 | | void proto_reg_handoff_evs(void); |
27 | | |
28 | | static dissector_handle_t evs_handle; |
29 | | |
30 | | static bool evs_hf_only; |
31 | | |
32 | | /* Initialize the protocol and registered fields */ |
33 | | static int proto_evs; |
34 | | static int proto_rtp; |
35 | | |
36 | | static int hf_evs_packet_length; |
37 | | static int hf_evs_voice_data; |
38 | | static int hf_evs_h_bit; |
39 | | static int hf_evs_cmr_t; |
40 | | static int hf_evs_cmr_t0_d; |
41 | | static int hf_evs_cmr_t1_d; |
42 | | static int hf_evs_cmr_t2_d; |
43 | | static int hf_evs_cmr_t3_d; |
44 | | static int hf_evs_cmr_t4_d; |
45 | | static int hf_evs_cmr_t5_d; |
46 | | static int hf_evs_cmr_t6_d; |
47 | | static int hf_evs_cmr_t7_d; |
48 | | static int hf_evs_f_bit; |
49 | | static int hf_evs_mode_bit; |
50 | | static int hf_evs_toc_spare; |
51 | | static int hf_evs_amr_wb_q_bit; |
52 | | static int hf_evs_bit_rate_mode_0; |
53 | | static int hf_evs_bit_rate_mode_1; |
54 | | static int hf_evs_cmr_amr_io; |
55 | | static int hf_evs_bw; |
56 | | static int hf_evs_reserved_1bit; |
57 | | static int hf_evs_celp_switch_to_mdct_core; |
58 | | static int hf_evs_celp_mdct_core; |
59 | | static int hf_evs_tcx_or_hq_mdct_core; |
60 | | static int hf_evs_sid_cng; |
61 | | static int hf_evs_celp_sample_rate; |
62 | | static int hf_evs_core_sample_rate; |
63 | | static int hf_evs_132_bwctrf_idx; |
64 | | static int hf_evs_28_frame_type; |
65 | | static int hf_evs_28_bw_ppp_nelp; |
66 | | static int hf_evs_72_80_bwct_idx; |
67 | | static int hf_evs_320_bwct_idx; |
68 | | static int hf_evs_640_bwct_idx; |
69 | | |
70 | | static int ett_evs; |
71 | | static int ett_evs_header; |
72 | | static int ett_evs_speech; |
73 | | static int ett_evs_voice_data; |
74 | | |
75 | | static const value_string evs_protected_payload_sizes_value[] = { |
76 | | { 48, "EVS Primary SID 2.4" }, |
77 | | { 56, "Special case" }, |
78 | | { 136, "EVS AMR-WB IO 6.6" }, |
79 | | { 144, "EVS Primary 7.2" }, |
80 | | { 160, "EVS Primary 8.0" }, |
81 | | { 184, "EVS AMR-WB IO 8.85" }, |
82 | | { 192, "EVS Primary 9.6" }, |
83 | | { 256, "EVS AMR-WB IO 12.65" }, |
84 | | { 264, "EVS Primary 13.2" }, |
85 | | { 288, "EVS AMR-WB IO 14.25" }, |
86 | | { 320, "EVS AMR-WB IO 15.85" }, |
87 | | { 328, "EVS Primary 16.4" }, |
88 | | { 368, "EVS AMR-WB IO 18.25" }, |
89 | | { 400, "EVS AMR-WB IO 19.85" }, |
90 | | { 464, "EVS AMR-WB IO 23.05" }, |
91 | | { 480, "EVS AMR-WB IO 23.85" }, |
92 | | { 488, "EVS Primary 24.4" }, |
93 | | { 640, "EVS Primary 32.0" }, |
94 | | { 960, "EVS Primary 48.0" }, |
95 | | { 1280, "EVS Primary 64.0" }, |
96 | | { 1920, "EVS Primary 96.0" }, |
97 | | { 2560, "EVS Primary 128.0" }, |
98 | | { 0, NULL } |
99 | | }; |
100 | | |
101 | | static const value_string evs_d_bits_t0_values[] = { |
102 | | { 0x0, "NB 5.9 kbps (VBR)" }, |
103 | | { 0x1, "NB 7.2 kbps" }, |
104 | | { 0x2, "NB 8.0 kbps" }, |
105 | | { 0x3, "NB 9.6 kbps" }, |
106 | | { 0x4, "NB 13.2 kbps" }, |
107 | | { 0x5, "NB 16.4 kbps" }, |
108 | | { 0x6, "NB 24.4 kbps" }, |
109 | | { 0x7, "Not used" }, |
110 | | { 0x8, "Not used" }, |
111 | | { 0x9, "Not used" }, |
112 | | { 0xa, "Not used" }, |
113 | | { 0xb, "Not used" }, |
114 | | { 0xc, "Not used" }, |
115 | | { 0xd, "Not used" }, |
116 | | { 0xe, "Not used" }, |
117 | | { 0xf, "Not used" }, |
118 | | { 0, NULL } |
119 | | }; |
120 | | |
121 | | static const value_string evs_d_bits_t1_values[] = { |
122 | | { 0x0, "AMR-WB IO 6.6 kbps (mode-set 0)" }, |
123 | | { 0x1, "AMR-WB IO 8.8 kbps (mode-set 1)" }, |
124 | | { 0x2, "AMR-WB IO 12.65 kbps (mode-set 2)" }, |
125 | | { 0x3, "AMR-WB IO 14.25 kbps (mode-set 3)" }, |
126 | | { 0x4, "AMR-WB IO 15.85 kbps (mode-set 4)" }, |
127 | | { 0x5, "AMR-WB IO 18.25 kbps (mode-set 5)" }, |
128 | | { 0x6, "AMR-WB IO 19.85 kbps (mode-set 6)" }, |
129 | | { 0x7, "AMR-WB IO 23.05 kbps (mode-set 7)" }, |
130 | | { 0x8, "AMR-WB IO 23.85 kbps (mode-set 8)" }, |
131 | | { 0x9, "Not used" }, |
132 | | { 0xa, "Not used" }, |
133 | | { 0xb, "Not used" }, |
134 | | { 0xc, "Not used" }, |
135 | | { 0xd, "Not used" }, |
136 | | { 0xe, "Not used" }, |
137 | | { 0xf, "Not used" }, |
138 | | { 0, NULL } |
139 | | }; |
140 | | |
141 | | |
142 | | static const value_string evs_d_bits_t2_values[] = { |
143 | | { 0x0, "WB 5.9 kbps (VBR)" }, |
144 | | { 0x1, "WB 7.2 kbps" }, |
145 | | { 0x2, "WB 8 kbps" }, |
146 | | { 0x3, "WB 9.6 kbps" }, |
147 | | { 0x4,"WB 13.2 kbps" }, |
148 | | { 0x5,"WB 16.4 kbps" }, |
149 | | { 0x6,"WB 24.4 kbps" }, |
150 | | { 0x7,"WB 32 kbps" }, |
151 | | { 0x8,"WB 48 kbps" }, |
152 | | { 0x9,"WB 64 kbps" }, |
153 | | { 0xa,"WB 96 kbps" }, |
154 | | { 0xb,"WB 128 kbps" }, |
155 | | { 0xc, "Not used" }, |
156 | | { 0xd, "Not used" }, |
157 | | { 0xe, "Not used" }, |
158 | | { 0xf, "Not used" }, |
159 | | { 0, NULL } |
160 | | }; |
161 | | |
162 | | static const value_string evs_d_bits_t3_values[] = { |
163 | | { 0x0, "Not used" }, |
164 | | { 0x1, "Not used" }, |
165 | | { 0x2, "Not used" }, |
166 | | { 0x3, "SWB 9.6 kbps" }, |
167 | | { 0x4, "SWB 13.2 kbps" }, |
168 | | { 0x5, "SWB 16.4 kbps" }, |
169 | | { 0x6, "SWB 24.4 kbps" }, |
170 | | { 0x7, "SWB 32 kbps" }, |
171 | | { 0x8, "SWB 48 kbps" }, |
172 | | { 0x9, "SWB 64 kbps" }, |
173 | | { 0xa, "SWB 96 kbps" }, |
174 | | { 0xb, "SWB 128 kbps" }, |
175 | | { 0xc, "Not used" }, |
176 | | { 0xd, "Not used" }, |
177 | | { 0xe, "Not used" }, |
178 | | { 0xf, "Not used" }, |
179 | | { 0, NULL } |
180 | | }; |
181 | | |
182 | | static const value_string evs_d_bits_t4_values[] = { |
183 | | { 0x0, "Not used" }, |
184 | | { 0x1, "Not used" }, |
185 | | { 0x2, "Not used" }, |
186 | | { 0x3, "Not used" }, |
187 | | { 0x4, "Not used" }, |
188 | | { 0x5, "FB 16.4 kbps" }, |
189 | | { 0x6, "FB 24.4 kbps" }, |
190 | | { 0x7, "FB 32 kbps" }, |
191 | | { 0x8, "FB 48 kbps" }, |
192 | | { 0x9, "FB 64 kbps" }, |
193 | | { 0xa, "FB 96 kbps" }, |
194 | | { 0xb, "FB 128 kbps" }, |
195 | | { 0xc, "Not used" }, |
196 | | { 0xd, "Not used" }, |
197 | | { 0xe, "Not used" }, |
198 | | { 0xf, "Not used" }, |
199 | | { 0, NULL } |
200 | | }; |
201 | | |
202 | | static const value_string evs_d_bits_t5_values[] = { |
203 | | { 0x0, "WB 13.2 kbps CA-L-O2" }, |
204 | | { 0x1, "WB 13.2 kbps CA-L-O3" }, |
205 | | { 0x2, "WB 13.2 kbps CA-L-O5" }, |
206 | | { 0x3, "WB 13.2 kbps CA-L-O7" }, |
207 | | { 0x4, "WB 13.2 kbps CA-H-O2" }, |
208 | | { 0x5, "WB 13.2 kbps CA-H-O3" }, |
209 | | { 0x6, "WB 13.2 kbps CA-H-O5" }, |
210 | | { 0x7, "WB 13.2 kbps CA-H-O7" }, |
211 | | { 0x8, "Not used" }, |
212 | | { 0x9, "Not used" }, |
213 | | { 0xa, "Not used" }, |
214 | | { 0xb, "Not used" }, |
215 | | { 0xc, "Not used" }, |
216 | | { 0xd, "Not used" }, |
217 | | { 0xe, "Not used" }, |
218 | | { 0xf, "Not used" }, |
219 | | { 0, NULL } |
220 | | }; |
221 | | |
222 | | static const value_string evs_d_bits_t6_values[] = { |
223 | | { 0x0, "SWB 13.2 kbps CA-L-O2" }, |
224 | | { 0x1, "SWB 13.2 kbps CA-L-O3" }, |
225 | | { 0x2, "SWB 13.2 kbps CA-L-O5" }, |
226 | | { 0x3, "SWB 13.2 kbps CA-L-O7" }, |
227 | | { 0x4, "SWB 13.2 kbps CA-H-O2" }, |
228 | | { 0x5, "SWB 13.2 kbps CA-H-O3" }, |
229 | | { 0x6, "SWB 13.2 kbps CA-H-O5" }, |
230 | | { 0x7, "SWB 13.2 kbps CA-H-O7" }, |
231 | | { 0x8, "Not used" }, |
232 | | { 0x9, "Not used" }, |
233 | | { 0xa, "Not used" }, |
234 | | { 0xb, "Not used" }, |
235 | | { 0xc, "Not used" }, |
236 | | { 0xd, "Not used" }, |
237 | | { 0xe, "Not used" }, |
238 | | { 0xf, "Not used" }, |
239 | | { 0, NULL } |
240 | | }; |
241 | | |
242 | | static const value_string evs_d_bits_t7_values[] = { |
243 | | { 0x0, "Reserved" }, |
244 | | { 0x1, "Reserved" }, |
245 | | { 0x2, "Reserved" }, |
246 | | { 0x3, "Reserved" }, |
247 | | { 0x4, "Reserved" }, |
248 | | { 0x5, "Reserved" }, |
249 | | { 0x6, "Reserved" }, |
250 | | { 0x7, "Reserved" }, |
251 | | { 0x8, "Reserved" }, |
252 | | { 0x9, "Reserved" }, |
253 | | { 0xa, "Reserved" }, |
254 | | { 0xb, "Reserved" }, |
255 | | { 0xc, "Reserved" }, |
256 | | { 0xd, "Reserved" }, |
257 | | { 0xe, "Reserved" }, |
258 | | { 0xf, "NO_REQ" }, |
259 | | { 0, NULL } |
260 | | }; |
261 | | |
262 | | static const value_string evs_bit_rate_mode_0_values[] = { |
263 | | { 0x0, "Primary 2.8 kbps" }, |
264 | | { 0x1, "Primary 7.2 kbps" }, |
265 | | { 0x2, "Primary 8.0 kbps" }, |
266 | | { 0x3, "Primary 9.6 kbps" }, |
267 | | { 0x4, "Primary 13.2 kbps" }, |
268 | | { 0x5, "Primary 16.4 kbps" }, |
269 | | { 0x6, "Primary 24.4 kbps" }, |
270 | | { 0x7, "Primary 32.0 kbps" }, |
271 | | { 0x8, "Primary 48.0 kbps" }, |
272 | | { 0x9, "Primary 64.0 kbps" }, |
273 | | { 0xa, "Primary 96.0 kbps" }, |
274 | | { 0xb, "Primary 128.0 kbps" }, |
275 | | { 0xc, "Primary 2.4 kbps SID" }, |
276 | | { 0xd, "For future use" }, |
277 | | { 0xe, "SPEECH_LOST" }, |
278 | | { 0xf, "NO_DATA" }, |
279 | | { 0, NULL } |
280 | | }; |
281 | | |
282 | | static const value_string evs_bit_rate_mode_1_values[] = { |
283 | | { 0x0, "AMR-WB IO 6.6 kbps" }, |
284 | | { 0x1, "AMR-WB IO 8.85 kbps" }, |
285 | | { 0x2, "AMR-WB IO 12.65 kbps" }, |
286 | | { 0x3, "AMR-WB IO 14.24 kbps" }, |
287 | | { 0x4, "AMR-WB IO 15.85 kbps" }, |
288 | | { 0x5, "AMR-WB IO 18.25 kbps" }, |
289 | | { 0x6, "AMR-WB IO 19.85 kbps" }, |
290 | | { 0x7, "AMR-WB IO 23.05 kbps" }, |
291 | | { 0x8, "AMR-WB IO 23.85 kbps" }, |
292 | | { 0x9, "AMR-WB IO 2.0 kbps SID" }, |
293 | | { 0xa, "For future use" }, |
294 | | { 0xb, "For future use" }, |
295 | | { 0xc, "For future use" }, |
296 | | { 0xd, "For future use" }, |
297 | | { 0xe, "SPEECH_LOST" }, |
298 | | { 0xf, "NO_DATA" }, |
299 | | { 0, NULL } |
300 | | }; |
301 | | |
302 | | |
303 | | static const value_string evs_cmr_amr_io_values[] = { |
304 | | { 0x0, "AMR-WB IO 6.6 kbps" }, |
305 | | { 0x1, "AMR-WB IO 8.85 kbps" }, |
306 | | { 0x2, "AMR-WB IO 12.65 kbps" }, |
307 | | { 0x3, "AMR-WB IO 15.85 kbps" }, |
308 | | { 0x4, "AMR-WB IO 18.25 kbps" }, |
309 | | { 0x5, "AMR-WB IO 23.05 kbps" }, |
310 | | { 0x6, "AMR-WB IO 23.85 kbps" }, |
311 | | { 0x7, "none" }, |
312 | | { 0, NULL } |
313 | | }; |
314 | | |
315 | | static const true_false_string tfs_evs_h_bit = { |
316 | | "CMR", |
317 | | "ToC" |
318 | | }; |
319 | | |
320 | | static const true_false_string tfs_evs_f_bit = { |
321 | | "Speech frame follows", |
322 | | "Last frame in payload" |
323 | | }; |
324 | | |
325 | | static const true_false_string toc_evs_q_bit_vals = { |
326 | | "Ok", |
327 | | "Severely damaged frame" |
328 | | }; |
329 | | |
330 | | static const value_string evs_bw_values[] = { |
331 | | { 0x0, "NB" }, |
332 | | { 0x1, "WB" }, |
333 | | { 0x2, "SWB" }, |
334 | | { 0x3, "FB" }, |
335 | | { 0, NULL } |
336 | | }; |
337 | | |
338 | | static const value_string evs_celp_switch_to_mdct_core_values[] = { |
339 | | { 0x00, "False" }, |
340 | | { 0x01, "True" }, |
341 | | { 0, NULL } |
342 | | }; |
343 | | |
344 | | static const value_string evs_celp_or_mdct_core_values[] = { |
345 | | { 0x0, "CELP" }, |
346 | | { 0x1, "MDCT" }, |
347 | | { 0, NULL } |
348 | | }; |
349 | | |
350 | | static const value_string evs_tcx_or_hq_mdct_core_values[] = { |
351 | | { 0x0, "HQ-MDCT core" }, |
352 | | { 0x1, "TCX Core" }, |
353 | | { 0, NULL } |
354 | | }; |
355 | | |
356 | | static const value_string evs_sid_cng_values[] = { |
357 | | { 0x0, "LP-CNG SID" }, |
358 | | { 0x1, "FD-CNG" }, |
359 | | { 0, NULL } |
360 | | }; |
361 | | |
362 | | static const value_string evs_sid_celp_sample_rate_values[] = { |
363 | | { 0x0, "12.8 kHz" }, |
364 | | { 0x1, "16 kHz" }, |
365 | | { 0, NULL } |
366 | | }; |
367 | | |
368 | | static const value_string evs_132_bwctrf_idx_vals[] = { |
369 | | { 0x0, "NB generic" }, |
370 | | { 0x1, "NB voiced" }, |
371 | | { 0x2, "NB transition" }, |
372 | | { 0x3, "NB audio" }, |
373 | | { 0x4, "NB inactive" }, |
374 | | { 0x5, "WB generic" }, |
375 | | { 0x6, "WB voiced" }, |
376 | | { 0x7, "WB transition" }, |
377 | | { 0x8, "WB audio" }, |
378 | | { 0x9, "WB inactive" }, |
379 | | { 0xa, "SWB generic" }, |
380 | | { 0xb, "SWB voiced" }, |
381 | | { 0xc, "SWB transition" }, |
382 | | { 0xd, "SWB audio" }, |
383 | | { 0xe, "SWB inactive" }, |
384 | | { 0xf, "NB generic" }, |
385 | | { 0x10, "NB voiced" }, |
386 | | { 0x11, "WB generic" }, |
387 | | { 0x12, "WB voiced" }, |
388 | | { 0x13, "SWB generic" }, |
389 | | { 0x14, "SWB voiced" }, |
390 | | { 0x15, "WB generic" }, |
391 | | { 0x16, "WB unvoiced" }, |
392 | | { 0x17, "WB voiced" }, |
393 | | { 0x18, "WB inactive" }, |
394 | | { 0x19, "SWB generic" }, |
395 | | { 0x1a, "SWB unvoiced" }, |
396 | | { 0x1b, "SWB voiced" }, |
397 | | { 0x1c, "SWB inactive" }, |
398 | | { 0x1d, "NB lrMDCT" }, |
399 | | { 0x1e, "WB lrMDCT" }, |
400 | | { 0x1f, "SWB lrMDCT" }, |
401 | | { 0, NULL } |
402 | | }; |
403 | | |
404 | | static const value_string evs_28_frame_type_vals[] = { |
405 | | { 0x0, "Primary PPP/NELP" }, |
406 | | { 0x1, "AMR-WB IO SID" }, |
407 | | { 0, NULL } |
408 | | }; |
409 | | |
410 | | static const value_string evs_28_bw_ppp_nelp_vals[] = { |
411 | | { 0x00, "NB PPP" }, |
412 | | { 0x01, "WB PPP" }, |
413 | | { 0x02, "NB NELP" }, |
414 | | { 0x03, "WB NELP" }, |
415 | | { 0, NULL } |
416 | | }; |
417 | | |
418 | | static const value_string evs_72_80_bwct_idx_vals[] = { |
419 | | { 0x0, "NB generic" }, |
420 | | { 0x1, "NB unvoiced" }, |
421 | | { 0x2, "NB voiced" }, |
422 | | { 0x3, "NB transition" }, |
423 | | { 0x4, "NB audio" }, |
424 | | { 0x5, "NB inactive" }, |
425 | | { 0x6, "WB generic" }, |
426 | | { 0x7, "WB unvoiced" }, |
427 | | { 0x8, "WB voiced" }, |
428 | | { 0x9, "WB transition" }, |
429 | | { 0xa, "WB audio" }, |
430 | | { 0xb, "WB inactive" }, |
431 | | { 0xc, "NB generic" }, |
432 | | { 0xd, "WB generic" }, |
433 | | { 0xe, "NB lrMDCT" }, |
434 | | { 0, NULL } |
435 | | }; |
436 | | |
437 | | static const value_string evs_320_bwct_idx_vals[] = { |
438 | | { 0x0, "WB generic" }, |
439 | | { 0x1, "WB transition" }, |
440 | | { 0x2, "WB inactive" }, |
441 | | { 0x3, "SWB generic" }, |
442 | | { 0x4, "SWB transition" }, |
443 | | { 0x5, "SWB inactive" }, |
444 | | { 0x6, "FB generic" }, |
445 | | { 0x7, "FB transition" }, |
446 | | { 0x8, "FB inactive" }, |
447 | | { 0x9, "WB generic" }, |
448 | | { 0xa, "WB transition" }, |
449 | | { 0xb, "SWB generic" }, |
450 | | { 0xc, "SWB transition" }, |
451 | | { 0xd, "FB generic" }, |
452 | | { 0xe, "FB transition" }, |
453 | | { 0, NULL } |
454 | | }; |
455 | | |
456 | | static const value_string evs_640_bwct_idx_vals[] = { |
457 | | { 0x0, "WB generic" }, |
458 | | { 0x1, "WB transition" }, |
459 | | { 0x2, "WB inactive" }, |
460 | | { 0x3, "SWB generic" }, |
461 | | { 0x4, "SWB transition" }, |
462 | | { 0x5, "SWB inactive" }, |
463 | | { 0x6, "FB generic" }, |
464 | | { 0x7, "FB transition" }, |
465 | | { 0x8, "FB inactive" }, |
466 | | { 0x9, "SWB generic" }, |
467 | | { 0xa, "SWB transition" }, |
468 | | { 0xb, "FB generic" }, |
469 | | { 0xc, "FB transition" }, |
470 | | { 0, NULL } |
471 | | }; |
472 | | |
473 | | static void |
474 | | dissect_evs_cmr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *evs_tree, int offset, uint8_t cmr_oct) |
475 | 0 | { |
476 | 0 | proto_tree *tree; |
477 | 0 | proto_item *item; |
478 | 0 | const char *str; |
479 | 0 | uint8_t t_bits = (cmr_oct & 0x70) >> 4; |
480 | 0 | uint8_t d_bits = (cmr_oct & 0x0f); |
481 | | /* CMR */ |
482 | 0 | tree = proto_tree_add_subtree(evs_tree, tvb, offset, 1, ett_evs_header, &item, "CMR"); |
483 | | |
484 | |
|
485 | 0 | switch (t_bits) { |
486 | 0 | case 0: |
487 | 0 | { |
488 | 0 | static int * const flags_t0[] = { |
489 | 0 | &hf_evs_h_bit, |
490 | 0 | &hf_evs_cmr_t, |
491 | 0 | &hf_evs_cmr_t0_d, |
492 | 0 | NULL |
493 | 0 | }; |
494 | |
|
495 | 0 | str = val_to_str_const(d_bits, evs_d_bits_t0_values, "Unknown value"); |
496 | 0 | proto_item_append_text(item, " %s",str); |
497 | 0 | proto_tree_add_bitmask_list(tree, tvb, offset, 1, flags_t0, ENC_BIG_ENDIAN); |
498 | 0 | } |
499 | 0 | break; |
500 | 0 | case 1: |
501 | 0 | { |
502 | 0 | static int * const flags_t1[] = { |
503 | 0 | &hf_evs_h_bit, |
504 | 0 | &hf_evs_cmr_t, |
505 | 0 | &hf_evs_cmr_t1_d, |
506 | 0 | NULL |
507 | 0 | }; |
508 | |
|
509 | 0 | str = val_to_str_const(d_bits, evs_d_bits_t1_values, "Unknown value"); |
510 | 0 | proto_item_append_text(item, " %s",str); |
511 | 0 | proto_tree_add_bitmask_list(tree, tvb, offset, 1, flags_t1, ENC_BIG_ENDIAN); |
512 | 0 | } |
513 | 0 | break; |
514 | 0 | case 2: |
515 | 0 | { |
516 | 0 | static int * const flags_t2[] = { |
517 | 0 | &hf_evs_h_bit, |
518 | 0 | &hf_evs_cmr_t, |
519 | 0 | &hf_evs_cmr_t2_d, |
520 | 0 | NULL |
521 | 0 | }; |
522 | |
|
523 | 0 | str = val_to_str_const(d_bits, evs_d_bits_t2_values, "Unknown value"); |
524 | 0 | proto_item_append_text(item, " %s",str); |
525 | 0 | proto_tree_add_bitmask_list(tree, tvb, offset, 1, flags_t2, ENC_BIG_ENDIAN); |
526 | 0 | } |
527 | 0 | break; |
528 | 0 | case 3: |
529 | 0 | { |
530 | 0 | static int * const flags_t3[] = { |
531 | 0 | &hf_evs_h_bit, |
532 | 0 | &hf_evs_cmr_t, |
533 | 0 | &hf_evs_cmr_t3_d, |
534 | 0 | NULL |
535 | 0 | }; |
536 | |
|
537 | 0 | str = val_to_str_const(d_bits, evs_d_bits_t3_values, "Unknown value"); |
538 | 0 | proto_item_append_text(item, " %s",str); |
539 | 0 | proto_tree_add_bitmask_list(tree, tvb, offset, 1, flags_t3, ENC_BIG_ENDIAN); |
540 | 0 | } |
541 | 0 | break; |
542 | 0 | case 4: |
543 | 0 | { |
544 | 0 | static int * const flags_t4[] = { |
545 | 0 | &hf_evs_h_bit, |
546 | 0 | &hf_evs_cmr_t, |
547 | 0 | &hf_evs_cmr_t4_d, |
548 | 0 | NULL |
549 | 0 | }; |
550 | |
|
551 | 0 | str = val_to_str_const(d_bits, evs_d_bits_t4_values, "Unknown value"); |
552 | 0 | proto_item_append_text(item, " %s",str); |
553 | 0 | proto_tree_add_bitmask_list(tree, tvb, offset, 1, flags_t4, ENC_BIG_ENDIAN); |
554 | 0 | } |
555 | 0 | break; |
556 | 0 | case 5: |
557 | 0 | { |
558 | 0 | static int * const flags_t5[] = { |
559 | 0 | &hf_evs_h_bit, |
560 | 0 | &hf_evs_cmr_t, |
561 | 0 | &hf_evs_cmr_t5_d, |
562 | 0 | NULL |
563 | 0 | }; |
564 | |
|
565 | 0 | str = val_to_str_const(d_bits, evs_d_bits_t5_values, "Unknown value"); |
566 | 0 | proto_item_append_text(item, " %s",str); |
567 | 0 | proto_tree_add_bitmask_list(tree, tvb, offset, 1, flags_t5, ENC_BIG_ENDIAN); |
568 | 0 | } |
569 | 0 | break; |
570 | 0 | case 6: |
571 | 0 | { |
572 | 0 | static int * const flags_t6[] = { |
573 | 0 | &hf_evs_h_bit, |
574 | 0 | &hf_evs_cmr_t, |
575 | 0 | &hf_evs_cmr_t6_d, |
576 | 0 | NULL |
577 | 0 | }; |
578 | |
|
579 | 0 | str = val_to_str_const(d_bits, evs_d_bits_t6_values, "Unknown value"); |
580 | 0 | proto_item_append_text(item, " %s",str); |
581 | 0 | proto_tree_add_bitmask_list(tree, tvb, offset, 1, flags_t6, ENC_BIG_ENDIAN); |
582 | 0 | } |
583 | 0 | break; |
584 | 0 | case 7: |
585 | 0 | { |
586 | 0 | static int * const flags_t7[] = { |
587 | 0 | &hf_evs_h_bit, |
588 | 0 | &hf_evs_cmr_t, |
589 | 0 | &hf_evs_cmr_t7_d, |
590 | 0 | NULL |
591 | 0 | }; |
592 | |
|
593 | 0 | str = val_to_str_const(d_bits, evs_d_bits_t7_values, "Unknown value"); |
594 | 0 | proto_item_append_text(item, " %s",str); |
595 | 0 | proto_tree_add_bitmask_list(tree, tvb, offset, 1, flags_t7, ENC_BIG_ENDIAN); |
596 | 0 | } |
597 | 0 | break; |
598 | 0 | default: |
599 | 0 | DISSECTOR_ASSERT_NOT_REACHED(); |
600 | 0 | break; |
601 | |
|
602 | 0 | } |
603 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", str); |
604 | 0 | } |
605 | | |
606 | | /* Code to actually dissect the packets */ |
607 | | static int |
608 | | dissect_evs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
609 | 0 | { |
610 | 0 | proto_item *ti; |
611 | 0 | proto_tree *evs_tree, *sub_tree, *vd_tree; |
612 | 0 | int offset = 0 , bit_offset = 0; |
613 | 0 | int packet_len, idx, speech_data_len; |
614 | 0 | uint32_t num_bits; |
615 | 0 | const char *str; |
616 | 0 | uint8_t oct, h_bit, toc_f_bit, evs_mode_b; |
617 | 0 | int num_toc, num_data; |
618 | 0 | uint64_t value; |
619 | 0 | bool is_compact = false; |
620 | 0 | struct _rtp_pkt_info *rtp_pkt_info = p_get_proto_data(pinfo->pool, pinfo, proto_rtp, pinfo->curr_layer_num-1); |
621 | 0 | struct _rtp_info *rtp_info = NULL; |
622 | 0 | bool rtmp_enforce_hf_only = false; |
623 | | |
624 | | /* Make entries in Protocol column and Info column on summary display */ |
625 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "EVS"); |
626 | |
|
627 | 0 | ti = proto_tree_add_item(tree, proto_evs, tvb, 0, -1, ENC_NA); |
628 | 0 | evs_tree = proto_item_add_subtree(ti, ett_evs); |
629 | 0 | packet_len = tvb_reported_length(tvb); |
630 | | |
631 | | /* A.2.3.2 ignore sizes if hf-only=1 */ |
632 | 0 | if (data) { |
633 | 0 | rtp_info = (struct _rtp_info*)data; |
634 | 0 | if (rtp_info->info_payload_fmtp_map) { |
635 | 0 | char *tmp = wmem_map_lookup(rtp_info->info_payload_fmtp_map, "hf-only"); |
636 | 0 | if (g_strcmp0(tmp, "1") == 0) { |
637 | 0 | rtmp_enforce_hf_only = true; |
638 | 0 | } |
639 | 0 | } |
640 | 0 | } |
641 | | |
642 | | /* Find out if we have one of the reserved packet sizes*/ |
643 | 0 | if (!(rtmp_enforce_hf_only || evs_hf_only)) { |
644 | 0 | num_bits = packet_len * 8; |
645 | 0 | if (rtp_pkt_info) |
646 | 0 | num_bits += rtp_pkt_info->padding_len * 8; /* take into account RTP padding if any */ |
647 | 0 | if (num_bits == 56) { |
648 | | /* A.2.1.3 Special case for 56 bit payload size (EVS Primary or EVS AMR-WB IO SID) */ |
649 | | /* The resulting ambiguity between EVS Primary 2.8 kbps and EVS AMR-WB IO SID frames is resolved through the |
650 | | most significant bit (MSB) of the first byte of the payload. By definition, the first data bit d(0) of the EVS Primary 2.8 |
651 | | kbps is always set to '0'. |
652 | | */ |
653 | 0 | oct = tvb_get_bits8(tvb, bit_offset, 1); |
654 | 0 | if (oct == 0) { |
655 | | /* EVS Primary 2.8 kbps */ |
656 | 0 | str = "EVS Primary 2.8"; |
657 | 0 | is_compact = true; |
658 | 0 | } else { |
659 | | /* EVS AMR-WB IO SID */ |
660 | 0 | str = "EVS AMR-WB IO SID"; |
661 | 0 | } |
662 | 0 | } else { |
663 | 0 | str = try_val_to_str_idx(num_bits, evs_protected_payload_sizes_value, &idx); |
664 | 0 | if (str) { |
665 | 0 | is_compact = true; |
666 | 0 | } |
667 | 0 | } |
668 | 0 | } |
669 | |
|
670 | 0 | if (is_compact) { |
671 | | /* A.2.1 EVS codec Compact Format */ |
672 | 0 | proto_tree_add_subtree(evs_tree, tvb, offset, -1, ett_evs_header, &ti, "Framing Mode: Compact"); |
673 | 0 | proto_item_set_generated(ti); |
674 | | |
675 | | /* One of the protected payload sizes, no further dissection currently.*/ |
676 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", str); |
677 | 0 | proto_tree_add_int_format(evs_tree, hf_evs_packet_length, tvb, offset, 1, packet_len * 8, " %s, packet_len %i bits", str, packet_len * 8); |
678 | 0 | if (strncmp(str, "EVS A", 5) == 0) { |
679 | | /* A.2.1.2 Compact format for EVS AMR-WB IO mode */ |
680 | | /* CMR */ |
681 | 0 | proto_tree_add_item(evs_tree, hf_evs_cmr_amr_io, tvb, offset, 1, ENC_BIG_ENDIAN); |
682 | 0 | } |
683 | |
|
684 | 0 | vd_tree = proto_tree_add_subtree(evs_tree, tvb, offset, -1, ett_evs_voice_data, NULL, "Voice Data"); |
685 | 0 | switch (packet_len) { |
686 | 0 | case 17: /* 136 EVS AMR-WB IO 6.6 */ |
687 | 0 | case 23: /* 184 EVS AMR-WB IO 8.85 */ |
688 | 0 | case 32: /* 256 EVS AMR-WB IO 12.65 */ |
689 | 0 | case 36: /* 288 EVS AMR-WB IO 14.25 */ |
690 | 0 | case 40: /* 320 EVS AMR-WB IO 15.85 */ |
691 | 0 | case 46: /* 368 EVS AMR-WB IO 18.25 */ |
692 | 0 | case 50: /* 400 EVS AMR-WB IO 19.85 */ |
693 | 0 | case 58: /* 464 EVS AMR-WB IO 23.05 */ |
694 | 0 | case 60: /* 480 EVS AMR-WB IO 23.85 */ |
695 | | /* A.2.1.2 Compact format for EVS AMR-WB IO mode (except SID) |
696 | | * In the Compact format for EVS AMR-WB IO mode, except SID, the RTP payload consists of one 3-bit CMR field, |
697 | | * one coded frame, and zero-padding bits if necessary. |
698 | | */ |
699 | | /* CMR */ |
700 | 0 | proto_tree_add_item(evs_tree, hf_evs_cmr_amr_io, tvb, offset, 1, ENC_BIG_ENDIAN); |
701 | 0 | break; |
702 | 0 | case 6: /* 48 EVS Primary SID 2.4 */ |
703 | | /* 7.2 Bit allocation for SID frames in the DTX operation */ |
704 | | /* CNG type flag 1 bit */ |
705 | 0 | proto_tree_add_bits_ret_val(vd_tree, hf_evs_sid_cng, tvb, bit_offset, 1, &value, ENC_BIG_ENDIAN); |
706 | 0 | bit_offset++; |
707 | 0 | if (value == 1) { |
708 | | /* FD-CNG SID frame */ |
709 | | /* Bandwidth indicator 2 bits */ |
710 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_bw, tvb, bit_offset, 2, ENC_BIG_ENDIAN); |
711 | 0 | bit_offset += 2; |
712 | | /* CELP sample rate 1 bit*/ |
713 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_celp_sample_rate, tvb, bit_offset, 1, ENC_BIG_ENDIAN); |
714 | | /* Global gain 7 bits */ |
715 | | /* Spectral band and energy 37 bits */ |
716 | 0 | } else { |
717 | | /* LP-CNG SID frame */ |
718 | | /* Bandwidth indicator 1 bit */ |
719 | 0 | oct = tvb_get_bits8(tvb, bit_offset, 1); |
720 | 0 | proto_tree_add_uint_bits_format_value(vd_tree, hf_evs_bw, tvb, bit_offset, 1, 1, ENC_BIG_ENDIAN, "%s (%u)", |
721 | 0 | val_to_str_const(1 << oct, evs_bw_values, "Unknown value"), oct); |
722 | 0 | bit_offset++; |
723 | | /* Core sampling rate indicator */ |
724 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_core_sample_rate, tvb, bit_offset, 1, ENC_BIG_ENDIAN); |
725 | 0 | } |
726 | 0 | break; |
727 | 0 | case 7: /* 56 EVS Primary SID 2.8 */ |
728 | | /* A.2.1.3 Special case for 56 bit payload size (EVS Primary or EVS AMR-WB IO SID) */ |
729 | | /* The resulting ambiguity between EVS Primary 2.8 kbps and EVS AMR-WB IO SID frames is resolved through the |
730 | | most significant bit (MSB) of the first byte of the payload. By definition, the first data bit d(0) of the EVS Primary 2.8 |
731 | | kbps is always set to '0'. |
732 | | */ |
733 | 0 | proto_tree_add_bits_ret_val(vd_tree, hf_evs_28_frame_type, tvb, bit_offset, 1, &value, ENC_BIG_ENDIAN); |
734 | 0 | bit_offset++; |
735 | 0 | if (value == 0) { |
736 | | /* Primary PPP/NELP frame */ |
737 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_28_bw_ppp_nelp, tvb, bit_offset, 2, ENC_BIG_ENDIAN); |
738 | 0 | } |
739 | 0 | break; |
740 | 0 | case 18: /* 144 EVS Primary 7.2 */ |
741 | 0 | case 20: /* 160 EVS Primary 8.0 */ |
742 | | /* 7.1.1 Bit allocation at VBR 5.9, 7.2 – 9.6 kbps |
743 | | * Note that the BW and CT parameters are combined together to form a single index at 7.2 and 8.0 kbps. This index |
744 | | * conveys the information whether CELP core or HQ-MDCT core is used. |
745 | | */ |
746 | | /* BW, CT, 4*/ |
747 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_72_80_bwct_idx, tvb, bit_offset, 4, ENC_BIG_ENDIAN); |
748 | 0 | break; |
749 | 0 | case 24: /* 192 EVS Primary 9.6 */ |
750 | | /* 7.1.1 Bit allocation at VBR 5.9, 7.2 – 9.6 kbps */ |
751 | | /* BW 2 bits */ |
752 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_bw, tvb, bit_offset, 2, ENC_BIG_ENDIAN); |
753 | 0 | break; |
754 | 0 | case 33: /* 264 EVS Primary 13.2 */ |
755 | | /* 7.1.2 Bit allocation at 13.2 kbps |
756 | | * The EVS codec encodes NB, WB and SWB content at 13.2 kbps with CELP core, HQ-MDCT core, or TCX core. |
757 | | * For WB signals, the CELP core uses TBE or FD extension layer. For SWB signals, the CELP core uses TBE or FD extension layer, |
758 | | * and the TCX core uses IGF extension layer |
759 | | */ |
760 | | /* BW, CT, RF 5*/ |
761 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_132_bwctrf_idx, tvb, bit_offset, 5, ENC_BIG_ENDIAN); |
762 | 0 | break; |
763 | 0 | case 41: /* 328 EVS Primary 16.4 */ |
764 | | /* 7.1.3 Bit allocation at 16.4 and 24.4 kbps */ |
765 | | /* BW 2 bits*/ |
766 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_bw, tvb, bit_offset, 2, ENC_BIG_ENDIAN); |
767 | 0 | bit_offset+=2; |
768 | | /* Reserved 1 bit */ |
769 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_reserved_1bit, tvb, bit_offset, 1, ENC_BIG_ENDIAN); |
770 | 0 | break; |
771 | 0 | case 61: /* 488 EVS Primary 24.4 */ |
772 | | /* 7.1.3 Bit allocation at 16.4 and 24.4 kbps */ |
773 | | /* BW 2 bits*/ |
774 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_bw, tvb, bit_offset, 2, ENC_BIG_ENDIAN); |
775 | 0 | bit_offset+=2; |
776 | | /* Reserved 1 bit */ |
777 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_reserved_1bit, tvb, bit_offset, 1, ENC_BIG_ENDIAN); |
778 | 0 | bit_offset++; |
779 | | /* CELP/MDCT core flag 1 */ |
780 | 0 | proto_tree_add_bits_ret_val(vd_tree, hf_evs_celp_mdct_core, tvb, bit_offset, 1, &value, ENC_BIG_ENDIAN); |
781 | 0 | bit_offset++; |
782 | | /* In the case of MDCT-based core, the next bit decides whether HQ-MDCT core or TCX core is used */ |
783 | 0 | if (value == 1) { |
784 | | /* MDCT-based core*/ |
785 | 0 | proto_tree_add_bits_ret_val(vd_tree, hf_evs_tcx_or_hq_mdct_core, tvb, bit_offset, 1, &value, ENC_BIG_ENDIAN); |
786 | 0 | } |
787 | 0 | break; |
788 | 0 | case 80: /* 640 EVS Primary 32 */ |
789 | | /* 7.1.4 Bit allocation at 32 kbps */ |
790 | | /* CELP/MDCT core flag 1 */ |
791 | 0 | proto_tree_add_bits_ret_val(vd_tree, hf_evs_celp_mdct_core, tvb, bit_offset, 1, &value, ENC_BIG_ENDIAN); |
792 | 0 | bit_offset++; |
793 | | /* In the case of MDCT-based core, the next bit decides whether HQ-MDCT core or TCX core is used */ |
794 | 0 | if (value == 1) { |
795 | | /* MDCT-based core*/ |
796 | 0 | proto_tree_add_bits_ret_val(vd_tree, hf_evs_tcx_or_hq_mdct_core, tvb, bit_offset, 1, &value, ENC_BIG_ENDIAN); |
797 | 0 | bit_offset++; |
798 | 0 | if (value == 1) { |
799 | | /* TCX core */ |
800 | | /* BW 2 bits */ |
801 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_bw, tvb, bit_offset, 2, ENC_BIG_ENDIAN); |
802 | 0 | } |
803 | 0 | } else { |
804 | | /* BW, CT, 4*/ |
805 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_320_bwct_idx, tvb, bit_offset, 4, ENC_BIG_ENDIAN); |
806 | 0 | } |
807 | 0 | break; |
808 | 0 | case 160: /* 1280 EVS Primary 64 */ |
809 | | /* 7.1.5 Bit allocation at 48, 64, 96 and 128 kbps */ |
810 | | /* CELP/MDCT core flag 1 */ |
811 | 0 | proto_tree_add_bits_ret_val(vd_tree, hf_evs_celp_mdct_core, tvb, bit_offset, 1, &value, ENC_BIG_ENDIAN); |
812 | 0 | bit_offset++; |
813 | 0 | if (value == 1) { |
814 | | /* MDCT-based core*/ |
815 | 0 | proto_tree_add_bits_ret_val(vd_tree, hf_evs_celp_switch_to_mdct_core, tvb, bit_offset, 1, &value, ENC_BIG_ENDIAN); |
816 | 0 | bit_offset++; |
817 | 0 | if (value == 1) { |
818 | | /* CELP sample rate 1 bit*/ |
819 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_celp_sample_rate, tvb, bit_offset, 1, ENC_BIG_ENDIAN); |
820 | 0 | bit_offset++; |
821 | 0 | } |
822 | | /* BW 2 bits*/ |
823 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_bw, tvb, bit_offset, 2, ENC_BIG_ENDIAN); |
824 | 0 | } else { |
825 | | /* BW, CT, 4*/ |
826 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_640_bwct_idx, tvb, bit_offset, 4, ENC_BIG_ENDIAN); |
827 | 0 | } |
828 | 0 | break; |
829 | 0 | case 120: /* 960 EVS Primary 48 */ |
830 | 0 | case 240: /* 1920 EVS Primary 96 */ |
831 | 0 | case 320: /* 2560 EVS Primary 128 */ |
832 | | /* 7.1.5 Bit allocation at 48, 64, 96 and 128 kbps */ |
833 | | /* BW 2 bits*/ |
834 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_bw, tvb, bit_offset, 2, ENC_BIG_ENDIAN); |
835 | 0 | bit_offset+=2; |
836 | | /* Reserved 1 bit */ |
837 | 0 | proto_tree_add_bits_item(vd_tree, hf_evs_reserved_1bit, tvb, bit_offset, 1, ENC_BIG_ENDIAN); |
838 | 0 | break; |
839 | 0 | default: |
840 | 0 | break; |
841 | 0 | } |
842 | | |
843 | 0 | return packet_len; |
844 | 0 | } |
845 | | |
846 | | /* A.2.2 EVS codec Header-Full format */ |
847 | 0 | proto_tree_add_subtree(evs_tree, tvb, offset, -1, ett_evs_header, &ti, "Framing Mode: Header-full"); |
848 | 0 | proto_item_set_generated(ti); |
849 | | |
850 | | /*proto_tree_add_int_format(evs_tree, hf_evs_packet_length, tvb, offset, 1, packet_len * 8, "packet_len %i bits", packet_len * 8);*/ |
851 | 0 | oct = tvb_get_uint8(tvb, offset); |
852 | 0 | h_bit = oct >> 7; |
853 | |
|
854 | 0 | if (h_bit == 1) { |
855 | | /* CMR */ |
856 | 0 | dissect_evs_cmr(tvb, pinfo, evs_tree, offset, oct); |
857 | 0 | offset++; |
858 | 0 | } |
859 | | /* ToC */ |
860 | 0 | num_toc = 0; |
861 | 0 | do { |
862 | 0 | oct = tvb_get_uint8(tvb, offset); |
863 | 0 | toc_f_bit = (oct & 0x40) >> 6; |
864 | 0 | evs_mode_b = (oct & 0x20) >> 5; |
865 | 0 | num_toc++; |
866 | |
|
867 | 0 | sub_tree = proto_tree_add_subtree_format(evs_tree, tvb, offset, 1, ett_evs_header, NULL, " TOC # %u", |
868 | 0 | num_toc); |
869 | |
|
870 | 0 | if (evs_mode_b == 0) { |
871 | 0 | static int * const flags_toc_mode_0[] = { |
872 | 0 | &hf_evs_h_bit, |
873 | 0 | &hf_evs_f_bit, |
874 | 0 | &hf_evs_mode_bit, |
875 | 0 | &hf_evs_toc_spare, |
876 | 0 | &hf_evs_bit_rate_mode_0, |
877 | 0 | NULL |
878 | 0 | }; |
879 | |
|
880 | 0 | proto_tree_add_bitmask_list(sub_tree, tvb, offset, 1, flags_toc_mode_0, ENC_BIG_ENDIAN); |
881 | 0 | str = val_to_str_const((oct & 0x0f), evs_bit_rate_mode_0_values, "Unknown value"); |
882 | 0 | } else { |
883 | 0 | static int * const flags_toc_mode_1[] = { |
884 | 0 | &hf_evs_h_bit, |
885 | 0 | &hf_evs_f_bit, |
886 | 0 | &hf_evs_mode_bit, |
887 | 0 | &hf_evs_amr_wb_q_bit, |
888 | 0 | &hf_evs_bit_rate_mode_1, |
889 | 0 | NULL |
890 | 0 | }; |
891 | 0 | proto_tree_add_bitmask_list(sub_tree, tvb, offset, 1, flags_toc_mode_1, ENC_BIG_ENDIAN); |
892 | 0 | str = val_to_str_const((oct & 0x0f), evs_bit_rate_mode_1_values, "Unknown value"); |
893 | 0 | } |
894 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", str); |
895 | 0 | offset++; |
896 | 0 | } while (toc_f_bit == 1); |
897 | |
|
898 | 0 | speech_data_len = (packet_len - offset) / num_toc; |
899 | |
|
900 | 0 | num_data = num_toc; |
901 | 0 | num_toc = 1; |
902 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s (%u frame%s in packet)", UTF8_HORIZONTAL_ELLIPSIS, num_data, plurality(num_data, "", "s")); |
903 | 0 | while (num_data > 0) { |
904 | 0 | proto_tree *speech_tree; |
905 | |
|
906 | 0 | speech_tree = proto_tree_add_subtree_format(evs_tree, tvb, offset, speech_data_len, ett_evs_speech, NULL, "Speech frame for TOC # %u", |
907 | 0 | num_toc); |
908 | 0 | proto_tree_add_item(speech_tree, hf_evs_voice_data, tvb, offset, speech_data_len, ENC_NA); |
909 | 0 | offset += speech_data_len; |
910 | 0 | num_toc++; |
911 | 0 | num_data--; |
912 | 0 | } |
913 | |
|
914 | 0 | return packet_len; |
915 | 0 | } |
916 | | |
917 | | void |
918 | | proto_register_evs(void) |
919 | 15 | { |
920 | 15 | module_t *evs_module; |
921 | | /*expert_module_t* expert_evs;*/ |
922 | | |
923 | 15 | static hf_register_info hf[] = { |
924 | 15 | { &hf_evs_packet_length, |
925 | 15 | { "Packet length", "evs.packet_length", |
926 | 15 | FT_INT32, BASE_DEC, NULL, 0x0, |
927 | 15 | NULL, HFILL } |
928 | 15 | }, |
929 | 15 | { &hf_evs_voice_data, |
930 | 15 | { "Voice data", "evs.voice_data", |
931 | 15 | FT_BYTES, BASE_NONE, NULL, 0x0, |
932 | 15 | NULL, HFILL } |
933 | 15 | }, |
934 | 15 | { &hf_evs_h_bit, |
935 | 15 | { "Header Type identification bit (H)", "evs.h_bit", |
936 | 15 | FT_BOOLEAN, 8, TFS(&tfs_evs_h_bit), 0x80, |
937 | 15 | NULL, HFILL } |
938 | 15 | }, |
939 | 15 | { &hf_evs_cmr_t, |
940 | 15 | { "Type of Request(T)", "evs.cmr_t", |
941 | 15 | FT_UINT8, BASE_DEC, NULL, 0x70, |
942 | 15 | NULL, HFILL } |
943 | 15 | }, |
944 | 15 | { &hf_evs_cmr_t0_d, |
945 | 15 | { "D", "evs.cmr_t0_d", |
946 | 15 | FT_UINT8, BASE_DEC, VALS(evs_d_bits_t0_values), 0x0f, |
947 | 15 | NULL, HFILL } |
948 | 15 | }, |
949 | 15 | { &hf_evs_cmr_t1_d, |
950 | 15 | { "D", "evs.cmr_t1_d", |
951 | 15 | FT_UINT8, BASE_DEC, VALS(evs_d_bits_t1_values), 0x0f, |
952 | 15 | NULL, HFILL } |
953 | 15 | }, |
954 | 15 | { &hf_evs_cmr_t2_d, |
955 | 15 | { "D", "evs.cmr_t3_d", |
956 | 15 | FT_UINT8, BASE_DEC, VALS(evs_d_bits_t2_values), 0x0f, |
957 | 15 | NULL, HFILL } |
958 | 15 | }, |
959 | 15 | { &hf_evs_cmr_t3_d, |
960 | 15 | { "D", "evs.cmr_t3_d", |
961 | 15 | FT_UINT8, BASE_DEC, VALS(evs_d_bits_t3_values), 0x0f, |
962 | 15 | NULL, HFILL } |
963 | 15 | }, |
964 | 15 | { &hf_evs_cmr_t4_d, |
965 | 15 | { "D", "evs.cmr_t4_d", |
966 | 15 | FT_UINT8, BASE_DEC, VALS(evs_d_bits_t4_values), 0x0f, |
967 | 15 | NULL, HFILL } |
968 | 15 | }, |
969 | 15 | { &hf_evs_cmr_t5_d, |
970 | 15 | { "D", "evs.cmr_t5_d", |
971 | 15 | FT_UINT8, BASE_DEC, VALS(evs_d_bits_t5_values), 0x0f, |
972 | 15 | NULL, HFILL } |
973 | 15 | }, |
974 | 15 | { &hf_evs_cmr_t6_d, |
975 | 15 | { "D", "evs.cmr_t6_d", |
976 | 15 | FT_UINT8, BASE_DEC, VALS(evs_d_bits_t6_values), 0x0f, |
977 | 15 | NULL, HFILL } |
978 | 15 | }, |
979 | 15 | { &hf_evs_cmr_t7_d, |
980 | 15 | { "D", "evs.cmr_t7_d", |
981 | 15 | FT_UINT8, BASE_DEC, VALS(evs_d_bits_t7_values), 0x0f, |
982 | 15 | NULL, HFILL } |
983 | 15 | }, |
984 | 15 | { &hf_evs_mode_bit, |
985 | 15 | { "EVS Mode", "evs.mode_bit", |
986 | 15 | FT_UINT8, BASE_DEC, NULL, 0x20, |
987 | 15 | NULL, HFILL } |
988 | 15 | }, |
989 | 15 | { &hf_evs_toc_spare, |
990 | 15 | { "Unused", "evs.toc_spare", |
991 | 15 | FT_UINT8, BASE_DEC, NULL, 0x10, |
992 | 15 | NULL, HFILL } |
993 | 15 | }, |
994 | 15 | { &hf_evs_amr_wb_q_bit, |
995 | 15 | { "AMR WB Q bit", "evs.amr_wb_q_bit", |
996 | 15 | FT_BOOLEAN, 8, TFS(&toc_evs_q_bit_vals), 0x10, |
997 | 15 | NULL, HFILL } |
998 | 15 | }, |
999 | | |
1000 | 15 | { &hf_evs_bit_rate_mode_0, |
1001 | 15 | { "EVS mode and bit rate", "evs.bit_rate_mode_0", |
1002 | 15 | FT_UINT8, BASE_DEC, VALS(evs_bit_rate_mode_0_values), 0x0f, |
1003 | 15 | NULL, HFILL } |
1004 | 15 | }, |
1005 | 15 | { &hf_evs_bit_rate_mode_1, |
1006 | 15 | { "EVS mode and bit rate", "evs.bit_rate_mode_1", |
1007 | 15 | FT_UINT8, BASE_DEC, VALS(evs_bit_rate_mode_1_values), 0x0f, |
1008 | 15 | NULL, HFILL } |
1009 | 15 | }, |
1010 | 15 | { &hf_evs_f_bit, |
1011 | 15 | { "F", "evs.f_bit", |
1012 | 15 | FT_BOOLEAN, 8, TFS(&tfs_evs_f_bit), 0x40, |
1013 | 15 | NULL, HFILL } |
1014 | 15 | }, |
1015 | 15 | { &hf_evs_cmr_amr_io, |
1016 | 15 | { "CMR", "evs.cmr_amr_io", |
1017 | 15 | FT_UINT8, BASE_DEC, VALS(evs_cmr_amr_io_values), 0xe0, |
1018 | 15 | NULL, HFILL } |
1019 | 15 | }, |
1020 | 15 | { &hf_evs_bw, |
1021 | 15 | { "BW", "evs.bw", |
1022 | 15 | FT_UINT8, BASE_DEC, VALS(evs_bw_values), 0x0, |
1023 | 15 | NULL, HFILL } |
1024 | 15 | }, |
1025 | 15 | { &hf_evs_reserved_1bit, |
1026 | 15 | { "Reserved", "evs.reserved_1bit", |
1027 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1028 | 15 | NULL, HFILL } |
1029 | 15 | }, |
1030 | 15 | { &hf_evs_celp_switch_to_mdct_core, |
1031 | 15 | { "CELP->HQ-MDCT core", "evs.celp_switch_to_mdct_core", |
1032 | 15 | FT_UINT8, BASE_DEC, VALS(evs_celp_switch_to_mdct_core_values), 0x0, |
1033 | 15 | NULL, HFILL } |
1034 | 15 | }, |
1035 | 15 | { &hf_evs_celp_mdct_core, |
1036 | 15 | { "CELP/MDCT core", "evs.celp_mdct_core", |
1037 | 15 | FT_UINT8, BASE_DEC, VALS(evs_celp_or_mdct_core_values), 0x0, |
1038 | 15 | NULL, HFILL } |
1039 | 15 | }, |
1040 | 15 | { &hf_evs_tcx_or_hq_mdct_core, |
1041 | 15 | { "TCX/HQ-MDCT core", "evs.tcx_hq_mdct_core", |
1042 | 15 | FT_UINT8, BASE_DEC, VALS(evs_tcx_or_hq_mdct_core_values), 0x0, |
1043 | 15 | NULL, HFILL } |
1044 | 15 | }, |
1045 | 15 | { &hf_evs_sid_cng, |
1046 | 15 | { "CNG type", "evs.sid.cng", |
1047 | 15 | FT_UINT8, BASE_DEC, VALS(evs_sid_cng_values), 0x0, |
1048 | 15 | NULL, HFILL } |
1049 | 15 | }, |
1050 | 15 | { &hf_evs_celp_sample_rate, |
1051 | 15 | { "CELP Sample Rate", "evs.sid.celp_sample_rate", |
1052 | 15 | FT_UINT8, BASE_DEC, VALS(evs_sid_celp_sample_rate_values), 0x0, |
1053 | 15 | NULL, HFILL } |
1054 | 15 | }, |
1055 | 15 | { &hf_evs_core_sample_rate, |
1056 | 15 | { "Core sampling rate indicator", "evs.sid.core_sample_rate", |
1057 | 15 | FT_UINT8, BASE_DEC, VALS(evs_sid_celp_sample_rate_values), 0x0, |
1058 | 15 | NULL, HFILL } |
1059 | 15 | }, |
1060 | 15 | { &hf_evs_132_bwctrf_idx, |
1061 | 15 | { "BW CT RF Index", "evs.132.bwctrf_idx", |
1062 | 15 | FT_UINT8, BASE_DEC, VALS(evs_132_bwctrf_idx_vals), 0x0, |
1063 | 15 | NULL, HFILL } |
1064 | 15 | }, |
1065 | 15 | { &hf_evs_28_frame_type, |
1066 | 15 | { "Frame type", "evs.28.frame_type", |
1067 | 15 | FT_UINT8, BASE_DEC, VALS(evs_28_frame_type_vals), 0x0, |
1068 | 15 | NULL, HFILL } |
1069 | 15 | }, |
1070 | 15 | { &hf_evs_28_bw_ppp_nelp, |
1071 | 15 | { "BW PPP/NELP", "evs.28.bw_ppp_nelp", |
1072 | 15 | FT_UINT8, BASE_DEC, VALS(evs_28_bw_ppp_nelp_vals), 0x0, |
1073 | 15 | NULL, HFILL } |
1074 | 15 | }, |
1075 | 15 | { &hf_evs_72_80_bwct_idx, |
1076 | 15 | { "BW CT Index", "evs.72.80.bwct_idx", |
1077 | 15 | FT_UINT8, BASE_DEC, VALS(evs_72_80_bwct_idx_vals), 0x0, |
1078 | 15 | NULL, HFILL } |
1079 | 15 | }, |
1080 | 15 | { &hf_evs_320_bwct_idx, |
1081 | 15 | { "BW CT Index", "evs.320.bwct_idx", |
1082 | 15 | FT_UINT8, BASE_DEC, VALS(evs_320_bwct_idx_vals), 0x0, |
1083 | 15 | NULL, HFILL } |
1084 | 15 | }, |
1085 | 15 | { &hf_evs_640_bwct_idx, |
1086 | 15 | { "BW CT Index", "evs.640.bwct_idx", |
1087 | 15 | FT_UINT8, BASE_DEC, VALS(evs_640_bwct_idx_vals), 0x0, |
1088 | 15 | NULL, HFILL } |
1089 | 15 | }, |
1090 | 15 | }; |
1091 | | |
1092 | | |
1093 | | /* Setup protocol subtree array */ |
1094 | 15 | static int *ett[] = { |
1095 | 15 | &ett_evs, |
1096 | 15 | &ett_evs_header, |
1097 | 15 | &ett_evs_speech, |
1098 | 15 | &ett_evs_voice_data, |
1099 | 15 | }; |
1100 | | |
1101 | | |
1102 | | /* Register the protocol name and description */ |
1103 | 15 | proto_evs = proto_register_protocol("Enhanced Voice Services", "EVS", "evs"); |
1104 | | |
1105 | | /* Required function calls to register the header fields and subtrees used */ |
1106 | 15 | proto_register_field_array(proto_evs, hf, array_length(hf)); |
1107 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
1108 | | |
1109 | 15 | evs_module = prefs_register_protocol(proto_evs, NULL); |
1110 | | |
1111 | 15 | prefs_register_obsolete_preference(evs_module, "dynamic.payload.type"); |
1112 | 15 | prefs_register_bool_preference(evs_module, "hf_only", |
1113 | 15 | "Header-Full format only", |
1114 | 15 | "Decode payload assuming that Header-Full format only is used", |
1115 | 15 | &evs_hf_only); |
1116 | | |
1117 | 15 | evs_handle = register_dissector("evs", dissect_evs, proto_evs); |
1118 | 15 | } |
1119 | | |
1120 | | void |
1121 | | proto_reg_handoff_evs(void) |
1122 | 15 | { |
1123 | 15 | dissector_add_string("rtp_dyn_payload_type", "EVS", evs_handle); |
1124 | 15 | dissector_add_uint_range_with_preference("rtp.pt", "", evs_handle); |
1125 | 15 | proto_rtp = proto_get_id_by_filter_name("rtp"); |
1126 | 15 | } |
1127 | | |
1128 | | /* |
1129 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1130 | | * |
1131 | | * Local variables: |
1132 | | * c-basic-offset: 4 |
1133 | | * tab-width: 8 |
1134 | | * indent-tabs-mode: nil |
1135 | | * End: |
1136 | | * |
1137 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
1138 | | * :indentSize=4:tabSize=8:noTabs=true: |
1139 | | */ |
1140 | | |