Added the ability to save S1AP pcaps at the eNB.

This commit is contained in:
Pedro Alvarez 2020-03-06 17:48:12 +00:00
parent 2edecea33e
commit 08a4ce0970
7 changed files with 65 additions and 23 deletions

View File

@ -76,9 +76,9 @@ rx_gain = 40
#####################################################################
# MAC-layer packet capture configuration
# Packet capture configuration
#
# Packets are captured to file in the compact format decoded by
# MAC Packets are captured to file in the compact format decoded by
# the Wireshark mac-lte-framed dissector and with DLT 147.
# To use the dissector, edit the preferences for DLT_USER to
# add an entry with DLT=147, Payload Protocol=mac-lte-framed.
@ -89,12 +89,22 @@ rx_gain = 40
# WRITE_SIB_PCAP enabled in srsenb/src/stack/mac/mac.cc if you want
# SIB to be part of the MAC pcap file.
#
# enable: Enable MAC layer packet captures (true/false)
# filename: File path to use for packet captures
# S1AP Packets are captured to file in the compact format decoded by
# the Wireshark s1ap dissector and with DLT 150.
# To use the dissector, edit the preferences for DLT_USER to
# add an entry with DLT=150, Payload Protocol=s1ap.
#
# mac_enable: Enable MAC layer packet captures (true/false)
# mac_filename: File path to use for packet captures
# s1ap_enable: Enable or disable the PCAP.
# s1ap_filename: File name where to save the PCAP.
#
#####################################################################
[pcap]
enable = false
filename = /tmp/enb.pcap
mac_enable = false
mac_filename = /tmp/enb_mac.pcap
s1ap_enable = false
s1ap_filename = /tmp/enb_s1ap.pcap
#####################################################################
# Log configuration
@ -268,4 +278,4 @@ nof_ctrl_symbols = 3
#rrc_inactivity_timer = 60000
#max_prach_offset_us = 30
#eea_pref_list = EEA0, EEA2, EEA1
#eia_pref_list = EIA2, EIA1, EIA0
#eia_pref_list = EIA2, EIA1, EIA0

View File

@ -56,7 +56,8 @@ typedef struct {
typedef struct {
mac_args_t mac;
s1ap_args_t s1ap;
pcap_args_t pcap;
pcap_args_t mac_pcap;
pcap_args_t s1ap_pcap;
stack_log_args_t log;
embms_args_t embms;
} stack_args_t;

View File

@ -136,13 +136,14 @@ private:
srslte::timer_handler timers;
std::unique_ptr<srslte::rx_multisocket_handler> rx_sockets;
srsenb::mac mac;
srslte::mac_pcap mac_pcap;
srsenb::rlc rlc;
srsenb::pdcp pdcp;
srsenb::rrc rrc;
srsenb::gtpu gtpu;
srsenb::s1ap s1ap;
srsenb::mac mac;
srslte::mac_pcap mac_pcap;
srsenb::rlc rlc;
srsenb::pdcp pdcp;
srsenb::rrc rrc;
srsenb::gtpu gtpu;
srsenb::s1ap s1ap;
srslte::s1ap_pcap s1ap_pcap;
srslte::logger* logger = nullptr;
srslte::byte_buffer_pool* pool = nullptr;

View File

@ -28,6 +28,7 @@
#include "srslte/common/buffer_pool.h"
#include "srslte/common/common.h"
#include "srslte/common/logmap.h"
#include "srslte/common/s1ap_pcap.h"
#include "srslte/common/threads.h"
#include "srslte/interfaces/enb_interfaces.h"
@ -85,7 +86,8 @@ public:
// Stack interface
bool
handle_mme_rx_msg(srslte::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags);
handle_mme_rx_msg(srslte::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags);
void start_pcap(srslte::s1ap_pcap* pcap_);
private:
static const int MME_PORT = 36412;
@ -114,6 +116,9 @@ private:
asn1::s1ap::tai_s tai;
asn1::s1ap::eutran_cgi_s eutran_cgi;
// PCAP
srslte::s1ap_pcap *pcap;
asn1::s1ap::s1_setup_resp_s s1setupresponse;
void build_tai_cgi();

View File

@ -90,11 +90,9 @@ void parse_args(all_args_t* args, int argc, char* argv[])
("rf.device_args", bpo::value<string>(&args->rf.device_args)->default_value("auto"), "Front-end device arguments")
("rf.time_adv_nsamples", bpo::value<string>(&args->rf.time_adv_nsamples)->default_value("auto"), "Transmission time advance")
("pcap.enable", bpo::value<bool>(&args->stack.pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark")
("pcap.filename", bpo::value<string>(&args->stack.pcap.filename)->default_value("ue.pcap"), "MAC layer capture filename")
("gui.enable", bpo::value<bool>(&args->gui.enable)->default_value(false), "Enable GUI plots")
/* Log section */
("log.rf_level", bpo::value<string>(&args->rf.log_level), "RF log level")
("log.phy_level", bpo::value<string>(&args->phy.log.phy_level), "PHY log level")
("log.phy_hex_limit", bpo::value<int>(&args->phy.log.phy_hex_limit), "PHY log hex dump limit")
@ -118,6 +116,12 @@ void parse_args(all_args_t* args, int argc, char* argv[])
("log.filename", bpo::value<string>(&args->log.filename)->default_value("/tmp/ue.log"),"Log filename")
("log.file_max_size", bpo::value<int>(&args->log.file_max_size)->default_value(-1), "Maximum file size (in kilobytes). When passed, multiple files are created. Default -1 (single file)")
/* PCAP */
("pcap.mac_enable", bpo::value<bool>(&args->stack.mac_pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark")
("pcap.mac_filename", bpo::value<string>(&args->stack.mac_pcap.filename)->default_value("enb_mac.pcap"), "MAC layer capture filename")
("pcap.s1ap_enable", bpo::value<bool>(&args->stack.s1ap_pcap.enable)->default_value(false), "Enable S1AP packet captures for wireshark")
("pcap.s1ap_filename", bpo::value<string>(&args->stack.s1ap_pcap.filename)->default_value("enb_s1ap.pcap"), "S1AP layer capture filename")
/* MCS section */
("scheduler.pdsch_mcs", bpo::value<int>(&args->stack.mac.sched.pdsch_mcs)->default_value(-1), "Optional fixed PDSCH MCS (ignores reported CQIs if specified)")
("scheduler.pdsch_max_mcs", bpo::value<int>(&args->stack.mac.sched.pdsch_max_mcs)->default_value(-1), "Optional PDSCH MCS limit")

View File

@ -97,10 +97,14 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_)
stack_log.set_hex_limit(128);
// Set up pcap and trace
if (args.pcap.enable) {
mac_pcap.open(args.pcap.filename.c_str());
if (args.mac_pcap.enable) {
mac_pcap.open(args.mac_pcap.filename.c_str());
mac.start_pcap(&mac_pcap);
}
if (args.s1ap_pcap.enable) {
s1ap_pcap.open(args.s1ap_pcap.filename.c_str());
s1ap.start_pcap(&s1ap_pcap);
}
// Init Rx socket handler
rx_sockets.reset(new srslte::rx_multisocket_handler("ENBSOCKETS", &stack_log));
@ -156,9 +160,12 @@ void enb_stack_lte::stop_impl()
pdcp.stop();
rrc.stop();
if (args.pcap.enable) {
if (args.mac_pcap.enable) {
mac_pcap.close();
}
if (args.s1ap_pcap.enable) {
s1ap_pcap.close();
}
// erasing the queues is the last thing, bc we need them to call stop_impl()
pending_tasks.erase_queue(sync_queue_id);

View File

@ -505,6 +505,11 @@ bool s1ap::handle_mme_rx_msg(srslte::unique_byte_buffer_t pdu,
bool s1ap::handle_s1ap_rx_pdu(srslte::byte_buffer_t* pdu)
{
// Save message to PCAP
if (pcap != nullptr) {
pcap->write_s1ap(pdu->msg, pdu->N_bytes);
}
s1ap_pdu_c rx_pdu;
asn1::cbit_ref bref(pdu->msg, pdu->N_bytes);
@ -1137,9 +1142,14 @@ bool s1ap::sctp_send_s1ap_pdu(const asn1::s1ap::s1ap_pdu_c& tx_pdu, uint32_t rnt
return false;
}
asn1::bit_ref bref(buf->msg, buf->get_tailroom());
tx_pdu.pack(bref);
buf->N_bytes = bref.distance_bytes();
// Save message to PCAP
if (pcap != nullptr) {
pcap->write_s1ap(buf->msg, buf->N_bytes);
}
if (rnti > 0) {
s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending %s for rnti=0x%x", procedure_name, rnti);
} else {
@ -1216,6 +1226,10 @@ std::string s1ap::get_cause(const cause_c& c)
return cause;
}
void s1ap::start_pcap(srslte::s1ap_pcap* pcap_)
{
pcap = pcap_;
}
/*******************************************************************************
/* s1ap::ue Class
********************************************************************************/