Added the ability to save S1AP pcaps at the eNB.

master
Pedro Alvarez 5 years ago
parent 2edecea33e
commit 08a4ce0970

@ -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. # the Wireshark mac-lte-framed dissector and with DLT 147.
# To use the dissector, edit the preferences for DLT_USER to # To use the dissector, edit the preferences for DLT_USER to
# add an entry with DLT=147, Payload Protocol=mac-lte-framed. # 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 # WRITE_SIB_PCAP enabled in srsenb/src/stack/mac/mac.cc if you want
# SIB to be part of the MAC pcap file. # SIB to be part of the MAC pcap file.
# #
# enable: Enable MAC layer packet captures (true/false) # S1AP Packets are captured to file in the compact format decoded by
# filename: File path to use for packet captures # 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] [pcap]
enable = false mac_enable = false
filename = /tmp/enb.pcap mac_filename = /tmp/enb_mac.pcap
s1ap_enable = false
s1ap_filename = /tmp/enb_s1ap.pcap
##################################################################### #####################################################################
# Log configuration # Log configuration

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

@ -143,6 +143,7 @@ private:
srsenb::rrc rrc; srsenb::rrc rrc;
srsenb::gtpu gtpu; srsenb::gtpu gtpu;
srsenb::s1ap s1ap; srsenb::s1ap s1ap;
srslte::s1ap_pcap s1ap_pcap;
srslte::logger* logger = nullptr; srslte::logger* logger = nullptr;
srslte::byte_buffer_pool* pool = nullptr; srslte::byte_buffer_pool* pool = nullptr;

@ -28,6 +28,7 @@
#include "srslte/common/buffer_pool.h" #include "srslte/common/buffer_pool.h"
#include "srslte/common/common.h" #include "srslte/common/common.h"
#include "srslte/common/logmap.h" #include "srslte/common/logmap.h"
#include "srslte/common/s1ap_pcap.h"
#include "srslte/common/threads.h" #include "srslte/common/threads.h"
#include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/enb_interfaces.h"
@ -86,6 +87,7 @@ public:
// Stack interface // Stack interface
bool 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: private:
static const int MME_PORT = 36412; static const int MME_PORT = 36412;
@ -114,6 +116,9 @@ private:
asn1::s1ap::tai_s tai; asn1::s1ap::tai_s tai;
asn1::s1ap::eutran_cgi_s eutran_cgi; asn1::s1ap::eutran_cgi_s eutran_cgi;
// PCAP
srslte::s1ap_pcap *pcap;
asn1::s1ap::s1_setup_resp_s s1setupresponse; asn1::s1ap::s1_setup_resp_s s1setupresponse;
void build_tai_cgi(); void build_tai_cgi();

@ -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.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") ("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") ("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.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_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") ("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.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)") ("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 */ /* 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_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") ("scheduler.pdsch_max_mcs", bpo::value<int>(&args->stack.mac.sched.pdsch_max_mcs)->default_value(-1), "Optional PDSCH MCS limit")

@ -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); stack_log.set_hex_limit(128);
// Set up pcap and trace // Set up pcap and trace
if (args.pcap.enable) { if (args.mac_pcap.enable) {
mac_pcap.open(args.pcap.filename.c_str()); mac_pcap.open(args.mac_pcap.filename.c_str());
mac.start_pcap(&mac_pcap); 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 // Init Rx socket handler
rx_sockets.reset(new srslte::rx_multisocket_handler("ENBSOCKETS", &stack_log)); rx_sockets.reset(new srslte::rx_multisocket_handler("ENBSOCKETS", &stack_log));
@ -156,9 +160,12 @@ void enb_stack_lte::stop_impl()
pdcp.stop(); pdcp.stop();
rrc.stop(); rrc.stop();
if (args.pcap.enable) { if (args.mac_pcap.enable) {
mac_pcap.close(); 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() // erasing the queues is the last thing, bc we need them to call stop_impl()
pending_tasks.erase_queue(sync_queue_id); pending_tasks.erase_queue(sync_queue_id);

@ -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) 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; s1ap_pdu_c rx_pdu;
asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); 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; return false;
} }
asn1::bit_ref bref(buf->msg, buf->get_tailroom()); asn1::bit_ref bref(buf->msg, buf->get_tailroom());
tx_pdu.pack(bref); tx_pdu.pack(bref);
buf->N_bytes = bref.distance_bytes(); buf->N_bytes = bref.distance_bytes();
// Save message to PCAP
if (pcap != nullptr) {
pcap->write_s1ap(buf->msg, buf->N_bytes);
}
if (rnti > 0) { if (rnti > 0) {
s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending %s for rnti=0x%x", procedure_name, rnti); s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending %s for rnti=0x%x", procedure_name, rnti);
} else { } else {
@ -1216,6 +1226,10 @@ std::string s1ap::get_cause(const cause_c& c)
return cause; return cause;
} }
void s1ap::start_pcap(srslte::s1ap_pcap* pcap_)
{
pcap = pcap_;
}
/******************************************************************************* /*******************************************************************************
/* s1ap::ue Class /* s1ap::ue Class
********************************************************************************/ ********************************************************************************/

Loading…
Cancel
Save