aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-amr.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2006-11-01 22:58:41 +0000
committerAnders Broman <anders.broman@ericsson.com>2006-11-01 22:58:41 +0000
commit1e89a5daa87eec192a08ca3cb47581fa1fd0e830 (patch)
tree7efd70c8777c7738bc303585737b61ea7258bd58 /epan/dissectors/packet-amr.c
parent8f10d0f24d12bc280928468df59b55f9ecd3fbde (diff)
Handle RFC 3267 Bandwidth-efficient mode.
svn path=/trunk/; revision=19769
Diffstat (limited to 'epan/dissectors/packet-amr.c')
-rw-r--r--epan/dissectors/packet-amr.c161
1 files changed, 88 insertions, 73 deletions
diff --git a/epan/dissectors/packet-amr.c b/epan/dissectors/packet-amr.c
index ee5dd85cf3..664069aac5 100644
--- a/epan/dissectors/packet-amr.c
+++ b/epan/dissectors/packet-amr.c
@@ -23,8 +23,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* References:
- * RFC 3267
- * http://www.ietf.org/rfc/rfc3267.txt?number=3267
+ * RFC 3267 http://www.ietf.org/rfc/rfc3267.txt?number=3267
+ * 3GPP TS 26.101
*/
#ifdef HAVE_CONFIG_H
@@ -52,12 +52,6 @@ static int hf_amr_reserved = -1;
static int hf_amr_toc_f = -1;
static int hf_amr_toc_ft = -1;
static int hf_amr_toc_q = -1;
-static int hf_amr_toc_f_unaligned1 = -1;
-static int hf_amr_toc_ft_unaligned1 = -1;
-static int hf_amr_toc_q_unaligned1 = -1;
-static int hf_amr_toc_f_unaligned2 = -1;
-static int hf_amr_toc_ft_unaligned2 = -1;
-static int hf_amr_toc_q_unaligned2 = -1;
static int hf_amr_if1_ft = -1;
static int hf_amr_if1_fqi = -1;
@@ -69,6 +63,10 @@ static int hf_amr_sti = -1;
static int hf_amr_if2_ft = -1;
+static int hf_amr_be_reserved = -1;
+static int hf_amr_be_ft = -1;
+static int hf_amr_be_reserved2 = -1;
+
/* Initialize the subtree pointers */
static int ett_amr = -1;
@@ -85,7 +83,7 @@ gint amr_encoding_type = 0;
static const value_string amr_encoding_type_value[] = {
{0, "RFC 3267"},
- {1, "RFC 3267 bandwidth-efficient mode"}, /* Not coded */
+ {1, "RFC 3267 bandwidth-efficient mode"},
{2, "AMR IF 1"},
{3, "AMR IF 2"},
{ 0, NULL }
@@ -103,6 +101,7 @@ static const value_string amr_codec_mode_vals[] = {
{ 0, NULL }
};
+/* Ref 3GPP TS 26.101 table 1a */
static const value_string amr_codec_mode_request_vals[] = {
{0, "AMR 4,75 kbit/s"},
{1, "AMR 5,15 kbit/s"},
@@ -182,7 +181,50 @@ dissect_amr_if2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree){
col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
val_to_str(octet, amr_codec_mode_request_vals, "Unknown (%d)" ));
}
+/*
+ * 4.3.5.1. Single Channel Payload Carrying a Single Frame
+ *
+ * The following diagram shows a bandwidth-efficient AMR payload from a
+ * single channel session carrying a single speech frame-block.
+ *
+ * In the payload, no specific mode is requested (CMR=15), the speech
+ * frame is not damaged at the IP origin (Q=1), and the coding mode is
+ * AMR 7.4 kbps (FT=4). The encoded speech bits, d(0) to d(147), are
+ * arranged in descending sensitivity order according to [2]. Finally,
+ * two zero bits are added to the end as padding to make the payload
+ * octet aligned.
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | CMR=15|0| FT=4 |1|d(0) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+static void
+dissect_amr_be(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree){
+ proto_item *item;
+ guint8 octet;
+ int offset =0;
+ proto_tree_add_item(tree, hf_amr_cmr, tvb, offset, 1, FALSE);
+ proto_tree_add_item(tree, hf_amr_be_reserved, tvb, offset, 1, FALSE);
+ octet = tvb_get_guint8(tvb,offset) & 0x08;
+ if ( octet != 0 ){
+ item = proto_tree_add_text(tree, tvb, offset, -1, "Reserved != 0, wrongly encoded or not bandwidth-efficient.");
+ PROTO_ITEM_SET_GENERATED(item);
+ return;
+ }
+ proto_tree_add_item(tree, hf_amr_be_ft, tvb, offset, 2, FALSE);
+ proto_tree_add_item(tree, hf_amr_be_reserved2, tvb, offset, 2, FALSE);
+ offset++;
+ octet = tvb_get_guint8(tvb,offset) & 0x40;
+ if ( octet != 0x40 ){
+ item = proto_tree_add_text(tree, tvb, offset, -1, "Reserved != 1, wrongly encoded or not bandwidth-efficient.");
+ PROTO_ITEM_SET_GENERATED(item);
+ return;
+ }
+
+}
/* Code to actually dissect the packets */
static void
dissect_amr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@@ -208,9 +250,11 @@ dissect_amr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree_add_text(amr_tree, tvb, offset, -1, "Payload decoded as %s",val_to_str(amr_encoding_type, amr_encoding_type_value, "Unknown value - Error"));
switch (amr_encoding_type){
- case 0:
- case 1:
+ case 0: /* RFC 3267 Byte aligned */
break;
+ case 1: /* RFC 3267 Bandwidth-efficient */
+ dissect_amr_be(tvb, pinfo, amr_tree);
+ return;
case 2: /* AMR IF1 */
dissect_amr_if1(tvb, pinfo, amr_tree);
return;
@@ -228,43 +272,28 @@ dissect_amr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if ( octet != 0 ){
item = proto_tree_add_text(amr_tree, tvb, offset, -1, "Reserved != 0, wrongly encoded or not octet aligned. Decoding as bandwidth-efficient mode");
PROTO_ITEM_SET_GENERATED(item);
- if (!tvb_length_remaining(tvb,offset))
- return;
- /* 0 1 2 3 4 5
- * +-+-+-+-+-+-+
- * |F| FT |Q|
- * +-+-+-+-+-+-+
- */
-
- toc_item = proto_tree_add_text(amr_tree, tvb, offset, -1, "Payload Table of Contents");
- toc_tree = proto_item_add_subtree(toc_item, ett_amr_toc);
-
- proto_tree_add_item(amr_tree, hf_amr_toc_f_unaligned1, tvb, offset, 2, FALSE);
- proto_tree_add_item(amr_tree, hf_amr_toc_ft_unaligned1, tvb, offset, 2, FALSE);
- proto_tree_add_item(amr_tree, hf_amr_toc_q_unaligned1, tvb, offset, 2, FALSE);
- if (octet & 0x04)
- return;
- octet = tvb_get_guint8(tvb,offset+1);
- proto_tree_add_item(amr_tree, hf_amr_toc_f_unaligned2, tvb, offset, 2, FALSE);
- proto_tree_add_item(amr_tree, hf_amr_toc_ft_unaligned2, tvb, offset, 2, FALSE);
- proto_tree_add_item(amr_tree, hf_amr_toc_q_unaligned2, tvb, offset, 2, FALSE);
- if (octet & 0x20)
- return;
return;
+
}
proto_tree_add_item(amr_tree, hf_amr_reserved, tvb, offset, 1, FALSE);
offset++;
toc_offset = offset;
- /* If interleaced ILL and ILP follows here */
-
- /* Payload Table of Contents
- * A ToC entry takes the following format in octet-aligned mode:
+ /*
+ * A ToC entry takes the following format in octet-aligned mode:
+ *
+ * 0 1 2 3 4 5 6 7
+ * +-+-+-+-+-+-+-+-+
+ * |F| FT |Q|P|P|
+ * +-+-+-+-+-+-+-+-+
*
- * 0 1 2 3 4 5 6 7
- * +-+-+-+-+-+-+-+-+
- * |F| FT |Q|P|P|
- * +-+-+-+-+-+-+-+-+
+ * F (1 bit): see definition in Section 4.3.2.
+ *
+ * FT (4 bits unsigned integer): see definition in Section 4.3.2.
+ *
+ * Q (1 bit): see definition in Section 4.3.2.
+ *
+ * P bits: padding bits, MUST be set to zero.
*/
octet = tvb_get_guint8(tvb,offset);
toc_item = proto_tree_add_text(amr_tree, tvb, offset, -1, "Payload Table of Contents");
@@ -344,43 +373,13 @@ proto_register_amr(void)
{ &hf_amr_toc_ft,
{ "FT bits", "amr.toc.ft",
FT_UINT8, BASE_DEC, VALS(amr_codec_mode_request_vals), 0x78,
- "FT bits", HFILL }
+ "Frame type index", HFILL }
},
{ &hf_amr_toc_q,
{ "Q bit", "amr.toc.q",
FT_BOOLEAN, 8, TFS(&toc_q_bit_vals), 0x04,
"Frame quality indicator bit", HFILL }
},
- { &hf_amr_toc_f_unaligned1,
- { "F bit", "amr.toc.f.ual1",
- FT_BOOLEAN, 16, TFS(&toc_f_bit_vals), 0x0800,
- "F bit", HFILL }
- },
- { &hf_amr_toc_ft_unaligned1,
- { "FT bits", "amr.toc.ft.ual1",
- FT_UINT16, BASE_DEC, VALS(amr_codec_mode_request_vals), 0x0780,
- "FT bits", HFILL }
- },
- { &hf_amr_toc_q_unaligned1,
- { "Q bit", "amr.toc.ua1.q.ual1",
- FT_BOOLEAN, 16, TFS(&toc_q_bit_vals), 0x0040,
- "Frame quality indicator bit", HFILL }
- },
- { &hf_amr_toc_f_unaligned2,
- { "F bit", "amr.toc.f.ual2",
- FT_BOOLEAN, 16, TFS(&toc_f_bit_vals), 0x0020,
- "F bit", HFILL }
- },
- { &hf_amr_toc_ft_unaligned2,
- { "FT bits", "amr.toc.ft.ual2",
- FT_UINT16, BASE_DEC, VALS(amr_codec_mode_request_vals), 0x001e,
- "FT bits", HFILL }
- },
- { &hf_amr_toc_q_unaligned2,
- { "Q bit", "amr.toc.ua1.q.ual2",
- FT_BOOLEAN, 16, TFS(&toc_q_bit_vals), 0x00001,
- "Frame quality indicator bit", HFILL }
- },
{ &hf_amr_if1_ft,
{ "Frame Type", "amr.if1.ft",
FT_UINT8, BASE_DEC, VALS(amr_codec_mode_request_vals), 0xf0,
@@ -421,6 +420,21 @@ proto_register_amr(void)
FT_BOOLEAN, 8, TFS(&toc_q_bit_vals), 0x08,
"Frame quality indicator bit", HFILL }
},
+ { &hf_amr_be_reserved,
+ { "Reserved", "amr.be.reserved",
+ FT_UINT8, BASE_DEC, NULL, 0x08,
+ "Reserved", HFILL }
+ },
+ { &hf_amr_be_ft,
+ { "Frame Type", "amr.be.ft",
+ FT_UINT16, BASE_DEC, VALS(amr_codec_mode_request_vals), 0x0780,
+ "Frame Type", HFILL }
+ },
+ { &hf_amr_be_reserved2,
+ { "Reserved", "amr.be.reserved2",
+ FT_UINT16, BASE_DEC, NULL, 0x0040,
+ "Reserved", HFILL }
+ },
};
/* Setup protocol subtree array */
@@ -429,7 +443,8 @@ proto_register_amr(void)
&ett_amr_toc,
};
static enum_val_t encoding_types[] = {
- {"RFC 3267 Byte aligned", "RFC 3267", 0},
+ {"RFC 3267 Byte aligned", "RFC 3267 octet aligned", 0},
+ {"RFC 3267 Bandwidth-efficient", "RFC 3267 BW-efficient", 1},
{"AMR IF1", "AMR IF1", 2},
{"AMR IF2", "AMR IF2", 3},
{NULL, NULL, -1}