Coverage Report

Created: 2026-07-12 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-evrc.c
Line
Count
Source
1
/* packet-evrc.c
2
 * Routines for:
3
 *      EVRC EVRC-B EVRC-WB EVRC-NW EVRC-NW2K
4
 * RTP payload header dissection
5
 *
6
 * Copyright 2008, Michael Lum <michael.lum [AT] shaw.ca>
7
 * In association with Star Solutions
8
 *
9
 * Title                3GPP2                   Other
10
 *
11
 *   Enhanced Variable Rate Codec, Speech Service Options 3, 68, 70, 73 and 77
12
 *   for Wideband Spread Spectrum Digital Systems
13
 *                      3GPP2 C.S0014-E v1.0      TIA-127-?
14
 *
15
 * RFC 3558  https://tools.ietf.org/html/rfc3558
16
 * RFC 4788  https://tools.ietf.org/html/rfc4788
17
 * RFC 5188  https://tools.ietf.org/html/rfc5188
18
 * draft-agupta-payload-rtp-evrc-nw2k-00
19
 *
20
 * Wireshark - Network traffic analyzer
21
 * By Gerald Combs <gerald@wireshark.org>
22
 * Copyright 1998 Gerald Combs
23
 *
24
 * SPDX-License-Identifier: GPL-2.0-or-later
25
 */
26
27
#include "config.h"
28
29
#include <epan/packet.h>
30
#include <epan/prefs.h>
31
#include <epan/expert.h>
32
#include <epan/tfs.h>
33
34
#include <wsutil/str_util.h>
35
36
/* PROTOTYPES/FORWARDS */
37
38
void proto_register_evrc(void);
39
void proto_reg_handoff_evrc(void);
40
41
static dissector_handle_t evrc_handle;
42
static dissector_handle_t evrcb_handle;
43
static dissector_handle_t evrcwb_handle;
44
static dissector_handle_t evrcnw_handle;
45
static dissector_handle_t evrcnw2k_handle;
46
static dissector_handle_t evrc_legacy_handle;
47
48
static const value_string evrc_frame_type_vals[] = {
49
    { 0,        "Blank (0 bits)" },
50
    { 1,        "1/8 Rate (16 bits)" },
51
    { 2,        "Not valid (1/4 Rate : 40 bits)" },
52
    { 3,        "1/2 Rate (80 bits)" },
53
    { 4,        "Full Rate (171 bits; + 5 bits padding)" },
54
    { 5,        "Erasure (0 bits)" },
55
    { 0,        NULL }
56
};
57
58
static const value_string evrc_b_frame_type_vals[] = {
59
    { 0,        "Blank (0 bits)" },
60
    { 1,        "1/8 Rate (16 bits)" },
61
    { 2,        "1/4 Rate (40 bits)" },
62
    { 3,        "1/2 Rate (80 bits)" },
63
    { 4,        "Full Rate (171 bits; + 5 bits padding)" },
64
    { 5,        "Erasure (0 bits)" },
65
    { 0,        NULL }
66
};
67
68
static const value_string evrc_legacy_frame_type_vals[] = {
69
    { 0,        "Blank (0 bits)" },
70
    { 1,        "1/8 Rate (16 bits)" },
71
    { 3,        "1/2 Rate (80 bits)" },
72
    { 4,        "Full Rate (171 bits; + 5 bits padding)" },
73
    { 14,       "Erasure (0 bits)" },
74
    { 0,        NULL }
75
};
76
77
static const value_string evrc_mode_request_vals[] = {
78
    { 0,        "Rate Reduction 0 (Full Rate)" },
79
    { 1,        "Rate Reduction 1" },
80
    { 2,        "Rate Reduction 2" },
81
    { 3,        "Rate Reduction 3" },
82
    { 4,        "Rate Reduction 4" },
83
    { 0,        NULL }
84
};
85
86
static const value_string evrc_b_mode_request_vals[] = {
87
    { 0,        "Encoder Operating Point 0 (Full Rate)" },
88
    { 1,        "Encoder Operating Point 1" },
89
    { 2,        "Encoder Operating Point 2" },
90
    { 3,        "Encoder Operating Point 3" },
91
    { 4,        "Encoder Operating Point 4" },
92
    { 5,        "Encoder Operating Point 5" },
93
    { 6,        "Encoder Operating Point 6" },
94
    { 7,        "Encoder Operating Point 7 (1/2 rate max)" },
95
    { 0,        NULL }
96
};
97
98
static const value_string evrc_wb_mode_request_vals[] = {
99
    { 0,        "Encoder Operating Point 0 (Full Rate)" },
100
    { 1,        "Reserved" },
101
    { 2,        "Reserved" },
102
    { 3,        "Reserved" },
103
    { 4,        "Encoder Operating Point 4" },
104
    { 5,        "Reserved" },
105
    { 6,        "Reserved" },
106
    { 7,        "Encoder Operating Point 7 (1/2 rate max)" },
107
    { 0,        NULL }
108
};
109
110
static const value_string evrc_nw_mode_request_vals[] = {
111
    { 0,        "Encoder Operating Point 0 (EVRC-WB COP0)" },
112
    { 1,        "Encoder Operating Point 1 (EVRC-B COP0/EVRC-WB COP4)" },
113
    { 2,        "Encoder Operating Point 2 (EVRC-B COP2)" },
114
    { 3,        "Encoder Operating Point 3 (EVRC-B COP3)" },
115
    { 4,        "Encoder Operating Point 4 (EVRC-B COP4)" },
116
    { 5,        "Encoder Operating Point 5 (EVRC-B COP5)" },
117
    { 6,        "Encoder Operating Point 6 (EVRC-B COP6)" },
118
    { 7,        "Encoder Operating Point 7 (EVRC-B COP7/EVRC-WB COP7)" },
119
    { 0,        NULL }
120
};
121
122
static const value_string evrc_nw2k_mode_request_vals[] = {
123
    { 0,        "Encoder Operating Point 0 (EVRC-WB COP0)" },
124
    { 1,        "Encoder Operating Point 1 (EVRC-B COP0/EVRC-WB COP4)" },
125
    { 2,        "Encoder Operating Point 2 (EVRC-B COP2)" },
126
    { 3,        "Encoder Operating Point 3 (EVRC-B COP3/EVRC-NW2k)" },
127
    { 4,        "Encoder Operating Point 4 (EVRC-B COP4)" },
128
    { 5,        "Encoder Operating Point 5 (EVRC-B COP5)" },
129
    { 6,        "Encoder Operating Point 6 (EVRC-B COP6)" },
130
    { 7,        "Encoder Operating Point 7 (EVRC-B COP7/EVRC-WB COP7)" },
131
    { 0,        NULL }
132
};
133
134
static const true_false_string toc_further_entries_bit_vals = {
135
  "More ToC entries follow",
136
  "End of ToC entries"
137
};
138
139
static const true_false_string evrc_nw2k_enc_capability_bit_vals = {
140
  "Mode-0 wideband encoding capable",
141
  "Mode-0 wideband encoding incapable (i.e. narrowband encoding only)"
142
};
143
144
typedef enum
145
{
146
    EVRC_VARIANT_EVRC,
147
    EVRC_VARIANT_EVRC_B,
148
    EVRC_VARIANT_EVRC_WB,
149
    EVRC_VARIANT_EVRC_NW,
150
    EVRC_VARIANT_EVRC_NW2k,
151
    EVRC_VARIANT_EVRC_LEGACY
152
}
153
evrc_variant_t;
154
155
156
/* Initialize the protocol and registered fields */
157
static int proto_evrc;
158
static int proto_evrcb;
159
static int proto_evrcwb;
160
static int proto_evrcnw;
161
static int proto_evrcnw2k;
162
static int proto_evrc_legacy;
163
164
static int hf_evrc_reserved;
165
static int hf_evrc_reserved_2k;
166
static int hf_evrc_enc_capability_2k;
167
static int hf_evrc_interleave_length;
168
static int hf_evrc_interleave_index;
169
static int hf_evrc_mode_request;
170
static int hf_evrc_b_mode_request;
171
static int hf_evrc_wb_mode_request;
172
static int hf_evrc_nw_mode_request;
173
static int hf_evrc_nw2k_mode_request;
174
static int hf_evrc_frame_count;
175
static int hf_evrc_toc_frame_type_high;
176
static int hf_evrc_toc_frame_type_low;
177
static int hf_evrc_b_toc_frame_type_high;
178
static int hf_evrc_b_toc_frame_type_low;
179
static int hf_evrc_padding;
180
static int hf_evrc_speech_data;
181
static int hf_evrc_legacy_toc_fe_ind;
182
static int hf_evrc_legacy_toc_reduc_rate;
183
static int hf_evrc_legacy_toc_frame_type;
184
185
/* Initialize the subtree pointers */
186
static int ett_evrc;
187
static int ett_toc;
188
189
static expert_field ei_evrc_unknown_variant;
190
191
/*
192
 * Variables to allow for proper deletion of dissector registration when
193
 * the user changes values
194
 */
195
static bool legacy_pt_60;
196
197
198
static uint8_t
199
evrc_frame_type_to_octs(uint8_t frame_type)
200
0
{
201
0
    switch (frame_type)
202
0
    {
203
0
    default:
204
0
        break;
205
206
0
    case 1:     /* 1/8 rate */
207
0
        return 2;
208
209
0
    case 2:     /* 1/4 rate */
210
0
        return 5;
211
212
0
    case 3:     /* 1/2 rate */
213
0
        return 10;
214
215
0
    case 4:     /* full rate */
216
0
        return 22;
217
0
    }
218
219
0
    return 0;
220
0
}
221
222
/* GENERIC EVRC DISSECTOR FUNCTIONS */
223
224
static void
225
dissect_evrc_aux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, evrc_variant_t evrc_variant)
226
0
{
227
0
    uint8_t                     oct;
228
0
    uint8_t                     frame_count;
229
0
    uint8_t                     i;
230
0
    uint32_t                    offset, saved_offset;
231
0
    bool                        further_entries;
232
0
    uint32_t                    len;
233
0
    proto_item                  *item = NULL;
234
0
    proto_tree                  *evrc_tree = NULL;
235
0
    proto_tree                  *toc_tree = NULL;
236
0
    int                         hf_mode_request;
237
0
    int                         hf_toc_frame_type_high;
238
0
    int                         hf_toc_frame_type_low;
239
240
    /*
241
     * assumed max number of speech frames based on
242
     * frame count being 5 bits + 1
243
     */
244
0
    uint8_t                     speech_data_len[0x20];
245
246
247
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "EVRC");
248
249
0
    if (!tree) return;
250
251
0
    offset = 0;
252
0
    memset(speech_data_len, 0, sizeof(speech_data_len));
253
254
0
    len = tvb_reported_length(tvb);
255
256
0
    item = proto_tree_add_item(tree, proto_evrc, tvb, 0, len, ENC_NA);
257
258
0
    evrc_tree = proto_item_add_subtree(item, ett_evrc);
259
260
0
    if (evrc_variant == EVRC_VARIANT_EVRC_LEGACY)
261
0
    {
262
        /* legacy 'payload type 60' draft-ietf-avt-evrc-07.txt header format */
263
264
0
        proto_tree_add_item(evrc_tree, hf_evrc_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
265
0
        proto_tree_add_item(evrc_tree, hf_evrc_interleave_length, tvb, offset, 1, ENC_BIG_ENDIAN);
266
0
        proto_tree_add_item(evrc_tree, hf_evrc_interleave_index, tvb, offset, 1, ENC_BIG_ENDIAN);
267
268
0
        offset++;
269
270
0
        frame_count = 0;
271
0
        further_entries = true;
272
0
        while (further_entries && (frame_count < sizeof(speech_data_len)) &&
273
0
            ((len - offset) > 0))
274
0
        {
275
0
            toc_tree =
276
0
                proto_tree_add_subtree_format(evrc_tree, tvb, offset, 1, ett_toc, NULL, "ToC [%u]", frame_count+1);
277
278
0
            proto_tree_add_item(toc_tree, hf_evrc_legacy_toc_fe_ind, tvb, offset, 1, ENC_BIG_ENDIAN);
279
0
            proto_tree_add_item(toc_tree, hf_evrc_legacy_toc_reduc_rate, tvb, offset, 1, ENC_BIG_ENDIAN);
280
0
            proto_tree_add_item(toc_tree, hf_evrc_legacy_toc_frame_type, tvb, offset, 1, ENC_BIG_ENDIAN);
281
282
0
            oct = tvb_get_uint8(tvb, offset);
283
0
            further_entries = (oct & 0x80) ? true : false;
284
285
0
            speech_data_len[frame_count] = evrc_frame_type_to_octs((uint8_t)(oct & 0x7f));
286
287
0
            frame_count++;
288
0
            offset++;
289
0
        }
290
0
    }
291
0
    else
292
0
    {
293
        /* RFC 3558 header format */
294
295
0
        switch (evrc_variant)
296
0
        {
297
0
        default:
298
0
            proto_tree_add_expert(evrc_tree, pinfo, &ei_evrc_unknown_variant, tvb, offset, len);
299
0
            return;
300
301
0
        case EVRC_VARIANT_EVRC:
302
0
            hf_mode_request = hf_evrc_mode_request;
303
0
            hf_toc_frame_type_high = hf_evrc_toc_frame_type_high;
304
0
            hf_toc_frame_type_low = hf_evrc_toc_frame_type_low;
305
306
0
            proto_tree_add_item(evrc_tree, hf_evrc_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
307
0
            break;
308
309
0
        case EVRC_VARIANT_EVRC_B:
310
0
            hf_mode_request = hf_evrc_b_mode_request;
311
0
            hf_toc_frame_type_high = hf_evrc_b_toc_frame_type_high;
312
0
            hf_toc_frame_type_low = hf_evrc_b_toc_frame_type_low;
313
314
0
            proto_tree_add_item(evrc_tree, hf_evrc_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
315
0
            break;
316
317
0
        case EVRC_VARIANT_EVRC_WB:
318
0
            hf_mode_request = hf_evrc_wb_mode_request;
319
0
            hf_toc_frame_type_high = hf_evrc_b_toc_frame_type_high;
320
0
            hf_toc_frame_type_low = hf_evrc_b_toc_frame_type_low;
321
322
0
            proto_tree_add_item(evrc_tree, hf_evrc_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
323
0
            break;
324
325
0
        case EVRC_VARIANT_EVRC_NW:
326
0
            hf_mode_request = hf_evrc_nw_mode_request;
327
0
            hf_toc_frame_type_high = hf_evrc_b_toc_frame_type_high;
328
0
            hf_toc_frame_type_low = hf_evrc_b_toc_frame_type_low;
329
330
0
            proto_tree_add_item(evrc_tree, hf_evrc_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
331
0
            break;
332
333
0
        case EVRC_VARIANT_EVRC_NW2k:
334
0
            hf_mode_request = hf_evrc_nw2k_mode_request;
335
0
            hf_toc_frame_type_high = hf_evrc_b_toc_frame_type_high;
336
0
            hf_toc_frame_type_low = hf_evrc_b_toc_frame_type_low;
337
338
0
            proto_tree_add_item(evrc_tree, hf_evrc_reserved_2k, tvb, offset, 1, ENC_BIG_ENDIAN);
339
0
            proto_tree_add_item(evrc_tree, hf_evrc_enc_capability_2k, tvb, offset, 1, ENC_BIG_ENDIAN);
340
0
            break;
341
0
        }
342
343
0
        proto_tree_add_item(evrc_tree, hf_evrc_interleave_length, tvb, offset, 1, ENC_BIG_ENDIAN);
344
0
        proto_tree_add_item(evrc_tree, hf_evrc_interleave_index, tvb, offset, 1, ENC_BIG_ENDIAN);
345
346
0
        offset++;
347
348
0
        proto_tree_add_item(evrc_tree, hf_mode_request, tvb, offset, 1, ENC_BIG_ENDIAN);
349
0
        proto_tree_add_item_ret_uint8(evrc_tree, hf_evrc_frame_count, tvb, offset, 1, ENC_BIG_ENDIAN, &frame_count);
350
351
        /*
352
         * number of frames in PACKET is frame_count + 1
353
         */
354
0
        frame_count++;
355
356
0
        offset++;
357
0
        saved_offset = offset;
358
359
0
        toc_tree =
360
0
            proto_tree_add_subtree_format(evrc_tree, tvb, offset, -1, ett_toc, &item, "ToC - %u frame%s",
361
0
                frame_count, plurality(frame_count, "", "s"));
362
363
0
        i = 0;
364
0
        while ((i < frame_count) &&
365
0
            ((len - offset) > 0))
366
0
        {
367
0
            oct = tvb_get_uint8(tvb, offset);
368
369
0
            proto_tree_add_item(toc_tree, hf_toc_frame_type_high, tvb, offset, 1, ENC_BIG_ENDIAN);
370
371
0
            speech_data_len[i] = evrc_frame_type_to_octs((uint8_t)((oct & 0xf0) >> 4));
372
373
0
            i++;
374
375
0
            if (i < frame_count)
376
0
            {
377
                /* even number of frames */
378
0
                proto_tree_add_item(toc_tree, hf_toc_frame_type_low, tvb, offset, 1, ENC_BIG_ENDIAN);
379
380
0
                speech_data_len[i] = evrc_frame_type_to_octs((uint8_t)(oct & 0x0f));
381
382
0
                i++;
383
0
            }
384
385
0
            offset++;
386
0
        }
387
388
0
        if (frame_count & 0x01)
389
0
        {
390
            /* odd number of frames */
391
0
            proto_tree_add_item(toc_tree, hf_evrc_padding, tvb, offset-1, 1, ENC_BIG_ENDIAN);
392
0
        }
393
394
0
        proto_item_set_len(item, offset - saved_offset);
395
0
    }
396
397
0
    i = 0;
398
0
    while ((i < frame_count) &&
399
0
        ((len - offset) >= speech_data_len[i]))
400
0
    {
401
0
        proto_tree_add_bytes_format(evrc_tree, hf_evrc_speech_data, tvb, offset, speech_data_len[i], NULL, "Speech Data [%u]", i+1);
402
403
0
        offset += speech_data_len[i];
404
0
        i++;
405
0
    }
406
0
}
407
408
static int
409
dissect_evrc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
410
0
{
411
0
    dissect_evrc_aux(tvb, pinfo, tree, EVRC_VARIANT_EVRC);
412
0
    return tvb_captured_length(tvb);
413
0
}
414
415
static int
416
dissect_evrcb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
417
0
{
418
0
    dissect_evrc_aux(tvb, pinfo, tree, EVRC_VARIANT_EVRC_B);
419
0
    return tvb_captured_length(tvb);
420
0
}
421
422
static int
423
dissect_evrcwb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
424
0
{
425
0
    dissect_evrc_aux(tvb, pinfo, tree, EVRC_VARIANT_EVRC_WB);
426
0
    return tvb_captured_length(tvb);
427
0
}
428
429
static int
430
dissect_evrcnw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
431
0
{
432
0
    dissect_evrc_aux(tvb, pinfo, tree, EVRC_VARIANT_EVRC_NW);
433
0
    return tvb_captured_length(tvb);
434
0
}
435
436
static int
437
dissect_evrcnw2k(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
438
0
{
439
0
    dissect_evrc_aux(tvb, pinfo, tree, EVRC_VARIANT_EVRC_NW2k);
440
0
    return tvb_captured_length(tvb);
441
0
}
442
443
static int
444
dissect_evrc_legacy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
445
0
{
446
0
    dissect_evrc_aux(tvb, pinfo, tree, EVRC_VARIANT_EVRC_LEGACY);
447
0
    return tvb_captured_length(tvb);
448
0
}
449
450
451
/* Register the protocol with Wireshark */
452
void
453
proto_register_evrc(void)
454
15
{
455
15
    module_t            *evrc_module;
456
457
    /* Setup list of header fields */
458
459
15
    static hf_register_info hf[] =
460
15
    {
461
15
        { &hf_evrc_reserved,
462
15
            { "Reserved",               "evrc.reserved",
463
15
            FT_UINT8, BASE_HEX, NULL, 0xc0,
464
15
            "Reserved bits", HFILL }
465
15
        },
466
15
        { &hf_evrc_reserved_2k,
467
15
            { "Reserved",               "evrc.reserved",
468
15
            FT_UINT8, BASE_HEX, NULL, 0x80,
469
15
            "Reserved bits", HFILL }
470
15
        },
471
15
        { &hf_evrc_enc_capability_2k,
472
15
            { "Encoding Capability",               "evrc.enc_capability",
473
15
            FT_BOOLEAN, 8, TFS(&evrc_nw2k_enc_capability_bit_vals), 0x40,
474
15
            "Encoding Capability Identification", HFILL }
475
15
        },
476
15
        { &hf_evrc_interleave_length,
477
15
            { "Interleave Length",      "evrc.interleave_len",
478
15
            FT_UINT8, BASE_DEC, NULL, 0x38,
479
15
            "Interleave length bits", HFILL }
480
15
        },
481
15
        { &hf_evrc_interleave_index,
482
15
            { "Interleave Index",       "evrc.interleave_idx",
483
15
            FT_UINT8, BASE_DEC, NULL, 0x07,
484
15
            "Interleave index bits", HFILL }
485
15
        },
486
15
        { &hf_evrc_mode_request,
487
15
            { "Mode Request",           "evrc.mode_request",
488
15
            FT_UINT8, BASE_DEC, VALS(evrc_mode_request_vals), 0xe0,
489
15
            "Mode Request bits", HFILL }
490
15
        },
491
15
        { &hf_evrc_b_mode_request,
492
15
            { "Mode Request",           "evrc.b.mode_request",
493
15
            FT_UINT8, BASE_DEC, VALS(evrc_b_mode_request_vals), 0xe0,
494
15
            "Mode Request bits", HFILL }
495
15
        },
496
15
        { &hf_evrc_wb_mode_request,
497
15
            { "Mode Request",           "evrc.wb.mode_request",
498
15
            FT_UINT8, BASE_DEC, VALS(evrc_wb_mode_request_vals), 0xe0,
499
15
            "Mode Request bits", HFILL }
500
15
        },
501
15
        { &hf_evrc_nw_mode_request,
502
15
            { "Mode Request",           "evrc.nw.mode_request",
503
15
            FT_UINT8, BASE_DEC, VALS(evrc_nw_mode_request_vals), 0xe0,
504
15
            "Mode Request bits", HFILL }
505
15
        },
506
15
        { &hf_evrc_nw2k_mode_request,
507
15
            { "Mode Request",           "evrc.nw2k.mode_request",
508
15
            FT_UINT8, BASE_DEC, VALS(evrc_nw2k_mode_request_vals), 0xe0,
509
15
            "Mode Request bits", HFILL }
510
15
        },
511
15
        { &hf_evrc_frame_count,
512
15
            { "Frame Count (0 means 1 frame)",  "evrc.frame_count",
513
15
            FT_UINT8, BASE_DEC, NULL, 0x1f,
514
15
            "Frame Count bits, a value of 0 means 1 frame", HFILL }
515
15
        },
516
15
        { &hf_evrc_toc_frame_type_high,
517
15
            { "ToC Frame Type",         "evrc.toc.frame_type_hi",
518
15
            FT_UINT8, BASE_DEC, VALS(evrc_frame_type_vals), 0xf0,
519
15
            "ToC Frame Type bits", HFILL }
520
15
        },
521
15
        { &hf_evrc_toc_frame_type_low,
522
15
            { "ToC Frame Type",         "evrc.toc.frame_type_lo",
523
15
            FT_UINT8, BASE_DEC, VALS(evrc_frame_type_vals), 0x0f,
524
15
            "ToC Frame Type bits", HFILL }
525
15
        },
526
15
        { &hf_evrc_b_toc_frame_type_high,
527
15
            { "ToC Frame Type",         "evrc.b.toc.frame_type_hi",
528
15
            FT_UINT8, BASE_DEC, VALS(evrc_b_frame_type_vals), 0xf0,
529
15
            "ToC Frame Type bits", HFILL }
530
15
        },
531
15
        { &hf_evrc_b_toc_frame_type_low,
532
15
            { "ToC Frame Type",         "evrc.b.toc.frame_type_lo",
533
15
            FT_UINT8, BASE_DEC, VALS(evrc_b_frame_type_vals), 0x0f,
534
15
            "ToC Frame Type bits", HFILL }
535
15
        },
536
15
        { &hf_evrc_padding,
537
15
            { "Padding",                "evrc.padding",
538
15
            FT_UINT8, BASE_DEC, NULL, 0x0f,
539
15
            "Padding bits", HFILL }
540
15
        },
541
15
        { &hf_evrc_speech_data,
542
15
            { "Speech data",                "evrc.speech_data",
543
15
            FT_BYTES, BASE_NONE, NULL, 0x0,
544
15
            NULL, HFILL }
545
15
        },
546
15
        { &hf_evrc_legacy_toc_fe_ind,
547
15
            { "ToC Further Entries Indicator",  "evrc.legacy.toc.further_entries_ind",
548
15
            FT_BOOLEAN, 8, TFS(&toc_further_entries_bit_vals), 0x80,
549
15
            "ToC Further Entries Indicator bit", HFILL }
550
15
        },
551
15
        { &hf_evrc_legacy_toc_reduc_rate,
552
15
            { "ToC Reduced Rate",       "evrc.legacy.toc.reduced_rate",
553
15
            FT_UINT8, BASE_DEC, NULL, 0x40,
554
15
            "ToC Reduced Rate bits", HFILL }
555
15
        },
556
15
        { &hf_evrc_legacy_toc_frame_type,
557
15
            { "ToC Frame Type",         "evrc.legacy.toc.frame_type",
558
15
            FT_UINT8, BASE_DEC, VALS(evrc_legacy_frame_type_vals), 0x3f,
559
15
            "ToC Frame Type bits", HFILL }
560
15
        }
561
15
    };
562
563
15
    static ei_register_info ei[] = {
564
15
        { &ei_evrc_unknown_variant,
565
15
            { "evrc.unknown_variant", PI_UNDECODED, PI_WARN,
566
15
            "Variant Unknown/Unsupported - dissector bug/later version spec (report to wireshark.org)",
567
15
            EXPFILL }
568
15
        }
569
15
    };
570
571
15
    expert_module_t     *expert_evrc;
572
573
    /* Setup protocol subtree array */
574
575
15
    static int *ett[] =
576
15
    {
577
15
        &ett_evrc,
578
15
        &ett_toc
579
15
    };
580
581
    /* Register the protocol name and description */
582
583
15
    proto_evrc =
584
15
        proto_register_protocol("Enhanced Variable Rate Codec", "EVRC", "evrc");
585
586
15
    proto_evrcb =
587
15
        proto_register_protocol_in_name_only("Enhanced Variable Rate Codec B",
588
15
        "EVRC-B", "evrcb", proto_evrc, FT_PROTOCOL);
589
15
    proto_evrcwb =
590
15
        proto_register_protocol_in_name_only("Enhanced Variable Rate Codec - Wideband",
591
15
        "EVRC-WB", "evrcwb", proto_evrc, FT_PROTOCOL);
592
15
    proto_evrcnw =
593
15
        proto_register_protocol_in_name_only("Enhanced Variable Rate Codec - Narrowband-Wideband",
594
15
        "EVRC-NW", "evrcnw", proto_evrc, FT_PROTOCOL);
595
15
    proto_evrcnw2k =
596
15
        proto_register_protocol_in_name_only("Enhanced Variable Rate Codec - Narrowband-Wideband plus 2kpbs",
597
15
        "EVRC-NW2K", "evrcnw2k", proto_evrc, FT_PROTOCOL);
598
15
    proto_evrc_legacy =
599
15
        proto_register_protocol_in_name_only("Enhanced Variable Rate Codec (Legacy Encapsulation)",
600
15
        "EVRC (Legacy)", "evrc_legacy", proto_evrc, FT_PROTOCOL);
601
15
    proto_register_field_array(proto_evrc, hf, array_length(hf));
602
603
15
    proto_register_subtree_array(ett, array_length(ett));
604
605
15
    evrc_handle        = register_dissector("evrc", dissect_evrc, proto_evrc);
606
15
    evrcb_handle       = register_dissector("evrcb", dissect_evrcb, proto_evrcb);
607
15
    evrcwb_handle      = register_dissector("evrcwb", dissect_evrcwb, proto_evrcwb);
608
15
    evrcnw_handle      = register_dissector("evrcnw", dissect_evrcnw, proto_evrcnw);
609
15
    evrcnw2k_handle    = register_dissector("evrcnw2k", dissect_evrcnw2k, proto_evrcnw2k);
610
15
    evrc_legacy_handle = register_dissector("evrc_legacy", dissect_evrc_legacy, proto_evrc_legacy);
611
612
15
    expert_evrc =
613
15
        expert_register_protocol(proto_evrc);
614
15
    expert_register_field_array(expert_evrc, ei, array_length(ei));
615
616
    /*
617
     * setup for preferences
618
     */
619
15
    evrc_module = prefs_register_protocol(proto_evrc, proto_reg_handoff_evrc);
620
621
15
    prefs_register_bool_preference(evrc_module,
622
15
        "legacy_pt_60",
623
15
        "Add dissector for static payload type 60 as legacy EVRC (non-RFC3558)",
624
15
        "Whether the EVRC dissector should process payload type 60 as legacy EVRC packets",
625
15
        &legacy_pt_60);
626
15
}
627
628
629
void
630
proto_reg_handoff_evrc(void)
631
15
{
632
15
    static bool                 evrc_prefs_initialized = false;
633
634
15
    if (!evrc_prefs_initialized)
635
15
    {
636
        /* header-full mime types */
637
15
        dissector_add_string("rtp_dyn_payload_type",  "EVRC", evrc_handle);
638
15
        dissector_add_string("rtp_dyn_payload_type",  "EVRCB", evrcb_handle);
639
15
        dissector_add_string("rtp_dyn_payload_type",  "EVRCWB", evrcwb_handle);
640
15
        dissector_add_string("rtp_dyn_payload_type",  "EVRCNW", evrcnw_handle);
641
15
        dissector_add_string("rtp_dyn_payload_type",  "EVRCNW2K", evrcnw2k_handle);
642
643
15
        dissector_add_for_decode_as("rtp.pt", evrc_handle);
644
15
        dissector_add_for_decode_as("rtp.pt", evrcb_handle);
645
15
        dissector_add_for_decode_as("rtp.pt", evrcwb_handle);
646
15
        dissector_add_for_decode_as("rtp.pt", evrcnw_handle);
647
15
        dissector_add_for_decode_as("rtp.pt", evrcnw2k_handle);
648
        /* Since the draft legacy encapsulation only appears on PT 60, not
649
         * adding it to decode as */
650
        /* dissector_add_for_decode_as("rtp.pt", evrc_legacy_handle); */
651
15
        evrc_prefs_initialized = true;
652
15
    }
653
0
    else
654
0
    {
655
0
        dissector_delete_uint("rtp.pt", 60, evrc_legacy_handle);
656
0
    }
657
658
15
    if (legacy_pt_60)
659
0
    {
660
0
        dissector_add_uint("rtp.pt", 60, evrc_legacy_handle);
661
0
    }
662
15
}
663
664
/*
665
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
666
 *
667
 * Local variables:
668
 * c-basic-offset: 4
669
 * tab-width: 8
670
 * indent-tabs-mode: nil
671
 * End:
672
 *
673
 * vi: set shiftwidth=4 tabstop=8 expandtab:
674
 * :indentSize=4:tabSize=8:noTabs=true:
675
 */