gsmtap: Add support for dissecting GSM voice / user plane messages
The GSMTAP Um interface type has so far only been used for transporting signaling messages. Osmocom has recently introduced support for encapsulating user-plane data (voice codec frames) in virtphy and osmo-bts-virtual. Let's catch up with this capability here. For the Osmcoom side, see: * https://gerrit.osmocom.org/c/osmocom-bb/+/17415 * https://gerrit.osmocom.org/c/osmo-bts/+/17377 Change-Id: Icceb524f0f47bab206ead8345d405ffea06ac109 Reviewed-on: https://code.wireshark.org/review/36359 Petri-Dish: Pascal Quantin <pascal@wireshark.org> Tested-by: Petri Dish Buildbot Reviewed-by: Vadim Yanitskiy <axilirator@gmail.com> Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
b6c50fe032
commit
29614e007e
|
@ -71,6 +71,8 @@ static int hf_ptcch_ta_idx = -1;
|
|||
static int hf_ptcch_ta_val = -1;
|
||||
static int hf_ptcch_padding = -1;
|
||||
|
||||
static int hf_um_voice_type = -1;
|
||||
|
||||
static gint ett_gsmtap = -1;
|
||||
|
||||
enum {
|
||||
|
@ -276,6 +278,28 @@ enum {
|
|||
GSMTAP_LTE_NAS_SUB_MAX
|
||||
};
|
||||
|
||||
/*! First byte of type==GSMTAP_TYPE_UM sub_type==GSMTAP_CHANNEL_VOICE payload */
|
||||
enum gsmtap_um_voice_type {
|
||||
/*! 1 byte TOC + 112 bits (14 octets) = 15 octets payload;
|
||||
* Reference is RFC5993 Section 5.2.1 + 3GPP TS 46.030 Annex B */
|
||||
GSMTAP_UM_VOICE_HR,
|
||||
/*! 33 payload bytes; Reference is RFC3551 Section 4.5.8.1 */
|
||||
GSMTAP_UM_VOICE_FR,
|
||||
/*! 31 payload bytes; Reference is RFC3551 Section 4.5.9 + ETSI TS 101 318 */
|
||||
GSMTAP_UM_VOICE_EFR,
|
||||
/*! 1 byte TOC + 5..31 bytes = 6..32 bytes payload; RFC4867 octet-aligned */
|
||||
GSMTAP_UM_VOICE_AMR,
|
||||
/* TODO: Revisit the types below; their usage; ... */
|
||||
GSMTAP_UM_VOICE_AMR_SID_BAD,
|
||||
GSMTAP_UM_VOICE_AMR_ONSET,
|
||||
GSMTAP_UM_VOICE_AMR_RATSCCH,
|
||||
GSMTAP_UM_VOICE_AMR_SID_UPDATE_INH,
|
||||
GSMTAP_UM_VOICE_AMR_SID_FIRST_P1,
|
||||
GSMTAP_UM_VOICE_AMR_SID_FIRST_P2,
|
||||
GSMTAP_UM_VOICE_AMR_SID_FIRST_INH,
|
||||
GSMTAP_UM_VOICE_AMR_RATSCCH_MARKER,
|
||||
GSMTAP_UM_VOICE_AMR_RATSCCH_DATA,
|
||||
};
|
||||
|
||||
static dissector_handle_t sub_handles[GSMTAP_SUB_MAX];
|
||||
static dissector_handle_t rrc_sub_handles[GSMTAP_RRC_SUB_MAX];
|
||||
|
@ -321,6 +345,8 @@ static const value_string gsmtap_channels[] = {
|
|||
{ GSMTAP_CHANNEL_PDTCH, "PDTCH" },
|
||||
{ GSMTAP_CHANNEL_PTCCH, "PTTCH" },
|
||||
{ GSMTAP_CHANNEL_CBCH51, "CBCH" },
|
||||
{ GSMTAP_CHANNEL_VOICE_F, "TCH/F" },
|
||||
{ GSMTAP_CHANNEL_VOICE_H, "TCH/H" },
|
||||
|
||||
{ GSMTAP_CHANNEL_ACCH|
|
||||
GSMTAP_CHANNEL_SDCCH, "LSACCH" },
|
||||
|
@ -409,6 +435,23 @@ static const value_string gsmtap_types[] = {
|
|||
{ 0, NULL },
|
||||
};
|
||||
|
||||
static const value_string gsmtap_um_voice_types[] = {
|
||||
{ GSMTAP_UM_VOICE_HR, "HR" },
|
||||
{ GSMTAP_UM_VOICE_FR, "FR" },
|
||||
{ GSMTAP_UM_VOICE_EFR, "EFR" },
|
||||
{ GSMTAP_UM_VOICE_AMR, "AMR" },
|
||||
{ GSMTAP_UM_VOICE_AMR_SID_BAD, "AMR_SID_BAD" },
|
||||
{ GSMTAP_UM_VOICE_AMR_ONSET, "AMR_ONSET" },
|
||||
{ GSMTAP_UM_VOICE_AMR_RATSCCH, "AMR_RATSCCH" },
|
||||
{ GSMTAP_UM_VOICE_AMR_SID_UPDATE_INH, "AMR_SID_UPDATE_INH" },
|
||||
{ GSMTAP_UM_VOICE_AMR_SID_FIRST_P1, "AMR_SID_FIRST_P1" },
|
||||
{ GSMTAP_UM_VOICE_AMR_SID_FIRST_P2, "AMR_SID_FIRST_P2" },
|
||||
{ GSMTAP_UM_VOICE_AMR_SID_FIRST_INH, "AMR_SID_FIRST_INH" },
|
||||
{ GSMTAP_UM_VOICE_AMR_RATSCCH_MARKER, "AMR_RATSCCH_MARKER" },
|
||||
{ GSMTAP_UM_VOICE_AMR_RATSCCH_DATA, "AMR_RATSCCH_DATA" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
/* dissect a SACCH L1 header which is included in the first 2 bytes
|
||||
* of every SACCH frame (according to TS 04.04) */
|
||||
static void
|
||||
|
@ -483,6 +526,21 @@ handle_lapdm(guint8 sub_type, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
|
|||
call_dissector_with_data(sub_handles[GSMTAP_SUB_UM_LAPDM], tvb, pinfo, tree, &ld);
|
||||
}
|
||||
|
||||
static void
|
||||
dissect_um_voice(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
tvbuff_t *payload_tvb;
|
||||
guint8 vtype = tvb_get_guint8(tvb, 0);
|
||||
|
||||
col_add_fstr(pinfo->cinfo, COL_INFO, "GSM CS User Plane (Voice/CSD): %s",
|
||||
val_to_str(vtype, gsmtap_um_voice_types, "Unknown %d"));
|
||||
|
||||
proto_tree_add_item(tree, hf_um_voice_type, tvb, 0, 1, ENC_NA);
|
||||
|
||||
payload_tvb = tvb_new_subset_length(tvb, 1, tvb_reported_length(tvb)-1);
|
||||
call_dissector(sub_handles[GSMTAP_SUB_DATA], payload_tvb, pinfo, tree);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_tetra(int channel, tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
|
@ -704,6 +762,11 @@ dissect_gsmtap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _
|
|||
sub_handle = GSMTAP_SUB_CBCH;
|
||||
break;
|
||||
|
||||
case GSMTAP_CHANNEL_VOICE_F:
|
||||
case GSMTAP_CHANNEL_VOICE_H:
|
||||
dissect_um_voice(payload_tvb, pinfo, tree);
|
||||
return tvb_captured_length(tvb);
|
||||
|
||||
case GSMTAP_CHANNEL_RACH:
|
||||
default:
|
||||
sub_handle = GSMTAP_SUB_DATA;
|
||||
|
@ -849,6 +912,8 @@ proto_register_gsmtap(void)
|
|||
NULL, HFILL } },
|
||||
{ &hf_sacch_l1h_ta, { "Actual Timing Advance", "gsmtap.sacch_l1.ta",
|
||||
FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
|
||||
{ &hf_um_voice_type, { "GSM Um Voice Type", "gsmtap.um_voice_type",
|
||||
FT_UINT8, BASE_DEC, VALS(gsmtap_um_voice_types), 0, NULL, HFILL } },
|
||||
|
||||
/* PTCCH (Packet Timing Advance Control Channel) on Downlink */
|
||||
{ &hf_ptcch_spare, { "Spare Bit", "gsmtap.ptcch.spare",
|
||||
|
|
|
@ -78,6 +78,8 @@
|
|||
#define GSMTAP_CHANNEL_PDTCH 0x0d
|
||||
#define GSMTAP_CHANNEL_PTCCH 0x0e
|
||||
#define GSMTAP_CHANNEL_CBCH51 0x0f
|
||||
#define GSMTAP_CHANNEL_VOICE_F 0x10
|
||||
#define GSMTAP_CHANNEL_VOICE_H 0x11
|
||||
|
||||
/* GPRS Coding Scheme CS1..4 */
|
||||
#define GSMTAP_GPRS_CS_BASE 0x20
|
||||
|
|
Loading…
Reference in New Issue