Added new pcap enable option and mac nr

master
David Rupprecht 4 years ago committed by Andre Puschmann
parent 3f4cf0a91f
commit bb3e87302d

@ -14,6 +14,7 @@
#define SRSLTE_NAS_PCAP_H #define SRSLTE_NAS_PCAP_H
#include "srslte/common/pcap.h" #include "srslte/common/pcap.h"
#include <string>
namespace srslte { namespace srslte {
@ -27,15 +28,16 @@ public:
pcap_file = NULL; pcap_file = NULL;
} }
void enable(); 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 close();
void write_nas(uint8_t* pdu, uint32_t pdu_len_bytes); void write_nas(uint8_t* pdu, uint32_t pdu_len_bytes);
private: private:
bool enable_write; bool enable_write;
FILE* pcap_file; std::string filename;
uint32_t ue_id; FILE* pcap_file;
void pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes); uint32_t ue_id;
void pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes);
}; };
} // namespace srslte } // namespace srslte

@ -21,15 +21,22 @@ void nas_pcap::enable()
{ {
enable_write = true; 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_; ue_id = ue_id_;
enable_write = true; enable_write = true;
return SRSLTE_SUCCESS;
} }
void nas_pcap::close() 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); LTE_PCAP_Close(pcap_file);
} }

@ -30,7 +30,6 @@ namespace srsue {
class rlc_interface_mac; class rlc_interface_mac;
struct mac_nr_args_t { 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 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 reset();
void run_tti(const uint32_t tti); 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); void bch_decoded_ok(uint32_t tti, srslte::unique_byte_buffer_t payload);
/// Interface for PHY /// Interface for PHY
@ -113,9 +114,9 @@ private:
rlc_interface_mac* rlc = nullptr; rlc_interface_mac* rlc = nullptr;
srslte::ext_task_sched_handle task_sched; srslte::ext_task_sched_handle task_sched;
std::unique_ptr<srslte::mac_pcap> pcap = nullptr; srslte::mac_pcap* pcap = nullptr;
srslog::basic_logger& logger; srslog::basic_logger& logger;
mac_nr_args_t args = {}; mac_nr_args_t args = {};
bool started = false; bool started = false;

@ -27,10 +27,15 @@ namespace srsue {
typedef struct { typedef struct {
bool enable; bool enable;
std::string filename; std::string filename;
bool nas_enable;
std::string nas_filename;
} pcap_args_t; } 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 { typedef struct {
std::string mac_level; std::string mac_level;
std::string rlc_level; std::string rlc_level;
@ -53,7 +58,7 @@ typedef struct {
typedef struct { typedef struct {
std::string type; std::string type;
pcap_args_t pcap; pkt_trace_args_t pkt_trace;
stack_log_args_t log; stack_log_args_t log;
usim_args_t usim; usim_args_t usim;
rrc_args_t rrc; rrc_args_t rrc;

@ -34,11 +34,11 @@
#include "srslte/common/buffer_pool.h" #include "srslte/common/buffer_pool.h"
#include "srslte/common/log_filter.h" #include "srslte/common/log_filter.h"
#include "srslte/common/multiqueue.h" #include "srslte/common/multiqueue.h"
#include "srslte/common/string_helpers.h"
#include "srslte/common/task_scheduler.h" #include "srslte/common/task_scheduler.h"
#include "srslte/common/thread_pool.h" #include "srslte/common/thread_pool.h"
#include "srslte/interfaces/ue_interfaces.h"
#include "srslte/common/time_prof.h" #include "srslte/common/time_prof.h"
#include "srslte/interfaces/ue_interfaces.h"
#include "srsue/hdr/ue_metrics_interface.h" #include "srsue/hdr/ue_metrics_interface.h"
#include "ue_stack_base.h" #include "ue_stack_base.h"
@ -177,6 +177,11 @@ private:
srslog::basic_logger& usim_logger; srslog::basic_logger& usim_logger;
srslog::basic_logger& nas_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 // RAT-specific interfaces
phy_interface_stack_lte* phy = nullptr; phy_interface_stack_lte* phy = nullptr;
gw_interface_stack* gw = nullptr; gw_interface_stack* gw = nullptr;
@ -193,8 +198,6 @@ private:
// stack components // stack components
srsue::mac mac; srsue::mac mac;
srslte::mac_pcap mac_pcap;
srslte::nas_pcap nas_pcap;
srslte::rlc rlc; srslte::rlc rlc;
srslte::pdcp pdcp; srslte::pdcp pdcp;
srsue::rrc rrc; srsue::rrc rrc;

@ -133,11 +133,11 @@ static int parse_args(all_args_t* args, int argc, char* argv[])
("nas.eia", bpo::value<string>(&args->stack.nas.eia)->default_value("1,2,3"), "List of integrity algorithms included in UE capabilities") ("nas.eia", bpo::value<string>(&args->stack.nas.eia)->default_value("1,2,3"), "List of integrity algorithms included in UE capabilities")
("nas.eea", bpo::value<string>(&args->stack.nas.eea)->default_value("0,1,2,3"), "List of ciphering algorithms included in UE capabilities") ("nas.eea", bpo::value<string>(&args->stack.nas.eea)->default_value("0,1,2,3"), "List of ciphering algorithms included in UE capabilities")
("pcap.enable", bpo::value<bool>(&args->stack.pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark") ("pcap.enable", bpo::value<string>(&args->stack.pkt_trace.enable)->default_value("none"), "Enable (MAC, MAC_NR, NAS) packet captures for wireshark")
("pcap.filename", bpo::value<string>(&args->stack.pcap.filename)->default_value("ue.pcap"), "MAC layer capture filename") ("pcap.mac_filename", bpo::value<string>(&args->stack.pkt_trace.mac_pcap.filename)->default_value("/tmp/ue_mac.pcap"), "MAC layer capture filename")
("pcap.nas_enable", bpo::value<bool>(&args->stack.pcap.nas_enable)->default_value(false), "Enable NAS packet captures for wireshark") ("pcap.mac_nr_filename", bpo::value<string>(&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<string>(&args->stack.pcap.nas_filename)->default_value("ue_nas.pcap"), "NAS layer capture filename (useful when NAS encryption is enabled)") ("pcap.nas_filename", bpo::value<string>(&args->stack.pkt_trace.nas_pcap.filename)->default_value("/tmp/ue_nas.pcap"), "NAS layer capture filename")
("gui.enable", bpo::value<bool>(&args->gui.enable)->default_value(false), "Enable GUI plots") ("gui.enable", bpo::value<bool>(&args->gui.enable)->default_value(false), "Enable GUI plots")
("log.rf_level", bpo::value<string>(&args->rf.log_level), "RF log level") ("log.rf_level", bpo::value<string>(&args->rf.log_level), "RF log level")

@ -17,7 +17,11 @@
namespace srsue { namespace srsue {
mac_nr::mac_nr(srslte::ext_task_sched_handle task_sched_) : 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(); tx_buffer = srslte::make_byte_buffer();
rlc_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 // Create Stack task dispatch queue
stack_task_dispatch_queue = task_sched.make_task_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); proc_ra.init(phy, this, &task_sched);
mux.init(); 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; return SRSLTE_SUCCESS;
} }
void mac_nr::start_pcap(srslte::mac_pcap* pcap_)
{
pcap = pcap_;
}
void mac_nr::stop() void mac_nr::stop()
{ {
if (started) { if (started) {
if (pcap != nullptr) {
pcap->close();
}
started = false; started = false;
} }
} }

@ -33,6 +33,8 @@ ue_stack_lte::ue_stack_lte() :
rrc_logger(srslog::fetch_basic_logger("RRC", false)), rrc_logger(srslog::fetch_basic_logger("RRC", false)),
usim_logger(srslog::fetch_basic_logger("USIM", false)), usim_logger(srslog::fetch_basic_logger("USIM", false)),
nas_logger(srslog::fetch_basic_logger("NAS", false)), nas_logger(srslog::fetch_basic_logger("NAS", false)),
mac_pcap(srslte_rat_t::lte),
mac_nr_pcap(srslte_rat_t::nr),
usim(nullptr), usim(nullptr),
phy(nullptr), phy(nullptr),
rlc("RLC"), rlc("RLC"),
@ -44,8 +46,7 @@ ue_stack_lte::ue_stack_lte() :
nas(&task_sched), nas(&task_sched),
thread("STACK"), thread("STACK"),
task_sched(512, 64), task_sched(512, 64),
tti_tprof("tti_tprof", "STCK", TTI_STAT_PERIOD), tti_tprof("tti_tprof", "STCK", TTI_STAT_PERIOD)
mac_pcap(srslte_rat_t::lte)
{ {
get_background_workers().set_nof_workers(2); get_background_workers().set_nof_workers(2);
ue_task_queue = task_sched.make_task_queue(); 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_level(srslog::str_to_basic_level(args.log.nas_level));
nas_logger.set_hex_dump_max_size(args.log.nas_hex_limit); nas_logger.set_hex_dump_max_size(args.log.nas_hex_limit);
// parse pcap trace list
std::vector<std::string> 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 // Set up pcap
if (args.pcap.enable) { if (args.pkt_trace.mac_pcap.enable) {
if (mac_pcap.open(args.pcap.filename.c_str()) == SRSLTE_SUCCESS) { if (mac_pcap.open(args.pkt_trace.mac_pcap.filename.c_str()) == SRSLTE_SUCCESS) {
mac.start_pcap(&mac_pcap); 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()); if (args.pkt_trace.mac_nr_pcap.enable) {
nas.start_pcap(&nas_pcap); 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 // 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(); pdcp.stop();
mac.stop(); mac.stop();
if (args.pcap.enable) { if (args.pkt_trace.mac_pcap.enable) {
mac_pcap.close(); 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(); nas_pcap.close();
} }

@ -66,7 +66,6 @@ int ue_stack_nr::init(const stack_args_t& args_)
pdcp_log->set_hex_limit(args.log.pdcp_hex_limit); pdcp_log->set_hex_limit(args.log.pdcp_hex_limit);
mac_nr_args_t mac_args = {}; mac_nr_args_t mac_args = {};
mac_args.pcap = args.pcap;
mac->init(mac_args, phy, rlc.get()); mac->init(mac_args, phy, rlc.get());
rlc->init(pdcp.get(), rrc.get(), task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */); rlc->init(pdcp.get(), rrc.get(), task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */);
pdcp->init(rlc.get(), rrc.get(), gw); pdcp->init(rlc.get(), rrc.get(), gw);

@ -28,7 +28,8 @@ using namespace rapidjson;
namespace bpo = boost::program_options; namespace bpo = boost::program_options;
typedef struct { typedef struct {
pcap_args_t pcap; pcap_args_t mac_pcap;
pcap_args_t nas_pcap;
std::string log_filename; std::string log_filename;
std::string log_level; std::string log_level;
int32_t log_hex_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"); bpo::options_description common("Configuration options");
// clang-format off // clang-format off
common.add_options() common.add_options()
("pcap.enable", bpo::value<bool>(&args->pcap.enable)->default_value(true), "Enable MAC packet captures for wireshark") ("pcap.enable", bpo::value<bool>(&args->mac_pcap.enable)->default_value(true), "Enable MAC packet captures for wireshark")
("pcap.filename", bpo::value<string>(&args->pcap.filename)->default_value("/tmp/ttcn3_ue.pcap"), "MAC layer capture filename") ("pcap.filename", bpo::value<string>(&args->mac_pcap.filename)->default_value("/tmp/ttcn3_ue.pcap"), "MAC layer capture filename")
("pcap.nas_enable", bpo::value<bool>(&args->pcap.nas_enable)->default_value(false), "Enable NAS packet captures for wireshark") ("pcap.nas_enable", bpo::value<bool>(&args->nas_pcap.enable)->default_value(false), "Enable NAS packet captures for wireshark")
("pcap.nas_filename", bpo::value<string>(&args->pcap.nas_filename)->default_value("/tmp/ttcn3_ue_nas.pcap"), "NAS layer capture filename (useful when NAS encryption is enabled)") ("pcap.nas_filename", bpo::value<string>(&args->nas_pcap.filename)->default_value("/tmp/ttcn3_ue_nas.pcap"), "NAS layer capture filename (useful when NAS encryption is enabled)")
("logfilename", bpo::value<std::string>(&args->log_filename)->default_value("/tmp/ttcn3_ue.log"), "Filename of log file") ("logfilename", bpo::value<std::string>(&args->log_filename)->default_value("/tmp/ttcn3_ue.log"), "Filename of log file")
("loglevel", bpo::value<std::string>(&args->log_level)->default_value("warning"), "Log level (Error,Warning,Info,Debug)") ("loglevel", bpo::value<std::string>(&args->log_level)->default_value("warning"), "Log level (Error,Warning,Info,Debug)")
("loghexlevel", bpo::value<int32_t>(&args->log_hex_level)->default_value(64), "Log hex level (-1 unbounded)"); ("loghexlevel", bpo::value<int32_t>(&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_t all_args = {};
all_args.stack.pcap.enable = args->pcap.enable; all_args.stack.pkt_trace.mac_pcap.enable = args->mac_pcap.enable;
all_args.stack.pcap.nas_enable = args->pcap.nas_enable; all_args.stack.pkt_trace.mac_pcap.filename = args->mac_pcap.filename;
all_args.stack.pcap.filename = args->pcap.filename; all_args.stack.pkt_trace.nas_pcap.enable = args->nas_pcap.enable;
all_args.stack.pcap.nas_filename = args->pcap.nas_filename; all_args.stack.pkt_trace.nas_pcap.filename = args->nas_pcap.filename;
all_args.log.filename = args->log_filename; all_args.log.filename = args->log_filename;
all_args.log.all_level = args->log_level; all_args.log.all_level = args->log_level;

@ -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()); srslte::console("Initializing UE ID=%d for TC=%s\n", run_id, tc_name.c_str());
// Patch UE config // Patch UE config
local_args.stack.pcap.filename = get_filename_with_tc_name(args.stack.pcap.filename, run_id, tc_name); local_args.stack.pkt_trace.mac_pcap.filename =
local_args.stack.pcap.nas_filename = get_filename_with_tc_name(args.stack.pcap.nas_filename, run_id, tc_name); 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 // bring up UE
if (ue->init(local_args, this, tc_name)) { if (ue->init(local_args, this, tc_name)) {

@ -55,7 +55,7 @@ tx_gain = 80
##################################################################### #####################################################################
# Packet capture configuration # 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 # MAC-layer packets are captured to file in the compact format
# decoded by the Wireshark mac-lte-framed dissector. # decoded by the Wireshark mac-lte-framed dissector.
# To use this dissector, edit the preferences for DLT_USER to # 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 # NAS-layer packets are dissected with DLT=148, and
# Payload Protocol = nas-eps. # Payload Protocol = nas-eps.
# #
# enable: Enable MAC layer packet captures (true/false) # enable: Enable packet captures of layers (mac/mac_nr/nas/none) multiple option list
# filename: File path to use for MAC packet captures # mac_filename: File path to use for MAC packet capture
# nas_enable: Enable NAS layer packet captures (true/false) # mac_nr_filename: File path to use for MAC NR packet capture
# nas_filename: File path to use for NAS packet captures # nas_filename: File path to use for NAS packet capture
##################################################################### #####################################################################
[pcap] [pcap]
enable = false enable = none
filename = /tmp/ue.pcap mac_filename = /tmp/ue_mac.pcap
nas_enable = false mac_nr_filename = /tmp/ue_mac_nr.pcap
nas_filename = /tmp/nas.pcap nas_filename = /tmp/nas.pcap
##################################################################### #####################################################################

Loading…
Cancel
Save