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
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
19 #include <epan/packet.h>
20 #include <epan/expert.h>
21 #include <epan/oids.h>
22 #include <epan/asn1.h>
25 #include "packet-rtp.h"
26 #include "packet-amr.h"
28 void proto_register_amr(void);
29 void proto_reg_handoff_amr(void);
33 #define AMR_NO_TRANS 15
43 static dissector_handle_t amr_handle
;
44 static dissector_handle_t amr_wb_handle
;
46 /* Initialize the protocol and registered fields */
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 */
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"},
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)"},
114 {10, "TDMA-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)"},
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"},
140 {AMR_NO_TRANS
, "No Data (No transmission/No reception)"},
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"},
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"},
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
= {
207 "Severely damaged frame"
210 static const true_false_string amr_sti_vals
= {
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
)
239 for (ft
= 0; ft
< AMR_FT_PDC_EFR_SID
; ft
++) {
240 if ((Framebits_NB
[ft
] + 7) / 8 == bytes
) {
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
;
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 */
259 dissect_amr_nb_if1(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
) {
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
);
277 proto_tree_add_item(tree
, hf_amr_nb_if1_mode_ind
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
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
);
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 */
289 dissect_amr_wb_if1(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
) {
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
);
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
);
311 proto_tree_add_item(tree
, hf_amr_speech_data
, tvb
, offset
, -1, ENC_NA
);
312 return tvb_captured_length(tvb
);
316 dissect_amr_nb_if2(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
) {
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
);
329 if (octet
== AMR_NO_TRANS
)
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
);
339 dissect_amr_wb_if2(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
) {
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
);
352 if (octet
== AMR_NO_TRANS
)
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
);
362 dissect_amr_be(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int amr_mode
) {
365 int bitcount
; /*bitcounter, MSB = bit 0, over bytes*/
366 int bits_used_for_frames
= 0;
367 int bytes_needed_for_frames
;
373 if (amr_mode
== AMR_NB
)
374 proto_tree_add_bits_item(tree
, hf_amr_nb_cmr
, tvb
, bit_offset
, 4, ENC_BIG_ENDIAN
);
376 proto_tree_add_bits_item(tree
, hf_amr_wb_cmr
, tvb
, bit_offset
, 4, ENC_BIG_ENDIAN
);
379 /* In bandwidth-efficient mode, a ToC entry takes the following format:
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.
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
);
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
];
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
];
412 proto_tree_add_bits_item(tree
, hf_amr_toc_q
, tvb
, bit_offset
, 1, ENC_BIG_ENDIAN
);
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;
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
);
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);
445 proto_tree_add_expert(tree
, pinfo
, &ei_amr_padding_bits_not0
, tvb
,
453 dissect_amr_oa(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int amr_mode
)
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
);
469 proto_tree_add_bits_item(tree
, hf_amr_wb_cmr
, tvb
, bit_offset
, 4, ENC_BIG_ENDIAN
);
473 proto_tree_add_item(tree
, hf_amr_reserved
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
475 proto_tree_add_expert(tree
, pinfo
, &ei_amr_reserved_bits_not0
, tvb
, offset
, 1);
480 * A ToC entry takes the following format in octet-aligned mode:
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");
498 octet
= tvb_get_uint8(tvb
,offset
);
501 proto_tree_add_bits_item(toc_tree
, hf_amr_toc_f
, tvb
, bit_offset
, 1, ENC_BIG_ENDIAN
);
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
];
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;
516 proto_tree_add_bits_item(toc_tree
, hf_amr_toc_q
, tvb
, bit_offset
, 1, ENC_BIG_ENDIAN
);
518 /* 2 padding bits: */
520 proto_tree_add_expert(tree
, pinfo
, &ei_amr_padding_bits_not0
, tvb
, 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
);
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);
551 proto_tree_add_expert(tree
, pinfo
, &ei_amr_padding_bits_not0
, tvb
, offset
- 1, 1);
557 /* Code to actually dissect the packets */
559 dissect_amr_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int amr_mode
, unsigned encoding
)
565 /* Set up structures needed to add the protocol subtree and manage it */
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
);
577 case AMR_OA
: /* RFC 3267 Octet aligned */
579 case AMR_BE
: /* RFC 3267 Bandwidth-efficient */
580 dissect_amr_be(tvb
, pinfo
, amr_tree
, amr_mode
);
583 if (amr_mode
== AMR_NB
) {
584 dissect_amr_nb_if1(tvb
, pinfo
, amr_tree
, NULL
);
586 dissect_amr_wb_if1(tvb
, pinfo
, amr_tree
, NULL
);
590 if (amr_mode
== AMR_NB
) {
591 dissect_amr_nb_if2(tvb
, pinfo
, amr_tree
, NULL
);
593 dissect_amr_wb_if2(tvb
, pinfo
, amr_tree
, NULL
);
600 octet
= tvb_get_uint8(tvb
,offset
) & 0x0f;
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
);
609 dissect_amr_oa(tvb
, pinfo
, amr_tree
, amr_mode
);
613 /* Code to actually dissect the packets */
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
;
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) {
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
);
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
;
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) {
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
{
690 dissector_t content_pdu
;
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
;
719 for (f
=amr_capability_tab
; f
->id
; f
++) {
720 if (!strcmp(id
, f
->id
)) {
729 dissect_amr_name(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
733 /* Reject the packet if data is NULL */
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
);
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
);
746 proto_item_append_text(actx
->created_item
, " - unknown(%s)", pinfo
->match_string
);
750 return tvb_reported_length(tvb
);
754 proto_register_amr(void)
756 module_t
*amr_module
;
757 expert_module_t
* expert_amr
;
759 static hf_register_info hf
[] = {
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
}
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
}
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
}
781 { "F bit", "amr.toc.f",
782 FT_BOOLEAN
, BASE_NONE
, TFS(&toc_f_bit_vals
), 0x0,
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
}
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
}
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,
805 { &hf_amr_frame_data
,
806 { "Frame Data", "amr.frame_data",
807 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
811 { "Frame Type", "amr.nb.if1.ft",
812 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &amr_nb_codec_mode_vals_ext
, 0xf0,
816 { "Frame Type", "amr.wb.if1.ft",
817 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &amr_wb_codec_mode_vals_ext
, 0xf0,
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,
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,
831 { "SID Type Indicator", "amr.if1.sti",
832 FT_BOOLEAN
, 8, TFS(&amr_sti_vals
), 0x10,
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,
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,
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,
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,
856 { "Frame Type", "amr.nb.if2.ft",
857 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &amr_nb_codec_mode_vals_ext
, 0x0f,
861 { "Frame Type", "amr.wb.if2.ft",
862 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &amr_wb_codec_mode_vals_ext
, 0xf0,
866 { "SID Type Indicator", "amr.if2.sti",
867 FT_BOOLEAN
, 8, TFS(&amr_sti_vals
), 0x80,
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,
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,
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
[] = {
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
},
911 static const enum_val_t modes
[] = {
912 {"AMR-NB", "Narrowband AMR", AMR_NB
},
913 {"AMR-WB", "Wideband AMR", AMR_WB
},
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 "
937 &amr_encoding_type
, encoding_types
, false);
939 prefs_register_enum_preference(amr_module
, "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 */
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
++) {
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
991 * indent-tabs-mode: nil
994 * vi: set shiftwidth=4 tabstop=8 expandtab:
995 * :indentSize=4:tabSize=8:noTabs=true: