Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-amr.c
blob3bdc7476ba1cb83dc10143efef7a59e233840672
1 /* packet-amr.c
2 * Routines for AMR dissection
3 * Copyright 2005-2008, Anders Broman <anders.broman[at]ericsson.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
11 * References:
12 * RFC 3267 https://tools.ietf.org/html/rfc3267
13 * RFC 4867 https://tools.ietf.org/html/rfc4867
14 * 3GPP TS 26.101 for AMR-NB, 3GPP TS 26.201 for AMR-WB
17 #include "config.h"
19 #include <epan/packet.h>
20 #include <epan/expert.h>
21 #include <epan/oids.h>
22 #include <epan/asn1.h>
23 #include <epan/tfs.h>
25 #include "packet-rtp.h"
26 #include "packet-amr.h"
28 void proto_register_amr(void);
29 void proto_reg_handoff_amr(void);
31 #define AMR_NB_SID 8
32 #define AMR_WB_SID 9
33 #define AMR_NO_TRANS 15
35 #define AMR_NB 0
36 #define AMR_WB 1
38 #define AMR_OA 0
39 #define AMR_BE 1
40 #define AMR_IF1 2
41 #define AMR_IF2 3
43 static dissector_handle_t amr_handle;
44 static dissector_handle_t amr_wb_handle;
46 /* Initialize the protocol and registered fields */
47 static int proto_amr;
48 static int proto_amr_wb;
49 static int hf_amr_nb_cmr;
50 static int hf_amr_wb_cmr;
51 static int hf_amr_payload_decoded_as;
52 static int hf_amr_reserved;
53 static int hf_amr_toc_f;
54 static int hf_amr_nb_toc_ft;
55 static int hf_amr_wb_toc_ft;
56 static int hf_amr_toc_q;
58 static int hf_amr_speech_data;
59 static int hf_amr_frame_data;
60 static int hf_amr_nb_if1_ft;
61 static int hf_amr_wb_if1_ft;
62 static int hf_amr_if1_fqi;
63 static int hf_amr_nb_if1_mode_req;
64 static int hf_amr_wb_if1_mode_req;
65 static int hf_amr_if1_sti;
66 static int hf_amr_nb_if1_mode_ind;
67 static int hf_amr_wb_if1_mode_ind;
68 static int hf_amr_nb_if1_sti_mode_ind;
69 static int hf_amr_wb_if1_sti_mode_ind;
70 static int hf_amr_if2_sti;
71 static int hf_amr_nb_if2_sti_mode_ind;
72 static int hf_amr_wb_if2_sti_mode_ind;
74 static int hf_amr_nb_if2_ft;
75 static int hf_amr_wb_if2_ft;
78 /* Initialize the subtree pointers */
79 static int ett_amr;
80 static int ett_amr_toc;
82 static expert_field ei_amr_spare_bit_not0;
83 static expert_field ei_amr_not_enough_data_for_frames;
84 static expert_field ei_amr_superfluous_data;
85 static expert_field ei_amr_reserved_bits_not0;
86 static expert_field ei_amr_padding_bits_not0;
87 static expert_field ei_amr_padding_bits_correct;
88 static expert_field ei_amr_reserved;
90 static int amr_encoding_type = AMR_OA;
91 static int pref_amr_mode = AMR_NB;
93 static const value_string amr_encoding_type_value[] = {
94 {AMR_OA, "RFC 3267 octet-aligned mode"},
95 {AMR_BE, "RFC 3267 bandwidth-efficient mode"},
96 {AMR_IF1, "AMR IF 1"},
97 {AMR_IF2, "AMR IF 2"},
98 { 0, NULL }
102 /* Table 1a of 3GPP TS 26.201*/
103 static const value_string amr_nb_codec_mode_vals[] = {
104 {0, "AMR 4,75 kbit/s"},
105 {1, "AMR 5,15 kbit/s"},
106 {2, "AMR 5,90 kbit/s"},
107 {3, "AMR 6,70 kbit/s (PDC-EFR)"},
108 {4, "AMR 7,40 kbit/s (TDMA-EFR)"},
109 {5, "AMR 7,95 kbit/s"},
110 {6, "AMR 10,2 kbit/s"},
111 {7, "AMR 12,2 kbit/s (GSM-EFR)"},
112 {AMR_NB_SID, "AMR SID (Comfort Noise Frame)"},
113 {9, "GSM-EFR SID"},
114 {10, "TDMA-EFR SID "},
115 {11, "PDC-EFR SID"},
116 {12, "Illegal Frametype - for future use"},
117 {13, "Illegal Frametype - for future use"},
118 {14, "Illegal Frametype - for future use"},
119 {AMR_NO_TRANS, "No Data (No transmission/No reception)"},
120 { 0, NULL }
122 static value_string_ext amr_nb_codec_mode_vals_ext = VALUE_STRING_EXT_INIT(amr_nb_codec_mode_vals);
124 static const value_string amr_wb_codec_mode_vals[] = {
125 {0, "AMR-WB 6.60 kbit/s"},
126 {1, "AMR-WB 8.85 kbit/s"},
127 {2, "AMR-WB 12.65 kbit/s"},
128 {3, "AMR-WB 14.25 kbit/s"},
129 {4, "AMR-WB 15.85 kbit/s"},
130 {5, "AMR-WB 18.25 kbit/s"},
131 {6, "AMR-WB 19.85 kbit/s"},
132 {7, "AMR-WB 23.05 kbit/s"},
133 {8, "AMR-WB 23.85 kbit/s"},
134 {AMR_WB_SID, "AMR-WB SID (Comfort Noise Frame)"},
135 {10, "Illegal Frametype"},
136 {11, "Illegal Frametype"},
137 {12, "Illegal Frametype"},
138 {13, "Illegal Frametype"},
139 {14, "Speech lost"},
140 {AMR_NO_TRANS, "No Data (No transmission/No reception)"},
141 { 0, NULL }
144 static value_string_ext amr_wb_codec_mode_vals_ext = VALUE_STRING_EXT_INIT(amr_wb_codec_mode_vals);
146 /* Ref 3GPP TS 26.101 table 1a for AMR-NB*/
148 /* From RFC3267 chapter 4.3.1
149 CMR (4 bits): Indicates a codec mode request sent to the speech
150 encoder at the site of the receiver of this payload. The value of
151 the CMR field is set to the frame type index of the corresponding
152 speech mode being requested. The frame type index may be 0-7 for
153 AMR, as defined in Table 1a in [2], or 0-8 for AMR-WB, as defined
154 in Table 1a in [3GPP TS 26.201]. CMR value 15 indicates that no
155 mode request is present, and other values are for future use.
157 static const value_string amr_nb_codec_mode_request_vals[] = {
158 {0, "AMR 4,75 kbit/s"},
159 {1, "AMR 5,15 kbit/s"},
160 {2, "AMR 5,90 kbit/s"},
161 {3, "AMR 6,70 kbit/s (PDC-EFR)"},
162 {4, "AMR 7,40 kbit/s (TDMA-EFR)"},
163 {5, "AMR 7,95 kbit/s"},
164 {6, "AMR 10,2 kbit/s"},
165 {7, "AMR 12,2 kbit/s (GSM-EFR)"},
166 {8, "Illegal Frametype - For future use"},
167 {9, "Illegal Frametype - For future use"},
168 {10, "Illegal Frametype - For future use"},
169 {11, "Illegal Frametype - For future use"},
170 {12, "Illegal Frametype - For future use"},
171 {13, "Illegal Frametype - For future use"},
172 {14, "Illegal Frametype - For future use"},
173 {15, "No mode request"},
174 { 0, NULL }
176 static value_string_ext amr_nb_codec_mode_request_vals_ext = VALUE_STRING_EXT_INIT(amr_nb_codec_mode_request_vals);
178 /* Ref 3GPP TS 26.201 table 1a for AMR-WB*/
179 static const value_string amr_wb_codec_mode_request_vals[] = {
180 {0, "AMR-WB 6.60 kbit/s"},
181 {1, "AMR-WB 8.85 kbit/s"},
182 {2, "AMR-WB 12.65 kbit/s"},
183 {3, "AMR-WB 14.25 kbit/s"},
184 {4, "AMR-WB 15.85 kbit/s"},
185 {5, "AMR-WB 18.25 kbit/s"},
186 {6, "AMR-WB 19.85 kbit/s"},
187 {7, "AMR-WB 23.05 kbit/s"},
188 {8, "AMR-WB 23.85 kbit/s"},
189 {9, "Illegal Frametype - For future use"},
190 {10, "Illegal Frametype - For future use"},
191 {11, "Illegal Frametype - For future use"},
192 {12, "Illegal Frametype - For future use"},
193 {13, "Illegal Frametype - For future use"},
194 {14, "Illegal Frametype - For future use"},
195 {15, "No mode request"},
196 { 0, NULL }
198 static value_string_ext amr_wb_codec_mode_request_vals_ext = VALUE_STRING_EXT_INIT(amr_wb_codec_mode_request_vals);
200 static const true_false_string toc_f_bit_vals = {
201 "Followed by another speech frame",
202 "Last frame in this payload"
205 static const true_false_string toc_q_bit_vals = {
206 "Ok",
207 "Severely damaged frame"
210 static const true_false_string amr_sti_vals = {
211 "SID_UPDATE",
212 "SID_FIRST"
215 static wmem_map_t *amr_default_fmtp;
217 /* Number of bits per frame for AMR-NB, see Table 1 RFC3267*/
218 /* Values taken for GSM-EFR SID, TDMA-EFR SID and PDC-EFR SID from 3GPP 26.101 Table A.1b */
220 /* Frame type 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
221 static const uint8_t Framebits_NB[] = {95, 103, 118, 134, 148, 159, 204, 244, 39, 43, 38, 37, 0, 0, 0, 0};
223 /* Number of bits per frame for AMR-WB, see 3GPP TS 26.201 Table 2*/
224 /* Frame type 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
225 static const unsigned int Framebits_WB[] = {132, 177, 253, 285, 317, 365, 397, 461, 477, 40, 0, 0, 0, 0, 0, 0};
228 /** Return AMR narrowband Frame Type (FT) based on AMR speech data payload size.
229 * The input size is the size of an octet aligned payload without the
230 * CMR and TOC octets.
232 * @return AMR Frame Type (FT)
235 int amr_nb_bytes_to_ft(uint8_t bytes)
237 int ft;
239 for (ft = 0; ft < AMR_FT_PDC_EFR_SID; ft++) {
240 if ((Framebits_NB[ft] + 7) / 8 == bytes) {
241 return ft;
244 /* 12-14 not used, jump to 15 (AMR_FT_NO_DATA): */
245 if (Framebits_NB[AMR_FT_NO_DATA] == bytes) {
246 return AMR_FT_NO_DATA;
249 return -1;
252 static void
253 amr_apply_prefs(void) {
254 wmem_map_insert(amr_default_fmtp, "octet-align", (amr_encoding_type == AMR_OA) ? "1" : "0");
257 /* See 3GPP TS 26.101 chapter 4 for AMR-NB IF1 */
258 static int
259 dissect_amr_nb_if1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
260 int offset = 0;
261 uint8_t octet;
262 proto_item *ti;
264 proto_tree_add_item(tree, hf_amr_nb_if1_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
265 proto_tree_add_item(tree, hf_amr_if1_fqi, tvb, offset, 1, ENC_BIG_ENDIAN);
266 octet = (tvb_get_uint8(tvb,offset) & 0xf0) >> 4;
267 if (octet == AMR_NB_SID) {
268 ti = proto_tree_add_item(tree, hf_amr_nb_if1_mode_req, tvb, offset+1, 1, ENC_BIG_ENDIAN);
269 if (tvb_get_uint8(tvb,offset+1) & 0x1f)
270 expert_add_info(pinfo, ti, &ei_amr_spare_bit_not0);
271 proto_tree_add_item(tree, hf_amr_speech_data, tvb, offset+2, 5, ENC_NA);
272 proto_tree_add_item(tree, hf_amr_if1_sti, tvb, offset+7, 1, ENC_BIG_ENDIAN);
273 proto_tree_add_item(tree, hf_amr_nb_if1_sti_mode_ind, tvb, offset+7, 1, ENC_BIG_ENDIAN);
274 return offset+8;
277 proto_tree_add_item(tree, hf_amr_nb_if1_mode_ind, tvb, offset, 1, ENC_BIG_ENDIAN);
278 offset += 1;
279 ti = proto_tree_add_item(tree, hf_amr_nb_if1_mode_req, tvb, offset, 1, ENC_BIG_ENDIAN);
280 if (tvb_get_uint8(tvb,offset) & 0x1f)
281 expert_add_info(pinfo, ti, &ei_amr_spare_bit_not0);
282 offset += 1;
283 proto_tree_add_item(tree, hf_amr_speech_data, tvb, offset, -1, ENC_NA);
284 return tvb_captured_length(tvb);
287 /* See 3GPP TS 26.201 for AMR-WB */
288 static int
289 dissect_amr_wb_if1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
290 int offset = 0;
291 uint8_t octet;
292 proto_item *ti;
294 proto_tree_add_item(tree, hf_amr_wb_if1_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
295 ti = proto_tree_add_item(tree, hf_amr_if1_fqi, tvb, offset, 1, ENC_BIG_ENDIAN);
296 if (tvb_get_uint8(tvb,offset) & 0x03)
297 expert_add_info(pinfo, ti, &ei_amr_spare_bit_not0);
298 octet = (tvb_get_uint8(tvb,offset) & 0xf0) >> 4;
299 if (octet == AMR_WB_SID) {
300 proto_tree_add_item(tree, hf_amr_wb_if1_mode_req, tvb, offset+1, 1, ENC_BIG_ENDIAN);
301 proto_tree_add_item(tree, hf_amr_speech_data, tvb, offset+2, 4, ENC_NA);
302 proto_tree_add_item(tree, hf_amr_if1_sti, tvb, offset+7, 1, ENC_BIG_ENDIAN);
303 proto_tree_add_item(tree, hf_amr_wb_if1_sti_mode_ind, tvb, offset+7, 1, ENC_BIG_ENDIAN);
304 return offset+8;
307 offset += 1;
308 proto_tree_add_item(tree, hf_amr_wb_if1_mode_ind, tvb, offset, 1, ENC_BIG_ENDIAN);
309 proto_tree_add_item(tree, hf_amr_wb_if1_mode_req, tvb, offset, 1, ENC_BIG_ENDIAN);
310 offset += 1;
311 proto_tree_add_item(tree, hf_amr_speech_data, tvb, offset, -1, ENC_NA);
312 return tvb_captured_length(tvb);
315 static int
316 dissect_amr_nb_if2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
317 int offset = 0;
318 uint8_t octet;
320 proto_tree_add_item(tree, hf_amr_nb_if2_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
321 octet = tvb_get_uint8(tvb,offset) & 0x0f;
323 if (octet == AMR_NB_SID) {
324 proto_tree_add_item(tree, hf_amr_speech_data, tvb, offset+1, 3, ENC_NA);
325 proto_tree_add_item(tree, hf_amr_if2_sti, tvb, offset+4, 1, ENC_BIG_ENDIAN);
326 proto_tree_add_item(tree, hf_amr_nb_if2_sti_mode_ind, tvb, offset+5, 1, ENC_BIG_ENDIAN);
327 return offset+6;
329 if (octet == AMR_NO_TRANS)
330 return 1;
331 proto_tree_add_item(tree, hf_amr_speech_data, tvb, offset+1, -1, ENC_NA);
333 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
334 val_to_str_ext(octet, &amr_nb_codec_mode_request_vals_ext, "Unknown (%d)" ));
335 return tvb_captured_length(tvb);
338 static int
339 dissect_amr_wb_if2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
340 int offset = 0;
341 uint8_t octet;
343 proto_tree_add_item(tree, hf_amr_wb_if2_ft, tvb, offset, 1, ENC_BIG_ENDIAN);
344 octet = (tvb_get_uint8(tvb,offset) & 0xf0) >> 4;
346 if (octet == AMR_WB_SID) {
347 proto_tree_add_item(tree, hf_amr_speech_data, tvb, offset+1, 4, ENC_NA);
348 proto_tree_add_item(tree, hf_amr_if2_sti, tvb, offset+5, 1, ENC_BIG_ENDIAN);
349 proto_tree_add_item(tree, hf_amr_wb_if2_sti_mode_ind, tvb, offset+5, 1, ENC_BIG_ENDIAN);
350 return offset+6;
352 if (octet == AMR_NO_TRANS)
353 return 1;
354 proto_tree_add_item(tree, hf_amr_speech_data, tvb, offset+1, -1, ENC_NA);
356 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
357 val_to_str_ext(octet, &amr_wb_codec_mode_request_vals_ext, "Unknown (%d)" ));
358 return tvb_captured_length(tvb);
361 static void
362 dissect_amr_be(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int amr_mode) {
363 int ft;
364 int bit_offset = 0;
365 int bitcount; /*bitcounter, MSB = bit 0, over bytes*/
366 int bits_used_for_frames = 0;
367 int bytes_needed_for_frames;
368 uint8_t f_bit;
370 /* Chapter 4.3 */
372 bitcount = 3;
373 if (amr_mode == AMR_NB)
374 proto_tree_add_bits_item(tree, hf_amr_nb_cmr, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
375 else
376 proto_tree_add_bits_item(tree, hf_amr_wb_cmr, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
378 bit_offset += 4;
379 /* In bandwidth-efficient mode, a ToC entry takes the following format:
381 * 0 1 2 3 4 5
382 * +-+-+-+-+-+-+
383 * |F| FT |Q|
384 * +-+-+-+-+-+-+
386 * F (1 bit): If set to 1, indicates that this frame is followed by
387 * another speech frame in this payload; if set to 0, indicates that
388 * this frame is the last frame in this payload.
390 * FT (4 bits): Frame type index, indicating either the AMR or AMR-WB
391 * speech coding mode or comfort noise (SID) mode of the
392 * corresponding frame carried in this payload.
394 do {
395 /* Check F bit */
396 bitcount += 1;
397 f_bit = tvb_get_bits8(tvb, bit_offset, 1);
398 proto_tree_add_bits_item(tree, hf_amr_toc_f, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
399 bit_offset += 1;
400 /* Check FT bits */
401 ft = tvb_get_bits8(tvb, bit_offset, 4);
402 if (amr_mode == AMR_NB) {
403 proto_tree_add_bits_item(tree, hf_amr_nb_toc_ft, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
404 bits_used_for_frames += Framebits_NB[ft];
405 } else {
406 proto_tree_add_bits_item(tree, hf_amr_wb_toc_ft, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
407 bits_used_for_frames += Framebits_WB[ft];
409 bit_offset += 4;
410 bitcount += 4;
411 /* Check Q bit */
412 proto_tree_add_bits_item(tree, hf_amr_toc_q, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
413 bit_offset += 1;
414 bitcount += 1;
415 } while ((f_bit == 1) && (tvb_reported_length_remaining(tvb, bitcount/8) > 2));
417 if (bits_used_for_frames > 0)
418 bytes_needed_for_frames = 1 + (bitcount+bits_used_for_frames)/8-bitcount/8;
419 else
420 bytes_needed_for_frames = 0;
422 /* Check if we have enough data available for our frames */
423 if (tvb_reported_length_remaining(tvb, bitcount/8) < bytes_needed_for_frames) {
424 proto_tree_add_expert_format(tree, pinfo, &ei_amr_not_enough_data_for_frames,
425 tvb, bitcount/8, bytes_needed_for_frames,
426 "Error: %d Bytes available, %d would be needed!",
427 tvb_reported_length_remaining(tvb, bitcount/8),
428 bytes_needed_for_frames);
430 else {
431 proto_tree_add_item(tree, hf_amr_frame_data, tvb, bitcount/8, bytes_needed_for_frames, ENC_NA);
434 bitcount += bits_used_for_frames;
436 if (tvb_reported_length_remaining(tvb, (bitcount+8)/8) > 0) {
437 proto_tree_add_expert_format(tree, pinfo, &ei_amr_superfluous_data, tvb, bitcount/8, tvb_reported_length_remaining(tvb, bitcount/8),
438 "Error: %d Bytes remaining - should be 0!",tvb_reported_length_remaining(tvb, (bitcount+8)/8));
440 /* Now check the paddings */
441 if (bitcount%8 != 0) {
442 if ( (1 << (8 -(bitcount%8)-1)) & tvb_get_uint8(tvb,bitcount/8) )
443 proto_tree_add_expert(tree, pinfo, &ei_amr_padding_bits_correct, tvb, bitcount/8, 1);
444 else {
445 proto_tree_add_expert(tree, pinfo, &ei_amr_padding_bits_not0, tvb,
446 bitcount/8, 1);
452 static void
453 dissect_amr_oa(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int amr_mode)
455 int offset = 0;
456 int bit_offset = 0;
457 uint8_t octet;
458 int ft;
459 int ft_payload_bits = 0;
460 int bits_used_for_frames = 0;
461 int bytes_needed_for_frames = 0;
462 proto_tree *toc_tree;
464 octet = tvb_get_uint8(tvb,offset);
466 if (amr_mode == AMR_NB) {
467 proto_tree_add_bits_item(tree, hf_amr_nb_cmr, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
468 } else {
469 proto_tree_add_bits_item(tree, hf_amr_wb_cmr, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
472 bit_offset += 4;
473 proto_tree_add_item(tree, hf_amr_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
474 if (octet & 0x0f) {
475 proto_tree_add_expert(tree, pinfo, &ei_amr_reserved_bits_not0, tvb, offset, 1);
477 offset += 1;
478 bit_offset += 4;
480 * A ToC entry takes the following format in octet-aligned mode:
482 * 0 1 2 3 4 5 6 7
483 * +-+-+-+-+-+-+-+-+
484 * |F| FT |Q|P|P|
485 * +-+-+-+-+-+-+-+-+
487 * F (1 bit): see definition in Section 4.3.2.
489 * FT (4 bits unsigned integer): see definition in Section 4.3.2.
491 * Q (1 bit): see definition in Section 4.3.2.
493 * P bits: padding bits, MUST be set to zero.
495 toc_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_amr_toc, NULL, "Payload Table of Contents");
497 do {
498 octet = tvb_get_uint8(tvb,offset);
500 /* F bit: */
501 proto_tree_add_bits_item(toc_tree, hf_amr_toc_f, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
502 bit_offset += 1;
503 /* FT bits: */
504 ft = tvb_get_bits8(tvb, bit_offset, 4);
505 if (amr_mode == AMR_NB) {
506 proto_tree_add_bits_item(toc_tree, hf_amr_nb_toc_ft, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
507 ft_payload_bits = Framebits_NB[ft];
508 } else {
509 proto_tree_add_bits_item(toc_tree, hf_amr_wb_toc_ft, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
510 ft_payload_bits = Framebits_WB[ft];
512 bits_used_for_frames += ft_payload_bits;
513 bytes_needed_for_frames += (bits_used_for_frames + 7)/8;
514 bit_offset += 4;
515 /* Q bit: */
516 proto_tree_add_bits_item(toc_tree, hf_amr_toc_q, tvb, bit_offset, 1, ENC_BIG_ENDIAN);
517 bit_offset += 1;
518 /* 2 padding bits: */
519 if (octet & 0x02) {
520 proto_tree_add_expert(tree, pinfo, &ei_amr_padding_bits_not0, tvb, offset, 1);
522 bit_offset += 2;
523 offset += 1;
524 } while ((octet & 0x80) == 0x80);
526 /* Check if we have enough data available for our frames */
527 if (tvb_reported_length_remaining(tvb, offset) < bytes_needed_for_frames) {
528 proto_tree_add_expert_format(tree, pinfo, &ei_amr_not_enough_data_for_frames,
529 tvb, offset, bytes_needed_for_frames,
530 "Error: %d Bytes available, %d would be needed!",
531 tvb_reported_length_remaining(tvb, offset),
532 bytes_needed_for_frames);
533 } else {
534 proto_tree_add_item(tree, hf_amr_frame_data, tvb, offset, bytes_needed_for_frames, ENC_NA);
537 offset += bytes_needed_for_frames;
539 if (tvb_reported_length_remaining(tvb, offset) > 0) {
540 proto_tree_add_expert_format(tree, pinfo, &ei_amr_superfluous_data,
541 tvb, offset, tvb_reported_length_remaining(tvb, offset),
542 "Error: %d Bytes remaining - should be 0!",
543 tvb_reported_length_remaining(tvb, offset));
545 /* Now check the paddings (FIXME: only last speech data block is checked here) */
546 if (ft_payload_bits%8 != 0) {
547 uint8_t last_byte = tvb_get_uint8(tvb, offset - 1);
548 if ((1 << (8 -(ft_payload_bits%8)-1)) & last_byte) {
549 proto_tree_add_expert(tree, pinfo, &ei_amr_padding_bits_correct, tvb, offset - 1, 1);
550 } else {
551 proto_tree_add_expert(tree, pinfo, &ei_amr_padding_bits_not0, tvb, offset - 1, 1);
557 /* Code to actually dissect the packets */
558 static void
559 dissect_amr_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int amr_mode, unsigned encoding)
561 int offset = 0;
562 uint8_t octet;
563 proto_item *item;
565 /* Set up structures needed to add the protocol subtree and manage it */
566 proto_item *ti;
567 proto_tree *amr_tree;
569 ti = proto_tree_add_item(tree, proto_amr, tvb, 0, -1, ENC_NA);
570 amr_tree = proto_item_add_subtree(ti, ett_amr);
572 item = proto_tree_add_uint(amr_tree, hf_amr_payload_decoded_as, tvb, offset, 4, encoding);
573 proto_item_set_len(item, tvb_reported_length(tvb));
574 proto_item_set_generated(item);
576 switch (encoding) {
577 case AMR_OA: /* RFC 3267 Octet aligned */
578 break;
579 case AMR_BE: /* RFC 3267 Bandwidth-efficient */
580 dissect_amr_be(tvb, pinfo, amr_tree, amr_mode);
581 return;
582 case AMR_IF1:
583 if (amr_mode == AMR_NB) {
584 dissect_amr_nb_if1(tvb, pinfo, amr_tree, NULL);
585 } else {
586 dissect_amr_wb_if1(tvb, pinfo, amr_tree, NULL);
588 return;
589 case AMR_IF2:
590 if (amr_mode == AMR_NB) {
591 dissect_amr_nb_if2(tvb, pinfo, amr_tree, NULL);
592 } else {
593 dissect_amr_wb_if2(tvb, pinfo, amr_tree, NULL);
595 return;
596 default:
597 break;
600 octet = tvb_get_uint8(tvb,offset) & 0x0f;
601 if (octet != 0) {
602 item = proto_tree_add_item(amr_tree, hf_amr_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
603 expert_add_info(pinfo, item, &ei_amr_reserved);
604 proto_item_set_generated(item);
605 dissect_amr_be(tvb, pinfo, amr_tree, amr_mode);
606 return;
609 dissect_amr_oa(tvb, pinfo, amr_tree, amr_mode);
610 return;
613 /* Code to actually dissect the packets */
614 static int
615 dissect_amr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
617 struct _rtp_info *rtp_info = NULL;
618 unsigned encoding = amr_encoding_type;
620 if (data) {
621 rtp_info = (struct _rtp_info*)data;
622 if (rtp_info->info_payload_fmtp_map) {
623 /* If the map is non-NULL, then the RTP conversation was set up by
624 * a SDP (even if the fmtp attribute was not present, in which case
625 * the map is empty.) According to RFC 4867, if octet-align is
626 * "0 or if not present, bandwidth-efficient operation is employed."
628 char *octet_aligned = wmem_map_lookup(rtp_info->info_payload_fmtp_map, "octet-align");
629 if (g_strcmp0(octet_aligned, "1") == 0) {
630 encoding = AMR_OA;
631 } else {
632 encoding = AMR_BE;
634 } else {
635 /* If the map is NULL, then we were called by RTP, but the RTP
636 * conversation was set by Decode As or similar, and we should
637 * use the preference settings.
639 rtp_info->info_payload_fmtp_map = amr_default_fmtp;
643 /* Make entries in Protocol column and Info column on summary display */
644 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AMR");
646 dissect_amr_common(tvb, pinfo, tree, pref_amr_mode, encoding);
647 return tvb_captured_length(tvb);
650 static int
651 dissect_amr_wb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
653 struct _rtp_info *rtp_info = NULL;
654 unsigned encoding = amr_encoding_type;
656 if (data) {
657 rtp_info = (struct _rtp_info*)data;
658 if (rtp_info->info_payload_fmtp_map) {
659 /* If the map is non-NULL, then the RTP conversation was set up by
660 * a SDP (even if the fmtp attribute was not present, in which case
661 * the map is empty.) According to RFC 4867, if octet-align is
662 * "0 or if not present, bandwidth-efficient operation is employed."
664 char *octet_aligned = wmem_map_lookup(rtp_info->info_payload_fmtp_map, "octet-align");
665 if (g_strcmp0(octet_aligned, "1") == 0) {
666 encoding = AMR_OA;
667 } else {
668 encoding = AMR_BE;
670 } else {
671 /* If the map is NULL, then we were called by RTP, but the RTP
672 * conversation was set by Decode As or similar, and we should
673 * use the preference settings.
675 rtp_info->info_payload_fmtp_map = amr_default_fmtp;
679 /* Make entries in Protocol column and Info column on summary display */
680 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AMR-WB");
682 dissect_amr_common(tvb, pinfo, tree, AMR_WB, encoding);
683 return tvb_captured_length(tvb);
687 typedef struct _amr_capability_t {
688 const char *id;
689 const char *name;
690 dissector_t content_pdu;
691 } amr_capability_t;
693 static amr_capability_t amr_capability_tab[] = {
694 /* ITU-T H.241 (05/2006), 8.3 H.264 capabilities */
695 { "GenericCapability/0.0.8.245.1.1.1", "H.245 - GSM AMR Capability Identifier", NULL },
696 { "GenericCapability/0.0.8.245.1.1.1/collapsing/0", "maxAl-sduAudioFrames", NULL },
697 { "GenericCapability/0.0.8.245.1.1.1/collapsing/1", "bitRate", NULL },
698 { "GenericCapability/0.0.8.245.1.1.1/collapsing/2", "gsmAmrComfortNoise", NULL },
699 { "GenericCapability/0.0.8.245.1.1.1/collapsing/3", "gsmEfrComfortNoise", NULL },
700 { "GenericCapability/0.0.8.245.1.1.1/collapsing/4", "is-641ComfortNoise", NULL },
701 { "GenericCapability/0.0.8.245.1.1.1/collapsing/5", "pdcEFRComfortNoise", NULL },
702 /* ITU-T Rec. G.722.2/Annex F (11/2002) */
703 { "GenericCapability/0.0.7.7222.1.0/collapsing/0", "maxAl-sduFrames", NULL },
704 { "GenericCapability/0.0.7.7222.1.0/collapsing/1", "bitRate", NULL },
705 { "GenericCapability/0.0.7.7222.1.0/collapsing/2", "octetAlign", NULL },
706 { "GenericCapability/0.0.7.7222.1.0/collapsing/3", "modeSet", NULL },
707 { "GenericCapability/0.0.7.7222.1.0/collapsing/4", "modeChangePeriod", NULL },
708 { "GenericCapability/0.0.7.7222.1.0/collapsing/5", "modeChangeNeighbour", NULL },
709 { "GenericCapability/0.0.7.7222.1.0/collapsing/6", "crc", NULL },
710 { "GenericCapability/0.0.7.7222.1.0/collapsing/7", "robustSorting", NULL },
711 { "GenericCapability/0.0.7.7222.1.0/collapsing/8", "interleaving", NULL },
712 { NULL, NULL, NULL },
715 static amr_capability_t *find_cap(const char *id) {
716 amr_capability_t *ftr = NULL;
717 amr_capability_t *f;
719 for (f=amr_capability_tab; f->id; f++) {
720 if (!strcmp(id, f->id)) {
721 ftr = f;
722 break;
725 return ftr;
728 static int
729 dissect_amr_name(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
731 asn1_ctx_t *actx;
733 /* Reject the packet if data is NULL */
734 if (data == NULL)
735 return 0;
736 actx = get_asn1_ctx(data);
737 DISSECTOR_ASSERT(actx != NULL);
739 if (tree && (actx != NULL)) {
740 amr_capability_t *ftr;
741 ftr = find_cap(pinfo->match_string);
742 if (ftr) {
743 proto_item_append_text(actx->created_item, " - %s", ftr->name);
744 proto_item_append_text(proto_item_get_parent(proto_tree_get_parent(tree)), ": %s", ftr->name);
745 } else {
746 proto_item_append_text(actx->created_item, " - unknown(%s)", pinfo->match_string);
750 return tvb_reported_length(tvb);
753 void
754 proto_register_amr(void)
756 module_t *amr_module;
757 expert_module_t* expert_amr;
759 static hf_register_info hf[] = {
760 { &hf_amr_nb_cmr,
761 { "CMR", "amr.nb.cmr",
762 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_nb_codec_mode_request_vals_ext, 0x0,
763 "codec mode request", HFILL }
765 { &hf_amr_wb_cmr,
766 { "CMR", "amr.wb.cmr",
767 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_wb_codec_mode_request_vals_ext, 0x0,
768 "codec mode request", HFILL }
770 { &hf_amr_reserved,
771 { "Reserved", "amr.reserved",
772 FT_UINT8, BASE_DEC, NULL, 0x0f,
773 "Reserved bits", HFILL }
775 { &hf_amr_payload_decoded_as,
776 { "Payload decoded as", "amr.payload_decoded_as",
777 FT_UINT32, BASE_DEC, VALS(amr_encoding_type_value), 0x0,
778 "Value of decoding preference", HFILL }
780 { &hf_amr_toc_f,
781 { "F bit", "amr.toc.f",
782 FT_BOOLEAN, BASE_NONE, TFS(&toc_f_bit_vals), 0x0,
783 NULL, HFILL }
785 { &hf_amr_nb_toc_ft,
786 { "FT bits", "amr.nb.toc.ft",
787 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_nb_codec_mode_vals_ext, 0x0,
788 "Frame type index", HFILL }
790 { &hf_amr_wb_toc_ft,
791 { "FT bits", "amr.wb.toc.ft",
792 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_wb_codec_mode_vals_ext, 0x0,
793 "Frame type index", HFILL }
795 { &hf_amr_toc_q,
796 { "Q bit", "amr.toc.q",
797 FT_BOOLEAN, BASE_NONE, TFS(&toc_q_bit_vals), 0x0,
798 "Frame quality indicator bit", HFILL }
800 { &hf_amr_speech_data,
801 { "Speech data", "amr.speech_data",
802 FT_BYTES, BASE_NONE, NULL, 0x0,
803 NULL, HFILL }
805 { &hf_amr_frame_data,
806 { "Frame Data", "amr.frame_data",
807 FT_BYTES, BASE_NONE, NULL, 0x0,
808 NULL, HFILL }
810 { &hf_amr_nb_if1_ft,
811 { "Frame Type", "amr.nb.if1.ft",
812 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_nb_codec_mode_vals_ext, 0xf0,
813 NULL, HFILL }
815 { &hf_amr_wb_if1_ft,
816 { "Frame Type", "amr.wb.if1.ft",
817 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_wb_codec_mode_vals_ext, 0xf0,
818 NULL, HFILL }
820 { &hf_amr_nb_if1_mode_req,
821 { "Mode Type request", "amr.nb.if1.modereq",
822 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_nb_codec_mode_request_vals_ext, 0xe0,
823 NULL, HFILL }
825 { &hf_amr_wb_if1_mode_req,
826 { "Mode Type request", "amr.wb.if1.modereq",
827 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_wb_codec_mode_request_vals_ext, 0x0f,
828 NULL, HFILL }
830 { &hf_amr_if1_sti,
831 { "SID Type Indicator", "amr.if1.sti",
832 FT_BOOLEAN, 8, TFS(&amr_sti_vals), 0x10,
833 NULL, HFILL }
835 { &hf_amr_nb_if1_sti_mode_ind,
836 { "Mode Type indication", "amr.nb.if1.stimodeind",
837 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_nb_codec_mode_vals_ext, 0x0e,
838 NULL, HFILL }
840 { &hf_amr_wb_if1_sti_mode_ind,
841 { "Mode Type indication", "amr.wb.if1.stimodeind",
842 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_wb_codec_mode_vals_ext, 0x0f,
843 NULL, HFILL }
845 { &hf_amr_nb_if1_mode_ind,
846 { "Mode Type indication", "amr.nb.if1.modeind",
847 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_nb_codec_mode_vals_ext, 0x07,
848 NULL, HFILL }
850 { &hf_amr_wb_if1_mode_ind,
851 { "Mode Type indication", "amr.wb.if1.modeind",
852 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_wb_codec_mode_vals_ext, 0xf0,
853 NULL, HFILL }
855 { &hf_amr_nb_if2_ft,
856 { "Frame Type", "amr.nb.if2.ft",
857 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_nb_codec_mode_vals_ext, 0x0f,
858 NULL, HFILL }
860 { &hf_amr_wb_if2_ft,
861 { "Frame Type", "amr.wb.if2.ft",
862 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_wb_codec_mode_vals_ext, 0xf0,
863 NULL, HFILL }
865 { &hf_amr_if2_sti,
866 { "SID Type Indicator", "amr.if2.sti",
867 FT_BOOLEAN, 8, TFS(&amr_sti_vals), 0x80,
868 NULL, HFILL }
870 { &hf_amr_nb_if2_sti_mode_ind,
871 { "Mode Type indication", "amr.nb.if2.stimodeind",
872 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_nb_codec_mode_vals_ext, 0x07,
873 NULL, HFILL }
875 { &hf_amr_wb_if2_sti_mode_ind,
876 { "Mode Type indication", "amr.wb.if2.stimodeind",
877 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &amr_wb_codec_mode_vals_ext, 0x78,
878 NULL, HFILL }
880 { &hf_amr_if1_fqi,
881 { "FQI", "amr.fqi",
882 FT_BOOLEAN, 8, TFS(&toc_q_bit_vals), 0x08,
883 "Frame quality indicator bit", HFILL }
887 /* Setup protocol subtree array */
888 static int *ett[] = {
889 &ett_amr,
890 &ett_amr_toc,
893 static ei_register_info ei[] = {
894 { &ei_amr_spare_bit_not0, { "amr.spare_bit_not0", PI_PROTOCOL, PI_WARN, "Error:Spare bits not 0", EXPFILL }},
895 { &ei_amr_not_enough_data_for_frames, { "amr.not_enough_data_for_frames", PI_MALFORMED, PI_ERROR, "Not enough data for the frames according to TOC", EXPFILL }},
896 { &ei_amr_superfluous_data, { "amr.superfluous_data", PI_MALFORMED, PI_ERROR, "Superfluous data remaining", EXPFILL }},
897 { &ei_amr_reserved_bits_not0, { "amr.reserved_bits_not0", PI_MALFORMED, PI_ERROR, "Reserved bits error - MUST be 0", EXPFILL }},
898 { &ei_amr_padding_bits_not0, { "amr.padding_bits_not0", PI_MALFORMED, PI_ERROR, "Padding bits error - MUST be 0", EXPFILL }},
899 { &ei_amr_padding_bits_correct, { "amr.padding_bits_correct", PI_PROTOCOL, PI_NOTE, "Padding bits correct", EXPFILL }},
900 { &ei_amr_reserved, { "amr.reserved.not_zero", PI_PROTOCOL, PI_WARN, "Reserved != 0, wrongly encoded or not octet aligned. Decoding as bandwidth-efficient mode", EXPFILL }},
903 static const enum_val_t encoding_types[] = {
904 {"octet_aligned", "RFC 3267 octet aligned", AMR_OA},
905 {"bw_efficient", "RFC 3267 BW-efficient", AMR_BE},
906 {"IF1", "AMR IF1", AMR_IF1},
907 {"IF2", "AMR IF2", AMR_IF2},
908 {NULL, NULL, -1}
911 static const enum_val_t modes[] = {
912 {"AMR-NB", "Narrowband AMR", AMR_NB},
913 {"AMR-WB", "Wideband AMR", AMR_WB},
914 {NULL, NULL, -1}
917 /* Register the protocol name and description */
918 proto_amr = proto_register_protocol("Adaptive Multi-Rate","AMR", "amr");
919 proto_amr_wb = proto_register_protocol_in_name_only("Adaptive Multi-Rate WB","AMR WB", "amr_wb", proto_amr, FT_PROTOCOL);
921 /* Required function calls to register the header fields and subtrees used */
922 proto_register_field_array(proto_amr, hf, array_length(hf));
923 proto_register_subtree_array(ett, array_length(ett));
924 expert_amr = expert_register_protocol(proto_amr);
925 expert_register_field_array(expert_amr, ei, array_length(ei));
926 /* Register a configuration option for port */
928 amr_module = prefs_register_protocol(proto_amr, amr_apply_prefs);
930 prefs_register_obsolete_preference(amr_module, "dynamic.payload.type");
931 prefs_register_obsolete_preference(amr_module, "wb.dynamic.payload.type");
933 prefs_register_enum_preference(amr_module, "encoding.version",
934 "Type of AMR encoding of the payload",
935 "Type of AMR encoding of the payload, if not specified "
936 "via SDP",
937 &amr_encoding_type, encoding_types, false);
939 prefs_register_enum_preference(amr_module, "mode",
940 "The AMR mode",
941 "The AMR mode",
942 &pref_amr_mode, modes, AMR_NB);
944 amr_handle = register_dissector("amr", dissect_amr, proto_amr);
945 amr_wb_handle = register_dissector("amr-wb", dissect_amr_wb, proto_amr_wb);
946 register_dissector("amr_if1_nb", dissect_amr_nb_if1, proto_amr);
947 register_dissector("amr_if1_wb", dissect_amr_wb_if1, proto_amr);
948 register_dissector("amr_if2_nb", dissect_amr_nb_if2, proto_amr);
949 register_dissector("amr_if2_wb", dissect_amr_wb_if2, proto_amr);
951 oid_add_from_string("G.722.2 (AMR-WB) audio capability","0.0.7.7222.1.0");
953 amr_default_fmtp = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
956 /* Register the protocol with Wireshark */
957 void
958 proto_reg_handoff_amr(void)
960 dissector_handle_t amr_name_handle;
961 amr_capability_t *ftr;
963 dissector_add_string("rtp_dyn_payload_type","AMR", amr_handle);
964 dissector_add_string("rtp_dyn_payload_type","AMR-WB", amr_wb_handle);
966 dissector_add_uint_range_with_preference("rtp.pt", "", amr_handle);
967 dissector_add_uint_range_with_preference("rtp.pt", "", amr_wb_handle);
970 * Register H.245 Generic parameter name(s)
972 amr_name_handle = create_dissector_handle(dissect_amr_name, proto_amr);
973 for (ftr=amr_capability_tab; ftr->id; ftr++) {
974 if (ftr->name)
975 dissector_add_string("h245.gef.name", ftr->id, amr_name_handle);
976 if (ftr->content_pdu)
977 dissector_add_string("h245.gef.content", ftr->id,
978 create_dissector_handle(ftr->content_pdu, proto_amr));
980 /* Activate the next line for testing with the randpkt tool
981 dissector_add_uint_with_preference("udp.port", 55555, amr_handle);
986 * Editor modelines - https://www.wireshark.org/tools/modelines.html
988 * Local variables:
989 * c-basic-offset: 4
990 * tab-width: 8
991 * indent-tabs-mode: nil
992 * End:
994 * vi: set shiftwidth=4 tabstop=8 expandtab:
995 * :indentSize=4:tabSize=8:noTabs=true: