From bb3e87302d6e84dcffec104b2b379095262c701b Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Thu, 25 Feb 2021 11:17:24 +0100 Subject: [PATCH] Added new pcap enable option and mac nr --- lib/include/srslte/common/nas_pcap.h | 12 ++--- lib/src/common/nas_pcap.cc | 13 ++++-- srsue/hdr/stack/mac_nr/mac_nr.h | 9 ++-- srsue/hdr/stack/ue_stack_base.h | 11 +++-- srsue/hdr/stack/ue_stack_lte.h | 11 +++-- srsue/src/main.cc | 10 ++--- srsue/src/stack/mac_nr/mac_nr.cc | 21 +++++---- srsue/src/stack/ue_stack_lte.cc | 67 ++++++++++++++++++++++++---- srsue/src/stack/ue_stack_nr.cc | 1 - srsue/test/ttcn3/src/ttcn3_dut.cc | 19 ++++---- srsue/test/ttcn3/src/ttcn3_syssim.cc | 6 ++- srsue/ue.conf.example | 16 +++---- 12 files changed, 132 insertions(+), 64 deletions(-) diff --git a/lib/include/srslte/common/nas_pcap.h b/lib/include/srslte/common/nas_pcap.h index b8814a6aa..672f2c291 100644 --- a/lib/include/srslte/common/nas_pcap.h +++ b/lib/include/srslte/common/nas_pcap.h @@ -14,6 +14,7 @@ #define SRSLTE_NAS_PCAP_H #include "srslte/common/pcap.h" +#include namespace srslte { @@ -27,15 +28,16 @@ public: pcap_file = NULL; } void enable(); - void open(const char* filename, uint32_t ue_id = 0); + uint32_t open(std::string filename_, uint32_t ue_id = 0); void close(); void write_nas(uint8_t* pdu, uint32_t pdu_len_bytes); private: - bool enable_write; - FILE* pcap_file; - uint32_t ue_id; - void pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes); + bool enable_write; + std::string filename; + FILE* pcap_file; + uint32_t ue_id; + void pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes); }; } // namespace srslte diff --git a/lib/src/common/nas_pcap.cc b/lib/src/common/nas_pcap.cc index 5b67bcc27..47c987125 100644 --- a/lib/src/common/nas_pcap.cc +++ b/lib/src/common/nas_pcap.cc @@ -21,15 +21,22 @@ void nas_pcap::enable() { enable_write = true; } -void nas_pcap::open(const char* filename, uint32_t ue_id_) + +uint32_t nas_pcap::open(std::string filename_, uint32_t ue_id_) { - pcap_file = LTE_PCAP_Open(NAS_LTE_DLT, filename); + filename = filename_; + pcap_file = LTE_PCAP_Open(NAS_LTE_DLT, filename.c_str()); + if (pcap_file == nullptr) { + return SRSLTE_ERROR; + } ue_id = ue_id_; enable_write = true; + return SRSLTE_SUCCESS; } + void nas_pcap::close() { - fprintf(stdout, "Saving NAS PCAP file (DLT=%d)\n", NAS_LTE_DLT); + fprintf(stdout, "Saving NAS PCAP file (DLT=%d) to %s \n", NAS_LTE_DLT, filename.c_str()); LTE_PCAP_Close(pcap_file); } diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h index dc827c1fc..3a3f4b626 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -30,7 +30,6 @@ namespace srsue { class rlc_interface_mac; struct mac_nr_args_t { - srsue::pcap_args_t pcap; }; class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, public mac_interface_proc_ra_nr @@ -45,6 +44,8 @@ public: void reset(); void run_tti(const uint32_t tti); + void start_pcap(srslte::mac_pcap* pcap_); + void bch_decoded_ok(uint32_t tti, srslte::unique_byte_buffer_t payload); /// Interface for PHY @@ -113,9 +114,9 @@ private: rlc_interface_mac* rlc = nullptr; srslte::ext_task_sched_handle task_sched; - std::unique_ptr pcap = nullptr; - srslog::basic_logger& logger; - mac_nr_args_t args = {}; + srslte::mac_pcap* pcap = nullptr; + srslog::basic_logger& logger; + mac_nr_args_t args = {}; bool started = false; diff --git a/srsue/hdr/stack/ue_stack_base.h b/srsue/hdr/stack/ue_stack_base.h index 4a26739ac..72af1eaed 100644 --- a/srsue/hdr/stack/ue_stack_base.h +++ b/srsue/hdr/stack/ue_stack_base.h @@ -27,10 +27,15 @@ namespace srsue { typedef struct { bool enable; std::string filename; - bool nas_enable; - std::string nas_filename; } pcap_args_t; +typedef struct { + std::string enable; + pcap_args_t mac_pcap; + pcap_args_t mac_nr_pcap; + pcap_args_t nas_pcap; +} pkt_trace_args_t; + typedef struct { std::string mac_level; std::string rlc_level; @@ -53,7 +58,7 @@ typedef struct { typedef struct { std::string type; - pcap_args_t pcap; + pkt_trace_args_t pkt_trace; stack_log_args_t log; usim_args_t usim; rrc_args_t rrc; diff --git a/srsue/hdr/stack/ue_stack_lte.h b/srsue/hdr/stack/ue_stack_lte.h index f4f78dc50..34609ca00 100644 --- a/srsue/hdr/stack/ue_stack_lte.h +++ b/srsue/hdr/stack/ue_stack_lte.h @@ -34,11 +34,11 @@ #include "srslte/common/buffer_pool.h" #include "srslte/common/log_filter.h" #include "srslte/common/multiqueue.h" +#include "srslte/common/string_helpers.h" #include "srslte/common/task_scheduler.h" #include "srslte/common/thread_pool.h" -#include "srslte/interfaces/ue_interfaces.h" - #include "srslte/common/time_prof.h" +#include "srslte/interfaces/ue_interfaces.h" #include "srsue/hdr/ue_metrics_interface.h" #include "ue_stack_base.h" @@ -177,6 +177,11 @@ private: srslog::basic_logger& usim_logger; srslog::basic_logger& nas_logger; + // tracing + srslte::mac_pcap mac_pcap; + srslte::mac_pcap mac_nr_pcap; + srslte::nas_pcap nas_pcap; + // RAT-specific interfaces phy_interface_stack_lte* phy = nullptr; gw_interface_stack* gw = nullptr; @@ -193,8 +198,6 @@ private: // stack components srsue::mac mac; - srslte::mac_pcap mac_pcap; - srslte::nas_pcap nas_pcap; srslte::rlc rlc; srslte::pdcp pdcp; srsue::rrc rrc; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 7b60dbe9c..0418b6bc0 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -133,11 +133,11 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) ("nas.eia", bpo::value(&args->stack.nas.eia)->default_value("1,2,3"), "List of integrity algorithms included in UE capabilities") ("nas.eea", bpo::value(&args->stack.nas.eea)->default_value("0,1,2,3"), "List of ciphering algorithms included in UE capabilities") - ("pcap.enable", bpo::value(&args->stack.pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark") - ("pcap.filename", bpo::value(&args->stack.pcap.filename)->default_value("ue.pcap"), "MAC layer capture filename") - ("pcap.nas_enable", bpo::value(&args->stack.pcap.nas_enable)->default_value(false), "Enable NAS packet captures for wireshark") - ("pcap.nas_filename", bpo::value(&args->stack.pcap.nas_filename)->default_value("ue_nas.pcap"), "NAS layer capture filename (useful when NAS encryption is enabled)") - + ("pcap.enable", bpo::value(&args->stack.pkt_trace.enable)->default_value("none"), "Enable (MAC, MAC_NR, NAS) packet captures for wireshark") + ("pcap.mac_filename", bpo::value(&args->stack.pkt_trace.mac_pcap.filename)->default_value("/tmp/ue_mac.pcap"), "MAC layer capture filename") + ("pcap.mac_nr_filename", bpo::value(&args->stack.pkt_trace.mac_nr_pcap.filename)->default_value("/tmp/ue_mac_nr.pcap"), "MAC_NR layer capture filename") + ("pcap.nas_filename", bpo::value(&args->stack.pkt_trace.nas_pcap.filename)->default_value("/tmp/ue_nas.pcap"), "NAS layer capture filename") + ("gui.enable", bpo::value(&args->gui.enable)->default_value(false), "Enable GUI plots") ("log.rf_level", bpo::value(&args->rf.log_level), "RF log level") diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index 219d0b96f..7143e0052 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -17,7 +17,11 @@ namespace srsue { mac_nr::mac_nr(srslte::ext_task_sched_handle task_sched_) : - task_sched(task_sched_), logger(srslog::fetch_basic_logger("MAC")), proc_ra(logger), mux(logger) + task_sched(task_sched_), + logger(srslog::fetch_basic_logger("MAC")), + proc_ra(logger), + mux(logger), + pcap(nullptr) { tx_buffer = srslte::make_byte_buffer(); rlc_buffer = srslte::make_byte_buffer(); @@ -37,12 +41,6 @@ int mac_nr::init(const mac_nr_args_t& args_, phy_interface_mac_nr* phy_, rlc_int // Create Stack task dispatch queue stack_task_dispatch_queue = task_sched.make_task_queue(); - // Set up pcap - if (args.pcap.enable) { - pcap.reset(new srslte::mac_pcap(srslte::srslte_rat_t::nr)); - pcap->open(args.pcap.filename.c_str()); - } - proc_ra.init(phy, this, &task_sched); mux.init(); @@ -58,13 +56,14 @@ int mac_nr::init(const mac_nr_args_t& args_, phy_interface_mac_nr* phy_, rlc_int return SRSLTE_SUCCESS; } +void mac_nr::start_pcap(srslte::mac_pcap* pcap_) +{ + pcap = pcap_; +} + void mac_nr::stop() { if (started) { - if (pcap != nullptr) { - pcap->close(); - } - started = false; } } diff --git a/srsue/src/stack/ue_stack_lte.cc b/srsue/src/stack/ue_stack_lte.cc index 16aa2a8c7..35dc03348 100644 --- a/srsue/src/stack/ue_stack_lte.cc +++ b/srsue/src/stack/ue_stack_lte.cc @@ -33,6 +33,8 @@ ue_stack_lte::ue_stack_lte() : rrc_logger(srslog::fetch_basic_logger("RRC", false)), usim_logger(srslog::fetch_basic_logger("USIM", false)), nas_logger(srslog::fetch_basic_logger("NAS", false)), + mac_pcap(srslte_rat_t::lte), + mac_nr_pcap(srslte_rat_t::nr), usim(nullptr), phy(nullptr), rlc("RLC"), @@ -44,8 +46,7 @@ ue_stack_lte::ue_stack_lte() : nas(&task_sched), thread("STACK"), task_sched(512, 64), - tti_tprof("tti_tprof", "STCK", TTI_STAT_PERIOD), - mac_pcap(srslte_rat_t::lte) + tti_tprof("tti_tprof", "STCK", TTI_STAT_PERIOD) { get_background_workers().set_nof_workers(2); ue_task_queue = task_sched.make_task_queue(); @@ -111,15 +112,60 @@ int ue_stack_lte::init(const stack_args_t& args_) nas_logger.set_level(srslog::str_to_basic_level(args.log.nas_level)); nas_logger.set_hex_dump_max_size(args.log.nas_hex_limit); + // parse pcap trace list + std::vector pcap_list; + srslte::string_parse_list(args.pkt_trace.enable, ',', pcap_list); + if (pcap_list.empty()) { + stack_logger.error("PCAP enable list empty defaulting to disable all PCAPs"); + args.pkt_trace.mac_pcap.enable = false; + args.pkt_trace.mac_nr_pcap.enable = false; + args.pkt_trace.mac_nr_pcap.enable = false; + } + + for (auto& pcap : pcap_list) { + // Remove white spaces + pcap.erase(std::remove_if(pcap.begin(), pcap.end(), isspace), pcap.end()); + if (pcap == "mac" || pcap == "MAC") { + args.pkt_trace.mac_pcap.enable = true; + } else if (pcap == "mac_nr" || pcap == "MAC_NR") { + args.pkt_trace.mac_nr_pcap.enable = true; + } else if (pcap == "nas" || pcap == "NAS") { + args.pkt_trace.nas_pcap.enable = true; + } else if (pcap == "none" || pcap == "NONE") { + args.pkt_trace.mac_pcap.enable = false; + args.pkt_trace.mac_nr_pcap.enable = false; + args.pkt_trace.mac_nr_pcap.enable = false; + } else { + stack_logger.error("Unkown PCAP option %s", pcap.c_str()); + } + } + // Set up pcap - if (args.pcap.enable) { - if (mac_pcap.open(args.pcap.filename.c_str()) == SRSLTE_SUCCESS) { + if (args.pkt_trace.mac_pcap.enable) { + if (mac_pcap.open(args.pkt_trace.mac_pcap.filename.c_str()) == SRSLTE_SUCCESS) { mac.start_pcap(&mac_pcap); + stack_logger.info("Open mac pcap file %s", args.pkt_trace.mac_pcap.filename.c_str()); + } else { + stack_logger.error("Can not open pcap file %s", args.pkt_trace.mac_pcap.filename.c_str()); } } - if (args.pcap.nas_enable) { - nas_pcap.open(args.pcap.nas_filename.c_str()); - nas.start_pcap(&nas_pcap); + + if (args.pkt_trace.mac_nr_pcap.enable) { + if (mac_nr_pcap.open(args.pkt_trace.mac_nr_pcap.filename.c_str()) == SRSLTE_SUCCESS) { + mac_nr.start_pcap(&mac_nr_pcap); + stack_logger.info("Open mac nr pcap file %s", args.pkt_trace.mac_nr_pcap.filename.c_str()); + } else { + stack_logger.error("Can not open pcap file %s", args.pkt_trace.mac_nr_pcap.filename.c_str()); + } + } + + if (args.pkt_trace.nas_pcap.enable) { + if (nas_pcap.open(args.pkt_trace.nas_pcap.filename.c_str()) == SRSLTE_SUCCESS) { + nas.start_pcap(&nas_pcap); + stack_logger.info("Open nas pcap file %s", args.pkt_trace.nas_pcap.filename.c_str()); + } else { + stack_logger.error("Can not open pcap file %s", args.pkt_trace.nas_pcap.filename.c_str()); + } } // Init USIM first to allow early exit in case reader couldn't be found @@ -168,10 +214,13 @@ void ue_stack_lte::stop_impl() pdcp.stop(); mac.stop(); - if (args.pcap.enable) { + if (args.pkt_trace.mac_pcap.enable) { mac_pcap.close(); } - if (args.pcap.nas_enable) { + if (args.pkt_trace.mac_nr_pcap.enable) { + mac_nr_pcap.close(); + } + if (args.pkt_trace.nas_pcap.enable) { nas_pcap.close(); } diff --git a/srsue/src/stack/ue_stack_nr.cc b/srsue/src/stack/ue_stack_nr.cc index b71e11a83..3211f8fb4 100644 --- a/srsue/src/stack/ue_stack_nr.cc +++ b/srsue/src/stack/ue_stack_nr.cc @@ -66,7 +66,6 @@ int ue_stack_nr::init(const stack_args_t& args_) pdcp_log->set_hex_limit(args.log.pdcp_hex_limit); mac_nr_args_t mac_args = {}; - mac_args.pcap = args.pcap; mac->init(mac_args, phy, rlc.get()); rlc->init(pdcp.get(), rrc.get(), task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */); pdcp->init(rlc.get(), rrc.get(), gw); diff --git a/srsue/test/ttcn3/src/ttcn3_dut.cc b/srsue/test/ttcn3/src/ttcn3_dut.cc index 8016420ad..ae41cf840 100644 --- a/srsue/test/ttcn3/src/ttcn3_dut.cc +++ b/srsue/test/ttcn3/src/ttcn3_dut.cc @@ -28,7 +28,8 @@ using namespace rapidjson; namespace bpo = boost::program_options; typedef struct { - pcap_args_t pcap; + pcap_args_t mac_pcap; + pcap_args_t nas_pcap; std::string log_filename; std::string log_level; int32_t log_hex_level; @@ -45,10 +46,10 @@ all_args_t parse_args(ttcn3_dut_args_t* args, int argc, char* argv[]) bpo::options_description common("Configuration options"); // clang-format off common.add_options() - ("pcap.enable", bpo::value(&args->pcap.enable)->default_value(true), "Enable MAC packet captures for wireshark") - ("pcap.filename", bpo::value(&args->pcap.filename)->default_value("/tmp/ttcn3_ue.pcap"), "MAC layer capture filename") - ("pcap.nas_enable", bpo::value(&args->pcap.nas_enable)->default_value(false), "Enable NAS packet captures for wireshark") - ("pcap.nas_filename", bpo::value(&args->pcap.nas_filename)->default_value("/tmp/ttcn3_ue_nas.pcap"), "NAS layer capture filename (useful when NAS encryption is enabled)") + ("pcap.enable", bpo::value(&args->mac_pcap.enable)->default_value(true), "Enable MAC packet captures for wireshark") + ("pcap.filename", bpo::value(&args->mac_pcap.filename)->default_value("/tmp/ttcn3_ue.pcap"), "MAC layer capture filename") + ("pcap.nas_enable", bpo::value(&args->nas_pcap.enable)->default_value(false), "Enable NAS packet captures for wireshark") + ("pcap.nas_filename", bpo::value(&args->nas_pcap.filename)->default_value("/tmp/ttcn3_ue_nas.pcap"), "NAS layer capture filename (useful when NAS encryption is enabled)") ("logfilename", bpo::value(&args->log_filename)->default_value("/tmp/ttcn3_ue.log"), "Filename of log file") ("loglevel", bpo::value(&args->log_level)->default_value("warning"), "Log level (Error,Warning,Info,Debug)") ("loghexlevel", bpo::value(&args->log_hex_level)->default_value(64), "Log hex level (-1 unbounded)"); @@ -72,11 +73,11 @@ all_args_t parse_args(ttcn3_dut_args_t* args, int argc, char* argv[]) all_args_t all_args = {}; - all_args.stack.pcap.enable = args->pcap.enable; - all_args.stack.pcap.nas_enable = args->pcap.nas_enable; + all_args.stack.pkt_trace.mac_pcap.enable = args->mac_pcap.enable; + all_args.stack.pkt_trace.mac_pcap.filename = args->mac_pcap.filename; - all_args.stack.pcap.filename = args->pcap.filename; - all_args.stack.pcap.nas_filename = args->pcap.nas_filename; + all_args.stack.pkt_trace.nas_pcap.enable = args->nas_pcap.enable; + all_args.stack.pkt_trace.nas_pcap.filename = args->nas_pcap.filename; all_args.log.filename = args->log_filename; all_args.log.all_level = args->log_level; diff --git a/srsue/test/ttcn3/src/ttcn3_syssim.cc b/srsue/test/ttcn3/src/ttcn3_syssim.cc index 6c4bcddfd..4005994e1 100644 --- a/srsue/test/ttcn3/src/ttcn3_syssim.cc +++ b/srsue/test/ttcn3/src/ttcn3_syssim.cc @@ -418,8 +418,10 @@ void ttcn3_syssim::tc_start(const char* name) srslte::console("Initializing UE ID=%d for TC=%s\n", run_id, tc_name.c_str()); // Patch UE config - local_args.stack.pcap.filename = get_filename_with_tc_name(args.stack.pcap.filename, run_id, tc_name); - local_args.stack.pcap.nas_filename = get_filename_with_tc_name(args.stack.pcap.nas_filename, run_id, tc_name); + local_args.stack.pkt_trace.mac_pcap.filename = + get_filename_with_tc_name(args.stack.pkt_trace.mac_pcap.filename, run_id, tc_name); + local_args.stack.pkt_trace.nas_pcap.filename = + get_filename_with_tc_name(args.stack.pkt_trace.nas_pcap.filename, run_id, tc_name); // bring up UE if (ue->init(local_args, this, tc_name)) { diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 47176060d..56271d032 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -55,7 +55,7 @@ tx_gain = 80 ##################################################################### # Packet capture configuration # -# Packet capture is supported at both MAC and NAS layers. +# Packet capture is supported at both MAC, MAC_NR and NAS layers. # MAC-layer packets are captured to file in the compact format # decoded by the Wireshark mac-lte-framed dissector. # To use this dissector, edit the preferences for DLT_USER to @@ -64,15 +64,15 @@ tx_gain = 80 # NAS-layer packets are dissected with DLT=148, and # Payload Protocol = nas-eps. # -# enable: Enable MAC layer packet captures (true/false) -# filename: File path to use for MAC packet captures -# nas_enable: Enable NAS layer packet captures (true/false) -# nas_filename: File path to use for NAS packet captures +# enable: Enable packet captures of layers (mac/mac_nr/nas/none) multiple option list +# mac_filename: File path to use for MAC packet capture +# mac_nr_filename: File path to use for MAC NR packet capture +# nas_filename: File path to use for NAS packet capture ##################################################################### [pcap] -enable = false -filename = /tmp/ue.pcap -nas_enable = false +enable = none +mac_filename = /tmp/ue_mac.pcap +mac_nr_filename = /tmp/ue_mac_nr.pcap nas_filename = /tmp/nas.pcap #####################################################################