From 8f827d3b996d99cceb1784381d7522dc6f495a03 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Sun, 14 Mar 2021 02:30:05 +0100 Subject: [PATCH 01/18] osmo_trx: cosmetic: rename s/HDR version/PDU version/ TRXDv2 brings significant changes to the whole PDU structure, not just the header. Let's highlight this in the code / strings. --- epan/dissectors/packet-osmo_trx.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index 42cabdb99b1..41d4441a89b 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -3,6 +3,7 @@ * * (C) 2018 by Harald Welte <laforge@gnumonks.org> * (C) 2019 by Vadim Yanitskiy <axilirator@gmail.com> + * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * * Wireshark - Network traffic analyzer * By Gerald Combs <gerald@wireshark.org> @@ -33,8 +34,8 @@ static int proto_otrxc = -1; static int hf_otrxd_burst_dir = -1; static int hf_otrxc_msg_dir = -1; -/* TRXD header version */ -static int hf_otrxd_hdr_ver = -1; +/* TRXD PDU version */ +static int hf_otrxd_pdu_ver = -1; /* Common TDMA fields */ static int hf_otrxd_chdr_reserved = -1; @@ -73,7 +74,7 @@ static int hf_otrxc_status = -1; static gint ett_otrxd = -1; static gint ett_otrxc = -1; -static expert_field ei_otrxd_unknown_hdr_ver = EI_INIT; +static expert_field ei_otrxd_unknown_pdu_ver = EI_INIT; static expert_field ei_otrxd_injected_msg = EI_INIT; static expert_field ei_otrxd_unknown_dir = EI_INIT; @@ -273,11 +274,11 @@ static int dissect_otrxd_common_hdr(tvbuff_t *tvb, packet_info *pinfo, /* TRXD header version and TDMA time-slot number. * * | 7 6 5 4 3 2 1 0 | Bit numbers (value range) - * | X X X X . . . . | HDR version (0..15) + * | X X X X . . . . | TRXD PDU version (0..15) * | . . . . . X X X | TDMA time-slot number (0..7) * | . . . . X . . . | Reserved (0) */ - proto_tree_add_item_ret_uint(tree, hf_otrxd_hdr_ver, tvb, + proto_tree_add_item_ret_uint(tree, hf_otrxd_pdu_ver, tvb, offset, 1, ENC_NA, hdr_ver); proto_tree_add_item(tree, hf_otrxd_chdr_reserved, tvb, offset, 1, ENC_NA); @@ -311,8 +312,8 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, offset += dissect_otrxd_rx_hdr_v1(tvb, pinfo, ti, tree, offset); break; default: - expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_hdr_ver, - "Unknown TRXD header version %u", hdr_ver); + expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, + "Unknown TRXD PDU version %u", hdr_ver); return offset; } @@ -357,8 +358,8 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, offset++; break; default: - expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_hdr_ver, - "Unknown TRXD header version %u", hdr_ver); + expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, + "Unknown TRXD PDU version %u", hdr_ver); return offset; } @@ -571,7 +572,7 @@ void proto_register_osmo_trx(void) FT_UINT8, BASE_DEC, VALS(otrxcd_dir_vals), 0, NULL, HFILL } }, /* Common TRXD header fields */ - { &hf_otrxd_hdr_ver, { "Header Version", "osmo_trxd.hdr_ver", + { &hf_otrxd_pdu_ver, { "PDU Version", "osmo_trxd.pdu_ver", FT_UINT8, BASE_DEC, NULL, 0xf0, NULL, HFILL } }, { &hf_otrxd_chdr_reserved, { "Reserved", "osmo_trxd.chdr_reserved", FT_UINT8, BASE_DEC, NULL, 0x08, NULL, HFILL } }, @@ -653,8 +654,8 @@ void proto_register_osmo_trx(void) PI_COMMENTS_GROUP, PI_COMMENT, "Injected message", EXPFILL } }, { &ei_otrxd_unknown_dir, { "osmo_trx.ei.unknown_dir", PI_UNDECODED, PI_ERROR, "Unknown direction", EXPFILL } }, - { &ei_otrxd_unknown_hdr_ver, { "osmo_trxd.ei.unknown_hdr_ver", - PI_PROTOCOL, PI_WARN, "Unknown header version", EXPFILL } }, + { &ei_otrxd_unknown_pdu_ver, { "osmo_trxd.ei.unknown_pdu_ver", + PI_PROTOCOL, PI_WARN, "Unknown PDU version", EXPFILL } }, }; static ei_register_info ei_otrxc[] = { -- GitLab From 6cf5ed263c70b76fdad703f28312ce00f5700829 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Wed, 14 Apr 2021 04:14:16 +0200 Subject: [PATCH 02/18] osmo_trx: make the argument of format_rssi() const --- epan/dissectors/packet-osmo_trx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index 41d4441a89b..72ada127b41 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -104,7 +104,7 @@ static const value_string otrxd_mod_vals[] = { }; /* RSSI is encoded without a negative sign, so we need to show it */ -static void format_rssi(gchar *buf, guint32 rssi) +static void format_rssi(gchar *buf, const guint32 rssi) { g_snprintf(buf, ITEM_LABEL_LENGTH, "-%u%s", rssi, unit_name_string_get_value(rssi, &units_dbm)); } -- GitLab From 8ed012dc422a34e7bd597200b1d1b5fa5048fced Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Sun, 7 Mar 2021 22:54:24 +0100 Subject: [PATCH 03/18] osmo_trx: add a macro for GMSK modulated burst length --- epan/dissectors/packet-osmo_trx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index 72ada127b41..23e53c304e1 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -18,6 +18,8 @@ #include <epan/expert.h> #include <epan/unit_strings.h> +#define GMSK_BURST_LEN 148 + /* This is a non-standard, ad-hoc protocol to pass baseband GSM bursts between * the transceiver (such as osmo-trx, fake_trx.py or grgsm_trx) and the L1 * program (such as osmo-bts-trx or trxcon). Osmocom inherited this protocol @@ -321,7 +323,7 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, burst_len = tvb_reported_length(tvb) - offset; /* There can be two optional padding bytes -> detect them! */ - if (burst_len == 148 + 2 || burst_len == 444 + 2) { + if (burst_len == GMSK_BURST_LEN + 2 || burst_len == 3 * GMSK_BURST_LEN + 2) { burst_len -= 2; padding = 2; } @@ -375,11 +377,11 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, break; /* TODO: introduce an enumerated type, detect other modulation types, * TODO: add a generated field for "osmo_trxd.mod" */ - case 148: + case GMSK_BURST_LEN: col_append_str(pinfo->cinfo, COL_INFO, ", Modulation GMSK"); proto_item_append_text(ti, ", Modulation GMSK"); break; - case 444: + case 3 * GMSK_BURST_LEN: col_append_str(pinfo->cinfo, COL_INFO, ", Modulation 8-PSK"); proto_item_append_text(ti, ", Modulation 8-PSK"); break; -- GitLab From 8adf9742c966d668635f0497cfad2239ca1c3c5d Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Wed, 24 Feb 2021 19:48:34 +0100 Subject: [PATCH 04/18] osmo_trx: update coding of the MTS field in TRXDv1 --- epan/dissectors/packet-osmo_trx.c | 70 ++++++++++++++++++------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index 23e53c304e1..e66cc82db79 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -51,8 +51,9 @@ static int hf_otrxd_toa256 = -1; /* RX TRXD header, V1 specific fields */ static int hf_otrxd_nope_ind = -1; static int hf_otrxd_nope_ind_pad = -1; -static int hf_otrxd_mod_gmsk = -1; -static int hf_otrxd_mod_type = -1; +static int hf_otrxd_mod_2b = -1; /* 2 bit field */ +static int hf_otrxd_mod_3b = -1; /* 3 bit field */ +static int hf_otrxd_mod_4b = -1; /* 4 bit field */ static int hf_otrxd_tsc_set_x4 = -1; static int hf_otrxd_tsc_set_x2 = -1; static int hf_otrxd_tsc = -1; @@ -89,19 +90,25 @@ static expert_field ei_otrxc_unknown_dir = EI_INIT; /* Custom units */ static const unit_name_string otrx_units_toa256 = { " (1/256 of a symbol)", NULL }; -/* TRXD modulation types */ -static const value_string otrxd_mod_vals[] = { - /* NOTE: unlike the others, GMSK has 4 TSC sets, - * so the LSB bit is used to extend the value range. */ - { 0x00, "GMSK" }, - { 0x01, "GMSK" }, - { 0x02, "8-PSK" }, - { 0x03, "AQPSK" }, - { 0x04, "16QAM" }, - { 0x05, "32QAM" }, - /* Reserved for further use */ - { 0x06, "RESERVED" }, - { 0x07, "RESERVED" }, +/* TRXD modulation types (2 bit field) */ +static const value_string otrxd_mod_2b_vals[] = { + /* .00xx... */ { 0x00, "GMSK" }, + /* .11xx... */ { 0x03, "AQPSK" }, + { 0, NULL }, +}; + +/* TRXD modulation types (3 bit field) */ +static const value_string otrxd_mod_3b_vals[] = { + /* .010x... */ { 0x02, "8-PSK" }, + /* .100x... */ { 0x04, "16QAM" }, + /* .101x... */ { 0x05, "32QAM" }, + { 0, NULL }, +}; + +/* TRXD modulation types (4 bit field) */ +static const value_string otrxd_mod_4b_vals[] = { + /* .0110... */ { 0x06, "GMSK (Access Burst)" }, + /* .0111... */ { 0x07, "RFU (Reserved for Future Use)" }, { 0, NULL }, }; @@ -235,26 +242,30 @@ static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, * | 7 6 5 4 3 2 1 0 | Bit numbers (value range) * | . 0 0 X X . . . | GMSK, 4 TSC sets (0..3) * | . 0 1 0 X . . . | 8-PSK, 2 TSC sets (0..1) - * | . 0 1 1 X . . . | AQPSK, 2 TSC sets (0..1) + * | . 0 1 1 0 . . . | GMSK, Packet Access Burst + * | . 0 1 1 1 . . . | RFU (Reserved for Future Use) * | . 1 0 0 X . . . | 16QAM, 2 TSC sets (0..1) * | . 1 0 1 X . . . | 32QAM, 2 TSC sets (0..1) - * | . 1 1 0 X . . . | RESERVED (0) - * | . 1 1 1 X . . . | RESERVED (0) + * | . 1 1 X X . . . | AQPSK, 4 TSC sets (0..3) * - * NOTE: GMSK has 4 TSC sets, so bit 4 is used for range extension. + * NOTE: 3GPP defines 4 TSC sets for both GMSK and AQPSK. */ mts = tvb_get_guint8(tvb, offset); - if (((mts >> 5) & 0x03) == 0x00) { - proto_tree_add_item(tree, hf_otrxd_mod_gmsk, tvb, offset, 1, ENC_NA); + if ((mts >> 5) == 0x00 || (mts >> 5) == 0x03) { /* 2 bit: GMSK (0) or AQPSK (3) */ + mod_str = val_to_str(mts >> 5, otrxd_mod_2b_vals, "Unknown 0x%02x"); + proto_tree_add_item(tree, hf_otrxd_mod_2b, tvb, offset, 1, ENC_NA); proto_tree_add_item(tree, hf_otrxd_tsc_set_x4, tvb, offset, 1, ENC_NA); - } else { - proto_tree_add_item(tree, hf_otrxd_mod_type, tvb, offset, 1, ENC_NA); + } else if ((mts >> 4) != 0x03) { /* 3 bit: 8-PSK, 16QAM, or 32QAM */ + mod_str = val_to_str(mts >> 4, otrxd_mod_3b_vals, "Unknown 0x%02x"); + proto_tree_add_item(tree, hf_otrxd_mod_3b, tvb, offset, 1, ENC_NA); proto_tree_add_item(tree, hf_otrxd_tsc_set_x2, tvb, offset, 1, ENC_NA); + } else { /* 4 bit (without TSC set): GMSK (Packet Access Burst) or RFU */ + mod_str = val_to_str(mts >> 3, otrxd_mod_4b_vals, "Unknown 0x%02x"); + proto_tree_add_item(tree, hf_otrxd_mod_4b, tvb, offset, 1, ENC_NA); } proto_tree_add_item_ret_uint(tree, hf_otrxd_tsc, tvb, offset, 1, ENC_NA, &tsc); offset++; - mod_str = val_to_str((mts >> 4) & 0x07, otrxd_mod_vals, "Unknown 0x%02x"); col_append_fstr(pinfo->cinfo, COL_INFO, ", Modulation %s, TSC %u", mod_str, tsc); proto_item_append_text(ti, ", Modulation %s, TSC %u", mod_str, tsc); @@ -594,12 +605,15 @@ void proto_register_osmo_trx(void) FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL } }, { &hf_otrxd_nope_ind_pad, { "NOPE Padding", "osmo_trxd.nope_ind_pad", FT_UINT8, BASE_DEC, NULL, 0x7f, NULL, HFILL } }, - { &hf_otrxd_mod_type, { "Modulation", "osmo_trxd.mod", - FT_UINT8, BASE_DEC, VALS(otrxd_mod_vals), 0x70, NULL, HFILL } }, + + { &hf_otrxd_mod_2b, { "Modulation", "osmo_trxd.mod", + FT_UINT8, BASE_DEC, VALS(otrxd_mod_2b_vals), 0x60, NULL, HFILL } }, + { &hf_otrxd_mod_3b, { "Modulation", "osmo_trxd.mod", + FT_UINT8, BASE_DEC, VALS(otrxd_mod_3b_vals), 0x70, NULL, HFILL } }, + { &hf_otrxd_mod_4b, { "Modulation", "osmo_trxd.mod", + FT_UINT8, BASE_DEC, VALS(otrxd_mod_4b_vals), 0x78, NULL, HFILL } }, { &hf_otrxd_tsc_set_x2, { "TSC Set", "osmo_trxd.tsc_set", FT_UINT8, BASE_CUSTOM, CF_FUNC(format_tsc_set), 0x08, NULL, HFILL } }, - { &hf_otrxd_mod_gmsk, { "Modulation", "osmo_trxd.mod", - FT_UINT8, BASE_DEC, VALS(otrxd_mod_vals), 0x60, NULL, HFILL } }, { &hf_otrxd_tsc_set_x4, { "TSC Set", "osmo_trxd.tsc_set", FT_UINT8, BASE_CUSTOM, CF_FUNC(format_tsc_set), 0x18, NULL, HFILL } }, { &hf_otrxd_tsc, { "TSC (Training Sequence Code)", "osmo_trxd.tsc", -- GitLab From d893ee2af4828352c7e018ca2932702d0c8ffaa7 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Sun, 7 Mar 2021 22:48:46 +0100 Subject: [PATCH 05/18] osmo_trx: move MTS field dissector into a separate function --- epan/dissectors/packet-osmo_trx.c | 59 ++++++++++++++++++------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index e66cc82db79..76d0e573fab 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -196,32 +196,16 @@ static const value_string otrxc_msg_type_desc[] = { { 0, NULL }, }; -/* Dissector for Rx TRXD header version 0 */ -static int dissect_otrxd_rx_hdr_v0(tvbuff_t *tvb, packet_info *pinfo _U_, - proto_item *ti _U_, proto_tree *tree, - int offset) -{ - proto_tree_add_item(tree, hf_otrxd_rssi, tvb, offset++, 1, ENC_NA); - proto_tree_add_item(tree, hf_otrxd_toa256, tvb, offset, 2, ENC_NA); - - return 1 + 2; -} - -/* Dissector for Rx TRXD header version 1 */ -static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, - proto_item *ti, proto_tree *tree, - int offset) +/* Dissector for MTS (Modulation and Training Sequence) */ +static void dissect_otrxd_mts(tvbuff_t *tvb, packet_info *pinfo, + proto_item *ti, proto_tree *tree, + int offset) { const gchar *mod_str; gboolean nope_ind; guint32 mts, tsc; - int v0_hdr_len; - /* Dissect V0 specific part first */ - v0_hdr_len = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, offset); - offset += v0_hdr_len; - - /* NOPE indication does not contain MTS nor C/I. + /* NOPE indication contains no MTS information. * * | 7 6 5 4 3 2 1 0 | Bit numbers (value range) * | X . . . . . . . | NOPE / IDLE indication @@ -231,10 +215,10 @@ static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree_add_item_ret_boolean(tree, hf_otrxd_nope_ind, tvb, offset, 1, ENC_NA, &nope_ind); if (nope_ind) { - proto_tree_add_item(tree, hf_otrxd_nope_ind_pad, tvb, offset++, 1, ENC_NA); + proto_tree_add_item(tree, hf_otrxd_nope_ind_pad, tvb, offset, 1, ENC_NA); col_append_str(pinfo->cinfo, COL_INFO, ", NOPE.ind"); proto_item_append_text(ti, ", NOPE.ind"); - goto skip_mts; + return; } /* MTS (Modulation and Training Sequence info). @@ -263,13 +247,38 @@ static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, mod_str = val_to_str(mts >> 3, otrxd_mod_4b_vals, "Unknown 0x%02x"); proto_tree_add_item(tree, hf_otrxd_mod_4b, tvb, offset, 1, ENC_NA); } + proto_tree_add_item_ret_uint(tree, hf_otrxd_tsc, tvb, offset, 1, ENC_NA, &tsc); - offset++; col_append_fstr(pinfo->cinfo, COL_INFO, ", Modulation %s, TSC %u", mod_str, tsc); proto_item_append_text(ti, ", Modulation %s, TSC %u", mod_str, tsc); +} + +/* Dissector for Rx TRXD header version 0 */ +static int dissect_otrxd_rx_hdr_v0(tvbuff_t *tvb, packet_info *pinfo _U_, + proto_item *ti _U_, proto_tree *tree, + int offset) +{ + proto_tree_add_item(tree, hf_otrxd_rssi, tvb, offset++, 1, ENC_NA); + proto_tree_add_item(tree, hf_otrxd_toa256, tvb, offset, 2, ENC_NA); + + return 1 + 2; +} + +/* Dissector for Rx TRXD header version 1 */ +static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, + proto_item *ti, proto_tree *tree, + int offset) +{ + int v0_hdr_len; + + /* Dissect V0 specific part first */ + v0_hdr_len = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, offset); + offset += v0_hdr_len; + + /* MTS (Modulation and Training Sequence) */ + dissect_otrxd_mts(tvb, pinfo, ti, tree, offset++); -skip_mts: /* C/I (Carrier to Interference ratio) */ proto_tree_add_item(tree, hf_otrxd_ci, tvb, offset, 2, ENC_NA); -- GitLab From 233c3a10d5fb7bb85a7d1e97bb1c3f3a91041de1 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Wed, 17 Mar 2021 03:02:22 +0100 Subject: [PATCH 06/18] osmo_trx: add 'true_false_string' for NOPE.{ind,req} --- epan/dissectors/packet-osmo_trx.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index 76d0e573fab..aca893461e6 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -90,6 +90,12 @@ static expert_field ei_otrxc_unknown_dir = EI_INIT; /* Custom units */ static const unit_name_string otrx_units_toa256 = { " (1/256 of a symbol)", NULL }; +/* TRXD NOPE.{ind,req} value description */ +static const true_false_string otrxd_nope_bool_val = { + "Burst is not present", + "Burst is present", +}; + /* TRXD modulation types (2 bit field) */ static const value_string otrxd_mod_2b_vals[] = { /* .00xx... */ { 0x00, "GMSK" }, @@ -611,7 +617,7 @@ void proto_register_osmo_trx(void) /* Rx TRXD header, V1 specific fields */ { &hf_otrxd_nope_ind, { "NOPE Indication", "osmo_trxd.nope_ind", - FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL } }, + FT_BOOLEAN, 8, TFS(&otrxd_nope_bool_val), 0x80, NULL, HFILL } }, { &hf_otrxd_nope_ind_pad, { "NOPE Padding", "osmo_trxd.nope_ind_pad", FT_UINT8, BASE_DEC, NULL, 0x7f, NULL, HFILL } }, -- GitLab From d7328d4e1e35c3c34ae7071e2376a1feb99914b3 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Sun, 7 Mar 2021 23:19:22 +0100 Subject: [PATCH 07/18] osmo_trx: return offset from dissect_otrxd_rx_hdr_*() --- epan/dissectors/packet-osmo_trx.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index aca893461e6..871e247f9c3 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -267,8 +267,9 @@ static int dissect_otrxd_rx_hdr_v0(tvbuff_t *tvb, packet_info *pinfo _U_, { proto_tree_add_item(tree, hf_otrxd_rssi, tvb, offset++, 1, ENC_NA); proto_tree_add_item(tree, hf_otrxd_toa256, tvb, offset, 2, ENC_NA); + offset += 2; - return 1 + 2; + return offset; } /* Dissector for Rx TRXD header version 1 */ @@ -276,19 +277,17 @@ static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, proto_tree *tree, int offset) { - int v0_hdr_len; - /* Dissect V0 specific part first */ - v0_hdr_len = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, offset); - offset += v0_hdr_len; + offset = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, offset); /* MTS (Modulation and Training Sequence) */ dissect_otrxd_mts(tvb, pinfo, ti, tree, offset++); /* C/I (Carrier to Interference ratio) */ proto_tree_add_item(tree, hf_otrxd_ci, tvb, offset, 2, ENC_NA); + offset += 2; - return v0_hdr_len + 1 + 2; + return offset; } /* Dissector for common Rx/Tx TRXD header part */ @@ -334,10 +333,10 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, /* Parse version specific TRXD header part */ switch (hdr_ver) { case 0: - offset += dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, offset); + offset = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, offset); break; case 1: - offset += dissect_otrxd_rx_hdr_v1(tvb, pinfo, ti, tree, offset); + offset = dissect_otrxd_rx_hdr_v1(tvb, pinfo, ti, tree, offset); break; default: expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, -- GitLab From ed12e1bde1d550cfa68586632a2fc785a88888f2 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Sun, 14 Mar 2021 01:41:14 +0100 Subject: [PATCH 08/18] osmo_trx: store essential PDU information in a structure --- epan/dissectors/packet-osmo_trx.c | 44 ++++++++++++++++++------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index 871e247f9c3..5223d80e26e 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -202,6 +202,16 @@ static const value_string otrxc_msg_type_desc[] = { { 0, NULL }, }; +/* TRXD PDU information */ +struct otrxd_pdu_info { + /* PDU version */ + guint32 ver; + /* TDMA frame number */ + guint32 fn; + /* TDMA timeslot number */ + guint32 tn; +}; + /* Dissector for MTS (Modulation and Training Sequence) */ static void dissect_otrxd_mts(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, proto_tree *tree, @@ -293,9 +303,8 @@ static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, /* Dissector for common Rx/Tx TRXD header part */ static int dissect_otrxd_common_hdr(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, proto_tree *tree, - guint32 *hdr_ver) + struct otrxd_pdu_info *pi) { - guint32 tdma_tn, tdma_fn; int offset = 0; /* TRXD header version and TDMA time-slot number. @@ -306,19 +315,19 @@ static int dissect_otrxd_common_hdr(tvbuff_t *tvb, packet_info *pinfo, * | . . . . X . . . | Reserved (0) */ proto_tree_add_item_ret_uint(tree, hf_otrxd_pdu_ver, tvb, - offset, 1, ENC_NA, hdr_ver); + offset, 1, ENC_NA, &pi->ver); proto_tree_add_item(tree, hf_otrxd_chdr_reserved, tvb, offset, 1, ENC_NA); proto_tree_add_item_ret_uint(tree, hf_otrxd_tdma_tn, tvb, - offset, 1, ENC_NA, &tdma_tn); + offset, 1, ENC_NA, &pi->tn); offset++; /* TDMA frame number (4 octets, big endian) */ proto_tree_add_item_ret_uint(tree, hf_otrxd_tdma_fn, tvb, - offset, 4, ENC_BIG_ENDIAN, &tdma_fn); + offset, 4, ENC_BIG_ENDIAN, &pi->fn); - col_append_fstr(pinfo->cinfo, COL_INFO, "TDMA FN %07u TN %u", tdma_fn, tdma_tn); - proto_item_append_text(ti, ", TDMA FN %07u TN %u", tdma_fn, tdma_tn); + col_append_fstr(pinfo->cinfo, COL_INFO, "TDMA FN %07u TN %u", pi->fn, pi->tn); + proto_item_append_text(ti, ", TDMA FN %07u TN %u", pi->fn, pi->tn); return 1 + 4; } @@ -326,12 +335,12 @@ static int dissect_otrxd_common_hdr(tvbuff_t *tvb, packet_info *pinfo, /* Burst data in Receive direction */ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, proto_tree *tree, - int offset, guint32 hdr_ver) + struct otrxd_pdu_info *pi, int offset) { int burst_len, padding = 0; /* Parse version specific TRXD header part */ - switch (hdr_ver) { + switch (pi->ver) { case 0: offset = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, offset); break; @@ -340,7 +349,7 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, break; default: expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, - "Unknown TRXD PDU version %u", hdr_ver); + "Unknown TRXD PDU version %u", pi->ver); return offset; } @@ -372,12 +381,12 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, /* Burst data in Transmit direction */ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti _U_, proto_tree *tree, - int offset, guint32 hdr_ver) + struct otrxd_pdu_info *pi, int offset) { int burst_len; /* Parse version specific TRXD header part */ - switch (hdr_ver) { + switch (pi->ver) { /* Both versions feature the same header format */ case 0: case 1: @@ -386,7 +395,7 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, break; default: expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, - "Unknown TRXD PDU version %u", hdr_ver); + "Unknown TRXD PDU version %u", pi->ver); return offset; } @@ -425,10 +434,9 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, static int dissect_otrxd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { - + struct otrxd_pdu_info pi = { 0 }; proto_tree *otrxd_tree; proto_item *ti, *gi; - guint32 hdr_ver; int offset, rc; col_set_str(pinfo->cinfo, COL_PROTOCOL, "OsmoTRXD"); @@ -461,12 +469,12 @@ static int dissect_otrxd(tvbuff_t *tvb, packet_info *pinfo, proto_item_set_generated(gi); /* Parse common TRXD header part */ - offset = dissect_otrxd_common_hdr(tvb, pinfo, ti, otrxd_tree, &hdr_ver); + offset = dissect_otrxd_common_hdr(tvb, pinfo, ti, otrxd_tree, &pi); if (burst_dir == OTRXCD_DIR_L12TRX) - rc = dissect_otrxd_tx(tvb, pinfo, ti, otrxd_tree, offset, hdr_ver); + rc = dissect_otrxd_tx(tvb, pinfo, ti, otrxd_tree, &pi, offset); else if (burst_dir == OTRXCD_DIR_TRX2L1) - rc = dissect_otrxd_rx(tvb, pinfo, ti, otrxd_tree, offset, hdr_ver); + rc = dissect_otrxd_rx(tvb, pinfo, ti, otrxd_tree, &pi, offset); else { expert_add_info(pinfo, ti, &ei_otrxd_unknown_dir); rc = offset; -- GitLab From 06719b9c317930ad27cfc4ac8258352cd8027232 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Sun, 14 Mar 2021 03:57:07 +0100 Subject: [PATCH 09/18] osmo_trx: dissect_otrxd_mts(): store dissection results --- epan/dissectors/packet-osmo_trx.c | 54 +++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index 5223d80e26e..107ac6598ae 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -118,6 +118,17 @@ static const value_string otrxd_mod_4b_vals[] = { { 0, NULL }, }; +/* TRXD modulation type */ +enum otrxd_mod_type { + OTRXD_MOD_T_GMSK = 0x00, + OTRXD_MOD_T_8PSK = 0x02, + OTRXD_MOD_T_AQPSK = 0x03, + OTRXD_MOD_T_16QAM = 0x04, + OTRXD_MOD_T_32QAM = 0x05, + OTRXD_MOD_T_GMSK_AB = 0x06, + OTRXD_MOD_T_RFU = 0x07, +}; + /* RSSI is encoded without a negative sign, so we need to show it */ static void format_rssi(gchar *buf, const guint32 rssi) { @@ -210,17 +221,21 @@ struct otrxd_pdu_info { guint32 fn; /* TDMA timeslot number */ guint32 tn; + /* NOPE.{ind,req} marker */ + gboolean nope; + /* Modulation type and string */ + enum otrxd_mod_type mod; + const gchar *mod_str; + /* Training Sequence Code */ + guint32 tsc; }; /* Dissector for MTS (Modulation and Training Sequence) */ static void dissect_otrxd_mts(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, proto_tree *tree, + struct otrxd_pdu_info *pi, int offset) { - const gchar *mod_str; - gboolean nope_ind; - guint32 mts, tsc; - /* NOPE indication contains no MTS information. * * | 7 6 5 4 3 2 1 0 | Bit numbers (value range) @@ -229,8 +244,8 @@ static void dissect_otrxd_mts(tvbuff_t *tvb, packet_info *pinfo, * | . . . . . X X X | TSC (Training Sequence Code) */ proto_tree_add_item_ret_boolean(tree, hf_otrxd_nope_ind, tvb, - offset, 1, ENC_NA, &nope_ind); - if (nope_ind) { + offset, 1, ENC_NA, &pi->nope); + if (pi->nope) { proto_tree_add_item(tree, hf_otrxd_nope_ind_pad, tvb, offset, 1, ENC_NA); col_append_str(pinfo->cinfo, COL_INFO, ", NOPE.ind"); proto_item_append_text(ti, ", NOPE.ind"); @@ -250,29 +265,33 @@ static void dissect_otrxd_mts(tvbuff_t *tvb, packet_info *pinfo, * * NOTE: 3GPP defines 4 TSC sets for both GMSK and AQPSK. */ - mts = tvb_get_guint8(tvb, offset); + guint8 mts = tvb_get_guint8(tvb, offset); if ((mts >> 5) == 0x00 || (mts >> 5) == 0x03) { /* 2 bit: GMSK (0) or AQPSK (3) */ - mod_str = val_to_str(mts >> 5, otrxd_mod_2b_vals, "Unknown 0x%02x"); + pi->mod = (enum otrxd_mod_type) (mts >> 5); + pi->mod_str = val_to_str(mts >> 5, otrxd_mod_2b_vals, "Unknown 0x%02x"); proto_tree_add_item(tree, hf_otrxd_mod_2b, tvb, offset, 1, ENC_NA); proto_tree_add_item(tree, hf_otrxd_tsc_set_x4, tvb, offset, 1, ENC_NA); } else if ((mts >> 4) != 0x03) { /* 3 bit: 8-PSK, 16QAM, or 32QAM */ - mod_str = val_to_str(mts >> 4, otrxd_mod_3b_vals, "Unknown 0x%02x"); + pi->mod = (enum otrxd_mod_type) (mts >> 4); + pi->mod_str = val_to_str(mts >> 4, otrxd_mod_3b_vals, "Unknown 0x%02x"); proto_tree_add_item(tree, hf_otrxd_mod_3b, tvb, offset, 1, ENC_NA); proto_tree_add_item(tree, hf_otrxd_tsc_set_x2, tvb, offset, 1, ENC_NA); } else { /* 4 bit (without TSC set): GMSK (Packet Access Burst) or RFU */ - mod_str = val_to_str(mts >> 3, otrxd_mod_4b_vals, "Unknown 0x%02x"); + pi->mod = (enum otrxd_mod_type) (mts >> 3); + pi->mod_str = val_to_str(mts >> 3, otrxd_mod_4b_vals, "Unknown 0x%02x"); proto_tree_add_item(tree, hf_otrxd_mod_4b, tvb, offset, 1, ENC_NA); } - proto_tree_add_item_ret_uint(tree, hf_otrxd_tsc, tvb, offset, 1, ENC_NA, &tsc); + proto_tree_add_item_ret_uint(tree, hf_otrxd_tsc, tvb, offset, 1, ENC_NA, &pi->tsc); - col_append_fstr(pinfo->cinfo, COL_INFO, ", Modulation %s, TSC %u", mod_str, tsc); - proto_item_append_text(ti, ", Modulation %s, TSC %u", mod_str, tsc); + col_append_fstr(pinfo->cinfo, COL_INFO, ", Modulation %s, TSC %u", pi->mod_str, pi->tsc); + proto_item_append_text(ti, ", Modulation %s, TSC %u", pi->mod_str, pi->tsc); } /* Dissector for Rx TRXD header version 0 */ static int dissect_otrxd_rx_hdr_v0(tvbuff_t *tvb, packet_info *pinfo _U_, proto_item *ti _U_, proto_tree *tree, + struct otrxd_pdu_info *pi _U_, int offset) { proto_tree_add_item(tree, hf_otrxd_rssi, tvb, offset++, 1, ENC_NA); @@ -285,13 +304,14 @@ static int dissect_otrxd_rx_hdr_v0(tvbuff_t *tvb, packet_info *pinfo _U_, /* Dissector for Rx TRXD header version 1 */ static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, proto_tree *tree, + struct otrxd_pdu_info *pi, int offset) { /* Dissect V0 specific part first */ - offset = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, offset); + offset = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, pi, offset); /* MTS (Modulation and Training Sequence) */ - dissect_otrxd_mts(tvb, pinfo, ti, tree, offset++); + dissect_otrxd_mts(tvb, pinfo, ti, tree, pi, offset++); /* C/I (Carrier to Interference ratio) */ proto_tree_add_item(tree, hf_otrxd_ci, tvb, offset, 2, ENC_NA); @@ -342,10 +362,10 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, /* Parse version specific TRXD header part */ switch (pi->ver) { case 0: - offset = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, offset); + offset = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, pi, offset); break; case 1: - offset = dissect_otrxd_rx_hdr_v1(tvb, pinfo, ti, tree, offset); + offset = dissect_otrxd_rx_hdr_v1(tvb, pinfo, ti, tree, pi, offset); break; default: expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, -- GitLab From 8786ffb61150ab23f14ea8caff198ee7cabce890 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Sun, 14 Mar 2021 04:42:18 +0100 Subject: [PATCH 10/18] osmo_trx: refactor version specific handling of burst bits --- epan/dissectors/packet-osmo_trx.c | 70 ++++++++++++++++++------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index 107ac6598ae..28be70f63f2 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -18,8 +18,6 @@ #include <epan/expert.h> #include <epan/unit_strings.h> -#define GMSK_BURST_LEN 148 - /* This is a non-standard, ad-hoc protocol to pass baseband GSM bursts between * the transceiver (such as osmo-trx, fake_trx.py or grgsm_trx) and the L1 * program (such as osmo-bts-trx or trxcon). Osmocom inherited this protocol @@ -129,6 +127,20 @@ enum otrxd_mod_type { OTRXD_MOD_T_RFU = 0x07, }; +/* See 3GPP TS 45.002, section 5.2 "Bursts" */ +#define GMSK_BURST_LEN 148 + +/* TRXD modulation / burst length mapping */ +static const guint16 otrxd_burst_len[] = { + [OTRXD_MOD_T_GMSK] = GMSK_BURST_LEN * 1, + [OTRXD_MOD_T_GMSK_AB] = GMSK_BURST_LEN * 1, + [OTRXD_MOD_T_AQPSK] = GMSK_BURST_LEN * 2, + [OTRXD_MOD_T_8PSK] = GMSK_BURST_LEN * 3, + [OTRXD_MOD_T_16QAM] = GMSK_BURST_LEN * 4, + [OTRXD_MOD_T_32QAM] = GMSK_BURST_LEN * 5, + [OTRXD_MOD_T_RFU] = 0, /* unknown */ +}; + /* RSSI is encoded without a negative sign, so we need to show it */ static void format_rssi(gchar *buf, const guint32 rssi) { @@ -357,15 +369,36 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, proto_tree *tree, struct otrxd_pdu_info *pi, int offset) { - int burst_len, padding = 0; + int burst_len, padding; /* Parse version specific TRXD header part */ switch (pi->ver) { case 0: offset = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, pi, offset); + /* The remaining octets is basically soft-bits of the burst */ + burst_len = tvb_reported_length(tvb) - offset; + /* ... there must be at least 148 soft-bits */ + if (burst_len < GMSK_BURST_LEN) + burst_len = GMSK_BURST_LEN; /* let it crash! */ + /* ... there can be 2 optional padding octets in the end */ + padding = burst_len % GMSK_BURST_LEN; + proto_tree_add_item(tree, hf_otrxd_soft_symbols, tvb, + offset, burst_len - padding, ENC_NA); + offset += burst_len - padding; + if (padding == 0) + break; + proto_tree_add_item(tree, hf_otrxd_burst_pad, tvb, + offset, padding, ENC_NA); + offset += padding; break; case 1: offset = dissect_otrxd_rx_hdr_v1(tvb, pinfo, ti, tree, pi, offset); + if (pi->nope) /* NOPE.ind contains no burst */ + break; + burst_len = otrxd_burst_len[pi->mod]; + proto_tree_add_item(tree, hf_otrxd_soft_symbols, tvb, + offset, burst_len, ENC_NA); + offset += burst_len; break; default: expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, @@ -373,28 +406,6 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, return offset; } - /* Calculate the burst length */ - burst_len = tvb_reported_length(tvb) - offset; - - /* There can be two optional padding bytes -> detect them! */ - if (burst_len == GMSK_BURST_LEN + 2 || burst_len == 3 * GMSK_BURST_LEN + 2) { - burst_len -= 2; - padding = 2; - } - - /* Soft-bits (255..0) */ - if (burst_len > 0) { - proto_tree_add_item(tree, hf_otrxd_soft_symbols, tvb, - offset, burst_len, ENC_NA); - offset += burst_len; - } - - /* Optional padding */ - if (padding > 0) { - proto_tree_add_item(tree, hf_otrxd_burst_pad, tvb, - offset, padding, ENC_NA); - } - return tvb_captured_length(tvb); } @@ -428,7 +439,8 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, case 0: col_append_str(pinfo->cinfo, COL_INFO, ", NOPE.req"); proto_item_append_text(ti, ", NOPE.req"); - break; + return offset; + /* TODO: introduce an enumerated type, detect other modulation types, * TODO: add a generated field for "osmo_trxd.mod" */ case GMSK_BURST_LEN: @@ -442,10 +454,8 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, } /* Hard-bits (1 or 0) */ - if (burst_len > 0) { - proto_tree_add_item(tree, hf_otrxd_hard_symbols, tvb, - offset, burst_len, ENC_NA); - } + proto_tree_add_item(tree, hf_otrxd_hard_symbols, tvb, + offset, burst_len, ENC_NA); return tvb_captured_length(tvb); } -- GitLab From 92a24506a0858f520c75628c3d36c1e8b4fda2aa Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Tue, 16 Mar 2021 22:51:49 +0100 Subject: [PATCH 11/18] osmo_trx: 'Unknown PDU version' is an error, not warning --- epan/dissectors/packet-osmo_trx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index 28be70f63f2..6ab030996bb 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -723,7 +723,7 @@ void proto_register_osmo_trx(void) { &ei_otrxd_unknown_dir, { "osmo_trx.ei.unknown_dir", PI_UNDECODED, PI_ERROR, "Unknown direction", EXPFILL } }, { &ei_otrxd_unknown_pdu_ver, { "osmo_trxd.ei.unknown_pdu_ver", - PI_PROTOCOL, PI_WARN, "Unknown PDU version", EXPFILL } }, + PI_PROTOCOL, PI_ERROR, "Unknown PDU version", EXPFILL } }, }; static ei_register_info ei_otrxc[] = { -- GitLab From 1e11273663b6838ce6645abc8575980910fc23f6 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Sun, 14 Mar 2021 05:19:23 +0100 Subject: [PATCH 12/18] osmo_trx: let it warn us if there are unhandled tail octets --- epan/dissectors/packet-osmo_trx.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index 6ab030996bb..b7ba3903b82 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -78,6 +78,7 @@ static gint ett_otrxc = -1; static expert_field ei_otrxd_unknown_pdu_ver = EI_INIT; static expert_field ei_otrxd_injected_msg = EI_INIT; static expert_field ei_otrxd_unknown_dir = EI_INIT; +static expert_field ei_otrxd_tail_octets = EI_INIT; static expert_field ei_otrxc_unknown_msg_type = EI_INIT; static expert_field ei_otrxc_bad_delimiter = EI_INIT; @@ -403,10 +404,10 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, default: expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, "Unknown TRXD PDU version %u", pi->ver); - return offset; + offset = 1; /* Only the PDU version was parsed */ } - return tvb_captured_length(tvb); + return offset; } /* Burst data in Transmit direction */ @@ -427,6 +428,7 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, default: expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, "Unknown TRXD PDU version %u", pi->ver); + offset = 1; /* Only the PDU version was parsed */ return offset; } @@ -456,8 +458,9 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, /* Hard-bits (1 or 0) */ proto_tree_add_item(tree, hf_otrxd_hard_symbols, tvb, offset, burst_len, ENC_NA); + offset += burst_len; - return tvb_captured_length(tvb); + return offset; } /* Common dissector for bursts in both directions */ @@ -467,7 +470,7 @@ static int dissect_otrxd(tvbuff_t *tvb, packet_info *pinfo, struct otrxd_pdu_info pi = { 0 }; proto_tree *otrxd_tree; proto_item *ti, *gi; - int offset, rc; + int offset; col_set_str(pinfo->cinfo, COL_PROTOCOL, "OsmoTRXD"); col_clear(pinfo->cinfo, COL_INFO); @@ -502,15 +505,21 @@ static int dissect_otrxd(tvbuff_t *tvb, packet_info *pinfo, offset = dissect_otrxd_common_hdr(tvb, pinfo, ti, otrxd_tree, &pi); if (burst_dir == OTRXCD_DIR_L12TRX) - rc = dissect_otrxd_tx(tvb, pinfo, ti, otrxd_tree, &pi, offset); + offset = dissect_otrxd_tx(tvb, pinfo, ti, otrxd_tree, &pi, offset); else if (burst_dir == OTRXCD_DIR_TRX2L1) - rc = dissect_otrxd_rx(tvb, pinfo, ti, otrxd_tree, &pi, offset); + offset = dissect_otrxd_rx(tvb, pinfo, ti, otrxd_tree, &pi, offset); else { expert_add_info(pinfo, ti, &ei_otrxd_unknown_dir); - rc = offset; + offset = 1; /* Only the PDU version was parsed */ } - return rc; + proto_item_set_len(ti, offset); + + /* Let it warn us if there are unhandled tail octets */ + if ((guint) offset < tvb_reported_length(tvb)) + expert_add_info(pinfo, ti, &ei_otrxd_tail_octets); + + return offset; } /* Dissector for Control commands and responses, and Clock indications */ @@ -724,6 +733,8 @@ void proto_register_osmo_trx(void) PI_UNDECODED, PI_ERROR, "Unknown direction", EXPFILL } }, { &ei_otrxd_unknown_pdu_ver, { "osmo_trxd.ei.unknown_pdu_ver", PI_PROTOCOL, PI_ERROR, "Unknown PDU version", EXPFILL } }, + { &ei_otrxd_tail_octets, { "osmo_trxd.ei.tail_octets", + PI_UNDECODED, PI_WARN, "Unhandled tail octets", EXPFILL } }, }; static ei_register_info ei_otrxc[] = { -- GitLab From 36d75a96827638f74739a59a5b19ea1ac0a833fd Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Tue, 16 Mar 2021 21:09:55 +0100 Subject: [PATCH 13/18] osmo_trx: dissect_otrxd_common_hdr() is not common anymore The upcoming TRXDv2 brings significant changes, not only adding new fields but also changing order and presence of those that were considered common so far. Let's rename this function to reflect that it's TRXDv0/v1 specific, and call it directly from the corresponding dissection functions. --- epan/dissectors/packet-osmo_trx.c | 70 ++++++++++++++----------------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index b7ba3903b82..cf5bcad72b4 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -243,6 +243,27 @@ struct otrxd_pdu_info { guint32 tsc; }; +/* Dissector for common Rx/Tx TRXDv0/v1 header part */ +static void dissect_otrxd_chdr_v0(tvbuff_t *tvb, packet_info *pinfo, + proto_item *ti, proto_tree *tree, + struct otrxd_pdu_info *pi, + int *offset) +{ + proto_tree_add_item(tree, hf_otrxd_chdr_reserved, tvb, + *offset, 1, ENC_NA); + proto_tree_add_item_ret_uint(tree, hf_otrxd_tdma_tn, tvb, + *offset, 1, ENC_NA, &pi->tn); + *offset += 1; + + /* TDMA frame number (4 octets, big endian) */ + proto_tree_add_item_ret_uint(tree, hf_otrxd_tdma_fn, tvb, + *offset, 4, ENC_BIG_ENDIAN, &pi->fn); + *offset += 4; + + col_append_fstr(pinfo->cinfo, COL_INFO, "TDMA FN %07u TN %u", pi->fn, pi->tn); + proto_item_append_text(ti, ", TDMA FN %07u TN %u", pi->fn, pi->tn); +} + /* Dissector for MTS (Modulation and Training Sequence) */ static void dissect_otrxd_mts(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, proto_tree *tree, @@ -302,11 +323,13 @@ static void dissect_otrxd_mts(tvbuff_t *tvb, packet_info *pinfo, } /* Dissector for Rx TRXD header version 0 */ -static int dissect_otrxd_rx_hdr_v0(tvbuff_t *tvb, packet_info *pinfo _U_, - proto_item *ti _U_, proto_tree *tree, - struct otrxd_pdu_info *pi _U_, +static int dissect_otrxd_rx_hdr_v0(tvbuff_t *tvb, packet_info *pinfo, + proto_item *ti, proto_tree *tree, + struct otrxd_pdu_info *pi, int offset) { + dissect_otrxd_chdr_v0(tvb, pinfo, ti, tree, pi, &offset); + proto_tree_add_item(tree, hf_otrxd_rssi, tvb, offset++, 1, ENC_NA); proto_tree_add_item(tree, hf_otrxd_toa256, tvb, offset, 2, ENC_NA); offset += 2; @@ -333,38 +356,6 @@ static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, return offset; } -/* Dissector for common Rx/Tx TRXD header part */ -static int dissect_otrxd_common_hdr(tvbuff_t *tvb, packet_info *pinfo, - proto_item *ti, proto_tree *tree, - struct otrxd_pdu_info *pi) -{ - int offset = 0; - - /* TRXD header version and TDMA time-slot number. - * - * | 7 6 5 4 3 2 1 0 | Bit numbers (value range) - * | X X X X . . . . | TRXD PDU version (0..15) - * | . . . . . X X X | TDMA time-slot number (0..7) - * | . . . . X . . . | Reserved (0) - */ - proto_tree_add_item_ret_uint(tree, hf_otrxd_pdu_ver, tvb, - offset, 1, ENC_NA, &pi->ver); - proto_tree_add_item(tree, hf_otrxd_chdr_reserved, tvb, - offset, 1, ENC_NA); - proto_tree_add_item_ret_uint(tree, hf_otrxd_tdma_tn, tvb, - offset, 1, ENC_NA, &pi->tn); - offset++; - - /* TDMA frame number (4 octets, big endian) */ - proto_tree_add_item_ret_uint(tree, hf_otrxd_tdma_fn, tvb, - offset, 4, ENC_BIG_ENDIAN, &pi->fn); - - col_append_fstr(pinfo->cinfo, COL_INFO, "TDMA FN %07u TN %u", pi->fn, pi->tn); - proto_item_append_text(ti, ", TDMA FN %07u TN %u", pi->fn, pi->tn); - - return 1 + 4; -} - /* Burst data in Receive direction */ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti, proto_tree *tree, @@ -422,6 +413,7 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, /* Both versions feature the same header format */ case 0: case 1: + dissect_otrxd_chdr_v0(tvb, pinfo, ti, tree, pi, &offset); proto_tree_add_item(tree, hf_otrxd_tx_att, tvb, offset, 1, ENC_NA); offset++; break; @@ -470,12 +462,11 @@ static int dissect_otrxd(tvbuff_t *tvb, packet_info *pinfo, struct otrxd_pdu_info pi = { 0 }; proto_tree *otrxd_tree; proto_item *ti, *gi; - int offset; + int offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "OsmoTRXD"); col_clear(pinfo->cinfo, COL_INFO); - /* Common TRXD header tree (1 + 4 bytes) */ ti = proto_tree_add_item(tree, proto_otrxd, tvb, 0, -1, ENC_NA); otrxd_tree = proto_item_add_subtree(ti, ett_otrxd); @@ -501,8 +492,9 @@ static int dissect_otrxd(tvbuff_t *tvb, packet_info *pinfo, tvb, 0, 0, burst_dir); proto_item_set_generated(gi); - /* Parse common TRXD header part */ - offset = dissect_otrxd_common_hdr(tvb, pinfo, ti, otrxd_tree, &pi); + /* Parse common TRXD PDU version */ + proto_tree_add_item_ret_uint(otrxd_tree, hf_otrxd_pdu_ver, tvb, + offset, 1, ENC_NA, &pi.ver); if (burst_dir == OTRXCD_DIR_L12TRX) offset = dissect_otrxd_tx(tvb, pinfo, ti, otrxd_tree, &pi, offset); -- GitLab From 7d0fa4af18f91812687f88e4285f9a95f025da9f Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Wed, 17 Mar 2021 01:25:46 +0100 Subject: [PATCH 14/18] osmo_trx: separate TRXDv0/v1 Tx burst dissection function --- epan/dissectors/packet-osmo_trx.c | 56 +++++++++++++++++-------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index cf5bcad72b4..aea774dac2b 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -401,31 +401,13 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, return offset; } -/* Burst data in Transmit direction */ -static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, - proto_item *ti _U_, proto_tree *tree, - struct otrxd_pdu_info *pi, int offset) +/* Dissector for TRXDv0/v1 Tx burst */ +static void dissect_otrxd_tx_burst_v0(tvbuff_t *tvb, packet_info *pinfo, + proto_item *ti, proto_tree *tree, + int *offset) { - int burst_len; - - /* Parse version specific TRXD header part */ - switch (pi->ver) { - /* Both versions feature the same header format */ - case 0: - case 1: - dissect_otrxd_chdr_v0(tvb, pinfo, ti, tree, pi, &offset); - proto_tree_add_item(tree, hf_otrxd_tx_att, tvb, offset, 1, ENC_NA); - offset++; - break; - default: - expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, - "Unknown TRXD PDU version %u", pi->ver); - offset = 1; /* Only the PDU version was parsed */ - return offset; - } - /* Calculate the burst length */ - burst_len = tvb_reported_length(tvb) - offset; + const int burst_len = tvb_reported_length(tvb) - *offset; /* Attempt to guess modulation by the length */ switch (burst_len) { @@ -433,7 +415,7 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, case 0: col_append_str(pinfo->cinfo, COL_INFO, ", NOPE.req"); proto_item_append_text(ti, ", NOPE.req"); - return offset; + return; /* TODO: introduce an enumerated type, detect other modulation types, * TODO: add a generated field for "osmo_trxd.mod" */ @@ -449,8 +431,30 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, /* Hard-bits (1 or 0) */ proto_tree_add_item(tree, hf_otrxd_hard_symbols, tvb, - offset, burst_len, ENC_NA); - offset += burst_len; + *offset, burst_len, ENC_NA); + *offset += burst_len; +} + +/* Burst data in Transmit direction */ +static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, + proto_item *ti, proto_tree *tree, + struct otrxd_pdu_info *pi, + int offset) +{ + switch (pi->ver) { + /* Both versions feature the same PDU format */ + case 0: + case 1: + dissect_otrxd_chdr_v0(tvb, pinfo, ti, tree, pi, &offset); + proto_tree_add_item(tree, hf_otrxd_tx_att, tvb, offset++, 1, ENC_NA); + dissect_otrxd_tx_burst_v0(tvb, pinfo, ti, tree, &offset); + break; + default: + expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, + "Unknown TRXD PDU version %u", pi->ver); + offset = 1; /* Only the PDU version was parsed */ + return offset; + } return offset; } -- GitLab From 859d1c74cc4eab522e136f59133ce5e03d10d848 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Wed, 17 Mar 2021 01:49:38 +0100 Subject: [PATCH 15/18] osmo_trx: dissect version-specific content in sub-trees --- epan/dissectors/packet-osmo_trx.c | 43 ++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index aea774dac2b..de97fc93c27 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -75,6 +75,9 @@ static int hf_otrxc_status = -1; static gint ett_otrxd = -1; static gint ett_otrxc = -1; +static gint ett_otrxd_rx_pdu = -1; +static gint ett_otrxd_tx_pdu = -1; + static expert_field ei_otrxd_unknown_pdu_ver = EI_INIT; static expert_field ei_otrxd_injected_msg = EI_INIT; static expert_field ei_otrxd_unknown_dir = EI_INIT; @@ -261,7 +264,7 @@ static void dissect_otrxd_chdr_v0(tvbuff_t *tvb, packet_info *pinfo, *offset += 4; col_append_fstr(pinfo->cinfo, COL_INFO, "TDMA FN %07u TN %u", pi->fn, pi->tn); - proto_item_append_text(ti, ", TDMA FN %07u TN %u", pi->fn, pi->tn); + proto_item_append_text(ti, "TDMA FN %07u TN %u", pi->fn, pi->tn); } /* Dissector for MTS (Modulation and Training Sequence) */ @@ -358,10 +361,19 @@ static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, /* Burst data in Receive direction */ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, - proto_item *ti, proto_tree *tree, - struct otrxd_pdu_info *pi, int offset) + proto_item *pti, proto_tree *ptree, + struct otrxd_pdu_info *pi, + int offset) { - int burst_len, padding; + int start, burst_len, padding; + proto_tree *tree; + proto_item *ti; + + /* Add a sub-tree for each PDU (length is set below) */ + tree = proto_tree_add_subtree(ptree, tvb, offset, -1, + ett_otrxd_rx_pdu, &ti, + "TRXD Rx PDU: "); + start = offset; /* Parse version specific TRXD header part */ switch (pi->ver) { @@ -393,11 +405,14 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, offset += burst_len; break; default: - expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, + expert_add_info_format(pinfo, pti, &ei_otrxd_unknown_pdu_ver, "Unknown TRXD PDU version %u", pi->ver); offset = 1; /* Only the PDU version was parsed */ + return offset; } + proto_item_set_len(ti, offset - start); + return offset; } @@ -437,10 +452,20 @@ static void dissect_otrxd_tx_burst_v0(tvbuff_t *tvb, packet_info *pinfo, /* Burst data in Transmit direction */ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, - proto_item *ti, proto_tree *tree, + proto_item *pti, proto_tree *ptree, struct otrxd_pdu_info *pi, int offset) { + proto_tree *tree; + proto_item *ti; + int start; + + /* Add a sub-tree for each PDU (length is set below) */ + tree = proto_tree_add_subtree(ptree, tvb, offset, -1, + ett_otrxd_tx_pdu, &ti, + "TRXD Tx PDU: "); + start = offset; + switch (pi->ver) { /* Both versions feature the same PDU format */ case 0: @@ -450,12 +475,14 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, dissect_otrxd_tx_burst_v0(tvb, pinfo, ti, tree, &offset); break; default: - expert_add_info_format(pinfo, ti, &ei_otrxd_unknown_pdu_ver, + expert_add_info_format(pinfo, pti, &ei_otrxd_unknown_pdu_ver, "Unknown TRXD PDU version %u", pi->ver); offset = 1; /* Only the PDU version was parsed */ return offset; } + proto_item_set_len(ti, offset - start); + return offset; } @@ -710,6 +737,8 @@ void proto_register_osmo_trx(void) static gint *ett[] = { &ett_otrxd, + &ett_otrxd_rx_pdu, + &ett_otrxd_tx_pdu, &ett_otrxc, }; -- GitLab From bcf893a3ddfc61970b73efeefaea6cd3737957b3 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Sat, 3 Apr 2021 02:18:56 +0200 Subject: [PATCH 16/18] osmo_trx: append PDU version string to the root tree item --- epan/dissectors/packet-osmo_trx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index de97fc93c27..a1bb3aa5e56 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -526,6 +526,7 @@ static int dissect_otrxd(tvbuff_t *tvb, packet_info *pinfo, /* Parse common TRXD PDU version */ proto_tree_add_item_ret_uint(otrxd_tree, hf_otrxd_pdu_ver, tvb, offset, 1, ENC_NA, &pi.ver); + proto_item_append_text(ti, " Version %u", pi.ver); if (burst_dir == OTRXCD_DIR_L12TRX) offset = dissect_otrxd_tx(tvb, pinfo, ti, otrxd_tree, &pi, offset); -- GitLab From 1ac8da59719cac974dcbdafed1a7056a592ca167 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Sun, 11 Apr 2021 05:24:07 +0200 Subject: [PATCH 17/18] osmo_trx: cosmetic: re-arrange TRXD related fields --- epan/dissectors/packet-osmo_trx.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index a1bb3aa5e56..8d7e693a5ad 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -37,16 +37,12 @@ static int hf_otrxc_msg_dir = -1; /* TRXD PDU version */ static int hf_otrxd_pdu_ver = -1; -/* Common TDMA fields */ +/* TRXD common fields */ static int hf_otrxd_chdr_reserved = -1; static int hf_otrxd_tdma_tn = -1; static int hf_otrxd_tdma_fn = -1; -/* RX TRXD header, V0 specific fields */ -static int hf_otrxd_rssi = -1; -static int hf_otrxd_toa256 = -1; - -/* RX TRXD header, V1 specific fields */ +/* MTS (Modulation and Training Sequence) fields */ static int hf_otrxd_nope_ind = -1; static int hf_otrxd_nope_ind_pad = -1; static int hf_otrxd_mod_2b = -1; /* 2 bit field */ @@ -55,9 +51,13 @@ static int hf_otrxd_mod_4b = -1; /* 4 bit field */ static int hf_otrxd_tsc_set_x4 = -1; static int hf_otrxd_tsc_set_x2 = -1; static int hf_otrxd_tsc = -1; + +/* TRXD Rx header fields */ +static int hf_otrxd_rssi = -1; +static int hf_otrxd_toa256 = -1; static int hf_otrxd_ci = -1; -/* TX TRXC header, V0 / V1 specific fields */ +/* TRXD Tx header fields */ static int hf_otrxd_tx_att = -1; /* Burst soft (255 .. 0) / hard (1 or 0) bits */ @@ -669,7 +669,7 @@ void proto_register_osmo_trx(void) { &hf_otrxd_burst_dir, { "Burst Direction", "osmo_trx.direction", FT_UINT8, BASE_DEC, VALS(otrxcd_dir_vals), 0, NULL, HFILL } }, - /* Common TRXD header fields */ + /* Rx/Tx header fields */ { &hf_otrxd_pdu_ver, { "PDU Version", "osmo_trxd.pdu_ver", FT_UINT8, BASE_DEC, NULL, 0xf0, NULL, HFILL } }, { &hf_otrxd_chdr_reserved, { "Reserved", "osmo_trxd.chdr_reserved", @@ -679,18 +679,17 @@ void proto_register_osmo_trx(void) { &hf_otrxd_tdma_fn, { "TDMA Frame Number", "osmo_trxd.tdma.fn", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } }, - /* Rx TRXD header, V0 specific fields */ + /* Rx header fields */ { &hf_otrxd_rssi, { "RSSI", "osmo_trxd.meas.rssi", FT_UINT8, BASE_CUSTOM, CF_FUNC(format_rssi), 0, NULL, HFILL } }, { &hf_otrxd_toa256, { "Timing of Arrival", "osmo_trxd.meas.toa256", FT_INT16, BASE_DEC | BASE_UNIT_STRING, &otrx_units_toa256, 0, NULL, HFILL } }, - /* Rx TRXD header, V1 specific fields */ + /* MTS (Modulation and Training Sequence) fields */ { &hf_otrxd_nope_ind, { "NOPE Indication", "osmo_trxd.nope_ind", FT_BOOLEAN, 8, TFS(&otrxd_nope_bool_val), 0x80, NULL, HFILL } }, { &hf_otrxd_nope_ind_pad, { "NOPE Padding", "osmo_trxd.nope_ind_pad", FT_UINT8, BASE_DEC, NULL, 0x7f, NULL, HFILL } }, - { &hf_otrxd_mod_2b, { "Modulation", "osmo_trxd.mod", FT_UINT8, BASE_DEC, VALS(otrxd_mod_2b_vals), 0x60, NULL, HFILL } }, { &hf_otrxd_mod_3b, { "Modulation", "osmo_trxd.mod", @@ -706,7 +705,7 @@ void proto_register_osmo_trx(void) { &hf_otrxd_ci, { "C/I (Carrier-to-Interference ratio)", "osmo_trxd.meas.ci", FT_INT16, BASE_DEC | BASE_UNIT_STRING, &units_centibels, 0, NULL, HFILL } }, - /* Tx TRXD header, V0 / V1 specific fields */ + /* Tx header fields */ { &hf_otrxd_tx_att, { "Tx Attenuation", "osmo_trxd.tx_att", FT_UINT8, BASE_DEC | BASE_UNIT_STRING, &units_decibels, 0, NULL, HFILL } }, -- GitLab From ffb0723fb3d43eefc50d631ec0e7ebe8941eaf87 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Date: Wed, 17 Mar 2021 02:17:38 +0100 Subject: [PATCH 18/18] osmo_trx: add TRXDv2 PDU dissection support --- epan/dissectors/packet-osmo_trx.c | 192 +++++++++++++++++++++++++++--- 1 file changed, 177 insertions(+), 15 deletions(-) diff --git a/epan/dissectors/packet-osmo_trx.c b/epan/dissectors/packet-osmo_trx.c index 8d7e693a5ad..0a598b4627c 100644 --- a/epan/dissectors/packet-osmo_trx.c +++ b/epan/dissectors/packet-osmo_trx.c @@ -39,6 +39,8 @@ static int hf_otrxd_pdu_ver = -1; /* TRXD common fields */ static int hf_otrxd_chdr_reserved = -1; +static int hf_otrxd_batch_ind = -1; +static int hf_otrxd_trx_num = -1; static int hf_otrxd_tdma_tn = -1; static int hf_otrxd_tdma_fn = -1; @@ -59,6 +61,8 @@ static int hf_otrxd_ci = -1; /* TRXD Tx header fields */ static int hf_otrxd_tx_att = -1; +static int hf_otrxd_tx_scpir = -1; +static int hf_otrxd_tx_rfu = -1; /* Burst soft (255 .. 0) / hard (1 or 0) bits */ static int hf_otrxd_soft_symbols = -1; @@ -92,6 +96,12 @@ static expert_field ei_otrxc_unknown_dir = EI_INIT; /* Custom units */ static const unit_name_string otrx_units_toa256 = { " (1/256 of a symbol)", NULL }; +/* TRXD BATCH.ind value description */ +static const true_false_string otrxd_batch_bool_val = { + "Another PDU follows", + "This is the last PDU", +}; + /* TRXD NOPE.{ind,req} value description */ static const true_false_string otrxd_nope_bool_val = { "Burst is not present", @@ -233,6 +243,12 @@ static const value_string otrxc_msg_type_desc[] = { struct otrxd_pdu_info { /* PDU version */ guint32 ver; + /* BATCH.ind marker */ + gboolean batch; + /* Number of batched PDUs */ + guint32 num_pdus; + /* TRX (RF channel) number */ + guint32 trx_num; /* TDMA frame number */ guint32 fn; /* TDMA timeslot number */ @@ -247,7 +263,7 @@ struct otrxd_pdu_info { }; /* Dissector for common Rx/Tx TRXDv0/v1 header part */ -static void dissect_otrxd_chdr_v0(tvbuff_t *tvb, packet_info *pinfo, +static void dissect_otrxd_chdr_v0(tvbuff_t *tvb, packet_info *pinfo _U_, proto_item *ti, proto_tree *tree, struct otrxd_pdu_info *pi, int *offset) @@ -263,13 +279,11 @@ static void dissect_otrxd_chdr_v0(tvbuff_t *tvb, packet_info *pinfo, *offset, 4, ENC_BIG_ENDIAN, &pi->fn); *offset += 4; - col_append_fstr(pinfo->cinfo, COL_INFO, "TDMA FN %07u TN %u", pi->fn, pi->tn); proto_item_append_text(ti, "TDMA FN %07u TN %u", pi->fn, pi->tn); } /* Dissector for MTS (Modulation and Training Sequence) */ -static void dissect_otrxd_mts(tvbuff_t *tvb, packet_info *pinfo, - proto_item *ti, proto_tree *tree, +static void dissect_otrxd_mts(tvbuff_t *tvb, proto_tree *tree, struct otrxd_pdu_info *pi, int offset) { @@ -284,8 +298,6 @@ static void dissect_otrxd_mts(tvbuff_t *tvb, packet_info *pinfo, offset, 1, ENC_NA, &pi->nope); if (pi->nope) { proto_tree_add_item(tree, hf_otrxd_nope_ind_pad, tvb, offset, 1, ENC_NA); - col_append_str(pinfo->cinfo, COL_INFO, ", NOPE.ind"); - proto_item_append_text(ti, ", NOPE.ind"); return; } @@ -320,9 +332,6 @@ static void dissect_otrxd_mts(tvbuff_t *tvb, packet_info *pinfo, } proto_tree_add_item_ret_uint(tree, hf_otrxd_tsc, tvb, offset, 1, ENC_NA, &pi->tsc); - - col_append_fstr(pinfo->cinfo, COL_INFO, ", Modulation %s, TSC %u", pi->mod_str, pi->tsc); - proto_item_append_text(ti, ", Modulation %s, TSC %u", pi->mod_str, pi->tsc); } /* Dissector for Rx TRXD header version 0 */ @@ -350,7 +359,11 @@ static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, offset = dissect_otrxd_rx_hdr_v0(tvb, pinfo, ti, tree, pi, offset); /* MTS (Modulation and Training Sequence) */ - dissect_otrxd_mts(tvb, pinfo, ti, tree, pi, offset++); + dissect_otrxd_mts(tvb, tree, pi, offset++); + if (!pi->nope) + proto_item_append_text(ti, ", Modulation %s, TSC %u", pi->mod_str, pi->tsc); + else + proto_item_append_text(ti, ", NOPE.ind"); /* C/I (Carrier to Interference ratio) */ proto_tree_add_item(tree, hf_otrxd_ci, tvb, offset, 2, ENC_NA); @@ -359,6 +372,50 @@ static int dissect_otrxd_rx_hdr_v1(tvbuff_t *tvb, packet_info *pinfo, return offset; } +/* Dissector for TRXD Rx header version 2 */ +static int dissect_otrxd_rx_hdr_v2(tvbuff_t *tvb, packet_info *pinfo _U_, + proto_item *ti, proto_tree *tree, + struct otrxd_pdu_info *pi, + int offset) +{ + proto_tree_add_item(tree, hf_otrxd_chdr_reserved, tvb, offset, 1, ENC_NA); + proto_tree_add_item_ret_uint(tree, hf_otrxd_tdma_tn, tvb, + offset, 1, ENC_NA, &pi->tn); + offset += 1; + + proto_tree_add_item_ret_boolean(tree, hf_otrxd_batch_ind, tvb, + offset, 1, ENC_NA, &pi->batch); + proto_tree_add_item_ret_uint(tree, hf_otrxd_trx_num, tvb, + offset, 1, ENC_NA, &pi->trx_num); + offset += 1; + + /* MTS (Modulation and Training Sequence) */ + dissect_otrxd_mts(tvb, tree, pi, offset++); + + /* RSSI (Received Signal Strength Indication) */ + proto_tree_add_item(tree, hf_otrxd_rssi, tvb, offset++, 1, ENC_NA); + + /* ToA256 (Timing of Arrival) and C/I (Carrier to Interference ratio) */ + proto_tree_add_item(tree, hf_otrxd_toa256, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_otrxd_ci, tvb, offset + 2, 2, ENC_BIG_ENDIAN); + offset += 4; + + /* TDMA frame number (absent in additional PDUs) */ + if (pi->num_pdus == 0) { + proto_tree_add_item_ret_uint(tree, hf_otrxd_tdma_fn, tvb, + offset, 4, ENC_BIG_ENDIAN, &pi->fn); + offset += 4; + } + + proto_item_append_text(ti, "TRXN %02u, TDMA FN %07u TN %u", pi->trx_num, pi->fn, pi->tn); + if (!pi->nope) + proto_item_append_text(ti, ", Modulation %s, TSC %u", pi->mod_str, pi->tsc); + else + proto_item_append_text(ti, ", NOPE.ind"); + + return offset; +} + /* Burst data in Receive direction */ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, proto_item *pti, proto_tree *ptree, @@ -369,6 +426,7 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree; proto_item *ti; +loop: /* Add a sub-tree for each PDU (length is set below) */ tree = proto_tree_add_subtree(ptree, tvb, offset, -1, ett_otrxd_rx_pdu, &ti, @@ -404,6 +462,15 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, offset, burst_len, ENC_NA); offset += burst_len; break; + case 2: + offset = dissect_otrxd_rx_hdr_v2(tvb, pinfo, ti, tree, pi, offset); + if (pi->nope) /* NOPE.ind contains no burst */ + break; + burst_len = otrxd_burst_len[pi->mod]; + proto_tree_add_item(tree, hf_otrxd_soft_symbols, tvb, + offset, burst_len, ENC_NA); + offset += burst_len; + break; default: expert_add_info_format(pinfo, pti, &ei_otrxd_unknown_pdu_ver, "Unknown TRXD PDU version %u", pi->ver); @@ -413,12 +480,20 @@ static int dissect_otrxd_rx(tvbuff_t *tvb, packet_info *pinfo, proto_item_set_len(ti, offset - start); + /* Number of processed PDUs */ + pi->num_pdus += 1; + + /* There can be additional 'batched' PDUs */ + if (pi->batch) + goto loop; + return offset; } /* Dissector for TRXDv0/v1 Tx burst */ -static void dissect_otrxd_tx_burst_v0(tvbuff_t *tvb, packet_info *pinfo, +static void dissect_otrxd_tx_burst_v0(tvbuff_t *tvb, packet_info *pinfo _U_, proto_item *ti, proto_tree *tree, + struct otrxd_pdu_info *pi, int *offset) { /* Calculate the burst length */ @@ -428,19 +503,19 @@ static void dissect_otrxd_tx_burst_v0(tvbuff_t *tvb, packet_info *pinfo, switch (burst_len) { /* We may also have NOPE.req in the future (to drive fake_trx.py) */ case 0: - col_append_str(pinfo->cinfo, COL_INFO, ", NOPE.req"); proto_item_append_text(ti, ", NOPE.req"); + pi->nope = TRUE; return; /* TODO: introduce an enumerated type, detect other modulation types, * TODO: add a generated field for "osmo_trxd.mod" */ case GMSK_BURST_LEN: - col_append_str(pinfo->cinfo, COL_INFO, ", Modulation GMSK"); proto_item_append_text(ti, ", Modulation GMSK"); + pi->mod_str = "GMSK"; break; case 3 * GMSK_BURST_LEN: - col_append_str(pinfo->cinfo, COL_INFO, ", Modulation 8-PSK"); proto_item_append_text(ti, ", Modulation 8-PSK"); + pi->mod_str = "8-PSK"; break; } @@ -450,6 +525,53 @@ static void dissect_otrxd_tx_burst_v0(tvbuff_t *tvb, packet_info *pinfo, *offset += burst_len; } +/* Dissector for TRXD Tx header version 2 */ +static void dissect_otrxd_tx_hdr_v2(tvbuff_t *tvb, packet_info *pinfo _U_, + proto_item *ti, proto_tree *tree, + struct otrxd_pdu_info *pi, + int *offset) +{ + proto_tree_add_item(tree, hf_otrxd_chdr_reserved, tvb, *offset, 1, ENC_NA); + proto_tree_add_item_ret_uint(tree, hf_otrxd_tdma_tn, tvb, + *offset, 1, ENC_NA, &pi->tn); + *offset += 1; + + proto_tree_add_item_ret_boolean(tree, hf_otrxd_batch_ind, tvb, + *offset, 1, ENC_NA, &pi->batch); + proto_tree_add_item_ret_uint(tree, hf_otrxd_trx_num, tvb, + *offset, 1, ENC_NA, &pi->trx_num); + *offset += 1; + + /* MTS (Modulation and Training Sequence) */ + dissect_otrxd_mts(tvb, tree, pi, *offset); + *offset += 1; + + /* Tx power attenuation */ + proto_tree_add_item(tree, hf_otrxd_tx_att, tvb, *offset, 1, ENC_NA); + *offset += 1; + + /* SCPIR (Subchannel Power Imbalance Ratio) */ + proto_tree_add_item(tree, hf_otrxd_tx_scpir, tvb, *offset, 1, ENC_NA); + *offset += 1; + + /* RFU (currently just to make the header dword-alignment) */ + proto_tree_add_item(tree, hf_otrxd_tx_rfu, tvb, *offset, 3, ENC_NA); + *offset += 3; + + /* TDMA frame number (absent in additional PDUs) */ + if (pi->num_pdus == 0) { + proto_tree_add_item_ret_uint(tree, hf_otrxd_tdma_fn, tvb, + *offset, 4, ENC_BIG_ENDIAN, &pi->fn); + *offset += 4; + } + + proto_item_append_text(ti, "TRXN %02u, TDMA FN %07u TN %u", pi->trx_num, pi->fn, pi->tn); + if (!pi->nope) + proto_item_append_text(ti, ", Modulation %s, TSC %u", pi->mod_str, pi->tsc); + else + proto_item_append_text(ti, ", NOPE.req"); +} + /* Burst data in Transmit direction */ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, proto_item *pti, proto_tree *ptree, @@ -458,8 +580,10 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, { proto_tree *tree; proto_item *ti; + int burst_len; int start; +loop: /* Add a sub-tree for each PDU (length is set below) */ tree = proto_tree_add_subtree(ptree, tvb, offset, -1, ett_otrxd_tx_pdu, &ti, @@ -472,7 +596,16 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, case 1: dissect_otrxd_chdr_v0(tvb, pinfo, ti, tree, pi, &offset); proto_tree_add_item(tree, hf_otrxd_tx_att, tvb, offset++, 1, ENC_NA); - dissect_otrxd_tx_burst_v0(tvb, pinfo, ti, tree, &offset); + dissect_otrxd_tx_burst_v0(tvb, pinfo, ti, tree, pi, &offset); + break; + case 2: + dissect_otrxd_tx_hdr_v2(tvb, pinfo, ti, tree, pi, &offset); + if (pi->nope) /* NOPE.ind contains no burst */ + break; + burst_len = otrxd_burst_len[pi->mod]; + proto_tree_add_item(tree, hf_otrxd_hard_symbols, tvb, + offset, burst_len, ENC_NA); + offset += burst_len; break; default: expert_add_info_format(pinfo, pti, &ei_otrxd_unknown_pdu_ver, @@ -483,6 +616,13 @@ static int dissect_otrxd_tx(tvbuff_t *tvb, packet_info *pinfo, proto_item_set_len(ti, offset - start); + /* Number of processed PDUs */ + pi->num_pdus += 1; + + /* There can be additional 'batched' PDUs */ + if (pi->batch) + goto loop; + return offset; } @@ -537,6 +677,20 @@ static int dissect_otrxd(tvbuff_t *tvb, packet_info *pinfo, offset = 1; /* Only the PDU version was parsed */ } + /* Summary for all parsed PDUs */ + if (pi.num_pdus == 1) { + col_append_fstr(pinfo->cinfo, COL_INFO, "TDMA FN %07u TN %u", pi.fn, pi.tn); + if (pi.mod_str != NULL) + col_append_fstr(pinfo->cinfo, COL_INFO, ", Modulation %s", pi.mod_str); + else if (pi.nope && burst_dir == OTRXCD_DIR_TRX2L1) + col_append_str(pinfo->cinfo, COL_INFO, ", NOPE.ind"); + else if (pi.nope && burst_dir == OTRXCD_DIR_L12TRX) + col_append_str(pinfo->cinfo, COL_INFO, ", NOPE.req"); + } else if (pi.num_pdus > 1) { + col_append_fstr(pinfo->cinfo, COL_INFO, "TDMA FN %07u", pi.fn); + col_append_fstr(pinfo->cinfo, COL_INFO, ", %u batched PDUs ", pi.num_pdus); + } + proto_item_set_len(ti, offset); /* Let it warn us if there are unhandled tail octets */ @@ -678,6 +832,10 @@ void proto_register_osmo_trx(void) FT_UINT8, BASE_DEC, NULL, 0x07, NULL, HFILL } }, { &hf_otrxd_tdma_fn, { "TDMA Frame Number", "osmo_trxd.tdma.fn", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } }, + { &hf_otrxd_batch_ind, { "BATCH Indication", "osmo_trxd.batch_ind", + FT_BOOLEAN, 8, TFS(&otrxd_batch_bool_val), 0x80, NULL, HFILL } }, + { &hf_otrxd_trx_num, { "TRX (RF Channel) Number", "osmo_trxd.trx_num", + FT_UINT8, BASE_DEC, NULL, 0x3f, NULL, HFILL } }, /* Rx header fields */ { &hf_otrxd_rssi, { "RSSI", "osmo_trxd.meas.rssi", @@ -708,6 +866,10 @@ void proto_register_osmo_trx(void) /* Tx header fields */ { &hf_otrxd_tx_att, { "Tx Attenuation", "osmo_trxd.tx_att", FT_UINT8, BASE_DEC | BASE_UNIT_STRING, &units_decibels, 0, NULL, HFILL } }, + { &hf_otrxd_tx_scpir, { "SCPIR Value", "osmo_trxd.scpir_val", + FT_INT8, BASE_DEC | BASE_UNIT_STRING, &units_decibels, 0, NULL, HFILL } }, + { &hf_otrxd_tx_rfu, { "Spare padding", "osmo_trxd.spare", + FT_BYTES, SEP_SPACE, NULL, 0, NULL, HFILL } }, /* Burst soft (255 .. 0) / hard (1 or 0) bits */ { &hf_otrxd_soft_symbols, { "Soft-bits", "osmo_trxd.burst.sbits", -- GitLab