1 /* packet-gsm_abis_tfp.c
2 * Routines for packet dissection of Ericsson GSM A-bis TFP
3 * (Traffic Forwarding Protocol)
4 * Copyright 2010-2016 by Harald Welte <laforge@gnumonks.org>
6 * TFP is an Ericsson-specific packetized version of replacing TRAU
7 * frames on 8k/16k E1 sub-slots with a paketized frame format which
8 * can be transported over LAPD on a SuperChannel (E1 timeslot bundle)
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * SPDX-License-Identifier: GPL-2.0-or-later
20 #include <epan/packet.h>
21 #include <epan/prefs.h>
23 void proto_register_abis_tfp(void);
24 void proto_reg_handoff_abis_tfp(void);
32 static dissector_handle_t tfp_handle
;
33 static dissector_handle_t sub_handles
[SUB_MAX
];
35 /* initialize the protocol and registered fields */
36 static int proto_abis_tfp
;
39 static int hf_tfp_hdr_atsr
;
40 static int hf_tfp_hdr_slot_rate
;
41 static int hf_tfp_hdr_seq_nr
;
42 static int hf_tfp_hdr_delay_info
;
43 static int hf_tfp_hdr_p
;
44 static int hf_tfp_hdr_s
;
45 static int hf_tfp_hdr_m
;
46 static int hf_tfp_hdr_frame_type
;
47 static int hf_tfp_amr_rate
;
49 /* initialize the subtree pointers */
52 static const value_string tfp_slot_rate_vals
[] = {
53 { 0, "Full Rate (16kbps)" },
54 { 1, "Sub-Channel 0 (8kbps)" },
55 { 2, "Sub-Channel 1 (8kbps)" },
60 #define TFP_PACKED_NONE 0
61 #define TFP_PACKED_SCHEME_1 1
63 static const value_string tfp_packed_vals
[] = {
65 { 1, "Packing Scheme 1" },
69 static const value_string tfp_frame_type_vals
[] = {
72 { 1, "TFP-SCCE-AMR-IND" },
75 { 0x80, "TFP-AMR-IND" },
76 { 0x81, "TFP-SCCE-AMR-IND" },
77 { 0x82, "TFP-FR-IND" },
78 { 0x83, "TFP-EFR-IND" },
79 { 0x84, "TFP-SCCE-EFR-IND" },
83 static const value_string tfp_amr_len_rate_vals
[] = {
84 { 1, "SID_FIRST, ONSET, No speech/data" },
85 { 5, "SID_UPDATE, SID_BAD" },
98 dissect_abis_tfp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
101 proto_tree
*tfp_tree
;
103 uint32_t slot_rate
, frame_bits
, atsr
, seq_nr
;
108 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "TFP");
110 ti
= proto_tree_add_item(tree
, proto_abis_tfp
, tvb
, 0, -1, ENC_NA
);
111 tfp_tree
= proto_item_add_subtree(ti
, ett_tfp
);
113 proto_tree_add_item_ret_uint(tfp_tree
, hf_tfp_hdr_atsr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &atsr
);
114 proto_tree_add_item_ret_uint(tfp_tree
, hf_tfp_hdr_slot_rate
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &slot_rate
);
115 proto_tree_add_item_ret_uint(tfp_tree
, hf_tfp_hdr_seq_nr
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &seq_nr
);
116 proto_tree_add_item(tfp_tree
, hf_tfp_hdr_delay_info
, tvb
, offset
+1, 2, ENC_BIG_ENDIAN
);
117 proto_tree_add_item(tfp_tree
, hf_tfp_hdr_p
, tvb
, offset
+1, 2, ENC_BIG_ENDIAN
);
118 proto_tree_add_item(tfp_tree
, hf_tfp_hdr_s
, tvb
, offset
+2, 1, ENC_NA
);
119 proto_tree_add_item(tfp_tree
, hf_tfp_hdr_m
, tvb
, offset
+2, 1, ENC_NA
);
120 /* Frame Type depends on Slot Rate */
121 ftype
= tvb_get_uint8(tvb
, offset
+2) & 0x1E;
124 proto_tree_add_uint_format_value(tfp_tree
, hf_tfp_hdr_frame_type
, tvb
, offset
+2, 1, ftype
, "%s",
125 val_to_str(ftype
, tfp_frame_type_vals
, "Unknown (%u)"));
128 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "TS=%u, Seq=%u, %s, %s ", atsr
, seq_nr
,
129 val_to_str(slot_rate
, tfp_slot_rate_vals
, "Unknown (%u)"),
130 val_to_str(ftype
, tfp_frame_type_vals
, "Unknown (%u)"));
132 /* check for Tail bit == 1, iterate over further octests */
133 while ((tvb_get_uint8(tvb
, offset
) & 0x01) == 0)
137 switch (ftype
& 0x7F) {
138 case 0: /* TFP-AMR.ind */
139 len_remain
= tvb_captured_length_remaining(tvb
, offset
);
140 proto_tree_add_uint(tfp_tree
, hf_tfp_amr_rate
, tvb
, offset
, 0, len_remain
);
142 case 1: /* TFP-SCCE-AMR.ind */
144 case 2: /* TFP-HR.ind */
146 case 3: /* TFP-EFR.ind */
148 case 4: /* TFP-SCCE-EFR.ind */
152 /* FIXME: implement packed frame support */
157 next_tvb
= tvb_new_subset_length(tvb
, offset
, frame_bits
/8);
158 call_dissector(sub_handles
[SUB_DATA
], next_tvb
, pinfo
, tree
);
164 proto_register_abis_tfp(void)
166 static hf_register_info hf
[] = {
168 { "Air Timeslot Resource", "gsm_abis_tfp.atsr",
169 FT_UINT16
, BASE_DEC
, NULL
, 0xe000,
172 { &hf_tfp_hdr_slot_rate
,
173 { "Slot Rate", "gsm_abis_tfp.slot_rate",
174 FT_UINT16
, BASE_DEC
, VALS(tfp_slot_rate_vals
), 0x1800,
177 { &hf_tfp_hdr_seq_nr
,
178 { "Sequence Number", "gsm_abis_tfp.seq_nr",
179 FT_UINT16
, BASE_DEC
, NULL
, 0x07c0,
182 { &hf_tfp_hdr_delay_info
,
183 { "Delay Information (ms)", "gsm_abis_tfp.delay_info",
184 FT_UINT16
, BASE_DEC
, NULL
, 0x003e,
188 { "Packing Scheme", "gsm_abis_tfp.packing_scheme",
189 FT_UINT16
, BASE_DEC
, VALS(tfp_packed_vals
), 0x0180,
193 { "Silence Indicator", "gsm_abis_tfp.silence_ind",
194 FT_BOOLEAN
, 8, NULL
, 0x40,
198 { "Marker bit", "gsm_abis_tfp.marker",
199 FT_BOOLEAN
, 8, NULL
, 0x20,
202 { &hf_tfp_hdr_frame_type
,
203 { "Frame Type", "gsm_abis_tfp.frame_type",
204 FT_UINT8
, BASE_DEC
, VALS(tfp_frame_type_vals
), 0x1e,
208 { "AMR Rate", "gsm_abis_tfp.amr.rate",
209 FT_UINT8
, BASE_DEC
, VALS(tfp_amr_len_rate_vals
), 0,
213 static int *ett
[] = {
217 /* assign our custom match functions */
218 proto_abis_tfp
= proto_register_protocol("GSM A-bis TFP", "Ericsson GSM A-bis TFP",
221 proto_register_field_array(proto_abis_tfp
, hf
, array_length(hf
));
222 proto_register_subtree_array(ett
, array_length(ett
));
223 tfp_handle
= register_dissector("gsm_abis_tfp", dissect_abis_tfp
, proto_abis_tfp
);
226 /* This function is called once at startup and every time the user hits
227 * 'apply' in the preferences dialogue */
229 proto_reg_handoff_abis_tfp(void)
231 /* Those two SAPI values 10/11 are non-standard values, not specified by
232 * ETSI/3GPP, just like this very same protocol. */
233 dissector_add_uint("lapd.gsm.sapi", 10, tfp_handle
);
234 dissector_add_uint("lapd.gsm.sapi", 11, tfp_handle
);
235 sub_handles
[SUB_DATA
] = find_dissector("data");
239 * Editor modelines - https://www.wireshark.org/tools/modelines.html
244 * indent-tabs-mode: t
247 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
248 * :indentSize=8:tabSize=8:noTabs=false: