|
|
@ -49,14 +49,14 @@ namespace bpo = boost::program_options;
|
|
|
|
***********************************************************************/
|
|
|
|
***********************************************************************/
|
|
|
|
string config_file;
|
|
|
|
string config_file;
|
|
|
|
|
|
|
|
|
|
|
|
void parse_args(all_args_t *args, int argc, char* argv[]) {
|
|
|
|
void parse_args(all_args_t *args, int argc, char *argv[]) {
|
|
|
|
|
|
|
|
|
|
|
|
// Command line only options
|
|
|
|
// Command line only options
|
|
|
|
bpo::options_description general("General options");
|
|
|
|
bpo::options_description general("General options");
|
|
|
|
|
|
|
|
|
|
|
|
general.add_options()
|
|
|
|
general.add_options()
|
|
|
|
("help,h", "Produce help message")
|
|
|
|
("help,h", "Produce help message")
|
|
|
|
("version,v", "Print version information and exit")
|
|
|
|
("version,v", "Print version information and exit");
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Command line or config file options
|
|
|
|
// Command line or config file options
|
|
|
|
bpo::options_description common("Configuration options");
|
|
|
|
bpo::options_description common("Configuration options");
|
|
|
@ -69,15 +69,20 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
|
|
|
|
|
|
|
|
|
|
|
|
("rf.device_name", bpo::value<string>(&args->rf.device_name)->default_value("auto"), "Front-end device name")
|
|
|
|
("rf.device_name", bpo::value<string>(&args->rf.device_name)->default_value("auto"), "Front-end device name")
|
|
|
|
("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"),
|
|
|
|
("rf.burst_preamble_us", bpo::value<string>(&args->rf.burst_preamble)->default_value("auto"), "Transmission time advance")
|
|
|
|
"Transmission time advance")
|
|
|
|
|
|
|
|
("rf.burst_preamble_us", bpo::value<string>(&args->rf.burst_preamble)->default_value("auto"),
|
|
|
|
|
|
|
|
"Transmission time advance")
|
|
|
|
|
|
|
|
|
|
|
|
("pcap.enable", bpo::value<bool>(&args->pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark")
|
|
|
|
("pcap.enable", bpo::value<bool>(&args->pcap.enable)->default_value(false),
|
|
|
|
|
|
|
|
"Enable MAC packet captures for wireshark")
|
|
|
|
("pcap.filename", bpo::value<string>(&args->pcap.filename)->default_value("ue.pcap"), "MAC layer capture filename")
|
|
|
|
("pcap.filename", bpo::value<string>(&args->pcap.filename)->default_value("ue.pcap"), "MAC layer capture filename")
|
|
|
|
|
|
|
|
|
|
|
|
("trace.enable", bpo::value<bool>(&args->trace.enable)->default_value(false), "Enable PHY and radio timing traces")
|
|
|
|
("trace.enable", bpo::value<bool>(&args->trace.enable)->default_value(false), "Enable PHY and radio timing traces")
|
|
|
|
("trace.phy_filename",bpo::value<string>(&args->trace.phy_filename)->default_value("ue.phy_trace"), "PHY timing traces filename")
|
|
|
|
("trace.phy_filename", bpo::value<string>(&args->trace.phy_filename)->default_value("ue.phy_trace"),
|
|
|
|
("trace.radio_filename",bpo::value<string>(&args->trace.radio_filename)->default_value("ue.radio_trace"), "Radio timing traces filename")
|
|
|
|
"PHY timing traces filename")
|
|
|
|
|
|
|
|
("trace.radio_filename", bpo::value<string>(&args->trace.radio_filename)->default_value("ue.radio_trace"),
|
|
|
|
|
|
|
|
"Radio timing traces 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")
|
|
|
|
|
|
|
|
|
|
|
@ -88,7 +93,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
|
|
|
|
("log.rlc_level", bpo::value<string>(&args->log.rlc_level), "RLC log level")
|
|
|
|
("log.rlc_level", bpo::value<string>(&args->log.rlc_level), "RLC log level")
|
|
|
|
("log.rlc_hex_limit", bpo::value<int>(&args->log.rlc_hex_limit), "RLC log hex dump limit")
|
|
|
|
("log.rlc_hex_limit", bpo::value<int>(&args->log.rlc_hex_limit), "RLC log hex dump limit")
|
|
|
|
("log.pdcp_level", bpo::value<string>(&args->log.pdcp_level), "PDCP log level")
|
|
|
|
("log.pdcp_level", bpo::value<string>(&args->log.pdcp_level), "PDCP log level")
|
|
|
|
("log.pdcp_hex_limit",bpo::value<int>(&args->log.pdcp_hex_limit), "PDCP log hex dump limit")
|
|
|
|
("log.pdcp_hex_limit", bpo::value<int>(&args->log.pdcp_hex_limit), "PDCP log hex dump limit")
|
|
|
|
("log.rrc_level", bpo::value<string>(&args->log.rrc_level), "RRC log level")
|
|
|
|
("log.rrc_level", bpo::value<string>(&args->log.rrc_level), "RRC log level")
|
|
|
|
("log.rrc_hex_limit", bpo::value<int>(&args->log.rrc_hex_limit), "RRC log hex dump limit")
|
|
|
|
("log.rrc_hex_limit", bpo::value<int>(&args->log.rrc_hex_limit), "RRC log hex dump limit")
|
|
|
|
("log.gw_level", bpo::value<string>(&args->log.gw_level), "GW log level")
|
|
|
|
("log.gw_level", bpo::value<string>(&args->log.gw_level), "GW log level")
|
|
|
@ -96,12 +101,12 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
|
|
|
|
("log.nas_level", bpo::value<string>(&args->log.nas_level), "NAS log level")
|
|
|
|
("log.nas_level", bpo::value<string>(&args->log.nas_level), "NAS log level")
|
|
|
|
("log.nas_hex_limit", bpo::value<int>(&args->log.nas_hex_limit), "NAS log hex dump limit")
|
|
|
|
("log.nas_hex_limit", bpo::value<int>(&args->log.nas_hex_limit), "NAS log hex dump limit")
|
|
|
|
("log.usim_level", bpo::value<string>(&args->log.usim_level), "USIM log level")
|
|
|
|
("log.usim_level", bpo::value<string>(&args->log.usim_level), "USIM log level")
|
|
|
|
("log.usim_hex_limit",bpo::value<int>(&args->log.usim_hex_limit), "USIM log hex dump limit")
|
|
|
|
("log.usim_hex_limit", bpo::value<int>(&args->log.usim_hex_limit), "USIM log hex dump limit")
|
|
|
|
|
|
|
|
|
|
|
|
("log.all_level", bpo::value<string>(&args->log.all_level)->default_value("info"), "ALL log level")
|
|
|
|
("log.all_level", bpo::value<string>(&args->log.all_level)->default_value("info"), "ALL log level")
|
|
|
|
("log.all_hex_limit", bpo::value<int>(&args->log.all_hex_limit)->default_value(32), "ALL log hex dump limit")
|
|
|
|
("log.all_hex_limit", bpo::value<int>(&args->log.all_hex_limit)->default_value(32), "ALL log hex dump limit")
|
|
|
|
|
|
|
|
|
|
|
|
("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")
|
|
|
|
|
|
|
|
|
|
|
|
("usim.algo", bpo::value<string>(&args->usim.algo), "USIM authentication algorithm")
|
|
|
|
("usim.algo", bpo::value<string>(&args->usim.algo), "USIM authentication algorithm")
|
|
|
|
("usim.op", bpo::value<string>(&args->usim.op), "USIM operator variant")
|
|
|
|
("usim.op", bpo::value<string>(&args->usim.op), "USIM operator variant")
|
|
|
@ -197,18 +202,19 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
|
|
|
|
"Chooses the coefficients for the 3-tap channel estimator centered filter.")
|
|
|
|
"Chooses the coefficients for the 3-tap channel estimator centered filter.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
("rf_calibration.tx_corr_dc_gain", bpo::value<float>(&args->rf_cal.tx_corr_dc_gain)->default_value(0.0), "TX DC offset gain correction")
|
|
|
|
("rf_calibration.tx_corr_dc_gain", bpo::value<float>(&args->rf_cal.tx_corr_dc_gain)->default_value(0.0),
|
|
|
|
("rf_calibration.tx_corr_dc_phase", bpo::value<float>(&args->rf_cal.tx_corr_dc_phase)->default_value(0.0), "TX DC offset phase correction")
|
|
|
|
"TX DC offset gain correction")
|
|
|
|
("rf_calibration.tx_corr_iq_i", bpo::value<float>(&args->rf_cal.tx_corr_iq_i)->default_value(0.0), "TX IQ imbalance inphase correction")
|
|
|
|
("rf_calibration.tx_corr_dc_phase", bpo::value<float>(&args->rf_cal.tx_corr_dc_phase)->default_value(0.0),
|
|
|
|
("rf_calibration.tx_corr_iq_q", bpo::value<float>(&args->rf_cal.tx_corr_iq_q)->default_value(0.0), "TX IQ imbalance quadrature correction")
|
|
|
|
"TX DC offset phase correction")
|
|
|
|
|
|
|
|
("rf_calibration.tx_corr_iq_i", bpo::value<float>(&args->rf_cal.tx_corr_iq_i)->default_value(0.0),
|
|
|
|
;
|
|
|
|
"TX IQ imbalance inphase correction")
|
|
|
|
|
|
|
|
("rf_calibration.tx_corr_iq_q", bpo::value<float>(&args->rf_cal.tx_corr_iq_q)->default_value(0.0),
|
|
|
|
|
|
|
|
"TX IQ imbalance quadrature correction");
|
|
|
|
|
|
|
|
|
|
|
|
// Positional options - config file location
|
|
|
|
// Positional options - config file location
|
|
|
|
bpo::options_description position("Positional options");
|
|
|
|
bpo::options_description position("Positional options");
|
|
|
|
position.add_options()
|
|
|
|
position.add_options()
|
|
|
|
("config_file", bpo::value< string >(&config_file), "UE configuration file")
|
|
|
|
("config_file", bpo::value<string>(&config_file), "UE configuration file");
|
|
|
|
;
|
|
|
|
|
|
|
|
bpo::positional_options_description p;
|
|
|
|
bpo::positional_options_description p;
|
|
|
|
p.add("config_file", -1);
|
|
|
|
p.add("config_file", -1);
|
|
|
|
|
|
|
|
|
|
|
@ -245,7 +251,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
cout << "Reading configuration file " << config_file << "..." << endl;
|
|
|
|
cout << "Reading configuration file " << config_file << "..." << endl;
|
|
|
|
ifstream conf(config_file.c_str(), ios::in);
|
|
|
|
ifstream conf(config_file.c_str(), ios::in);
|
|
|
|
if(conf.fail()) {
|
|
|
|
if (conf.fail()) {
|
|
|
|
cout << "Failed to read configuration file " << config_file << " - exiting" << endl;
|
|
|
|
cout << "Failed to read configuration file " << config_file << " - exiting" << endl;
|
|
|
|
exit(1);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -255,56 +261,57 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
|
|
|
|
|
|
|
|
|
|
|
|
// Apply all_level to any unset layers
|
|
|
|
// Apply all_level to any unset layers
|
|
|
|
if (vm.count("log.all_level")) {
|
|
|
|
if (vm.count("log.all_level")) {
|
|
|
|
if(!vm.count("log.phy_level")) {
|
|
|
|
if (!vm.count("log.phy_level")) {
|
|
|
|
args->log.phy_level = args->log.all_level;
|
|
|
|
args->log.phy_level = args->log.all_level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.mac_level")) {
|
|
|
|
if (!vm.count("log.mac_level")) {
|
|
|
|
args->log.mac_level = args->log.all_level;
|
|
|
|
args->log.mac_level = args->log.all_level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.rlc_level")) {
|
|
|
|
if (!vm.count("log.rlc_level")) {
|
|
|
|
args->log.rlc_level = args->log.all_level;
|
|
|
|
args->log.rlc_level = args->log.all_level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.pdcp_level")) {
|
|
|
|
if (!vm.count("log.pdcp_level")) {
|
|
|
|
args->log.pdcp_level = args->log.all_level;
|
|
|
|
args->log.pdcp_level = args->log.all_level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.rrc_level")) {
|
|
|
|
if (!vm.count("log.rrc_level")) {
|
|
|
|
args->log.rrc_level = args->log.all_level;
|
|
|
|
args->log.rrc_level = args->log.all_level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.nas_level")) {
|
|
|
|
if (!vm.count("log.nas_level")) {
|
|
|
|
args->log.nas_level = args->log.all_level;
|
|
|
|
args->log.nas_level = args->log.all_level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.gw_level")) {
|
|
|
|
if (!vm.count("log.gw_level")) {
|
|
|
|
args->log.gw_level = args->log.all_level;
|
|
|
|
args->log.gw_level = args->log.all_level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.usim_level")) {
|
|
|
|
if (!vm.count("log.usim_level")) {
|
|
|
|
args->log.usim_level = args->log.all_level;
|
|
|
|
args->log.usim_level = args->log.all_level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Apply all_hex_limit to any unset layers
|
|
|
|
// Apply all_hex_limit to any unset layers
|
|
|
|
if (vm.count("log.all_hex_limit")) {
|
|
|
|
if (vm.count("log.all_hex_limit")) {
|
|
|
|
if(!vm.count("log.phy_hex_limit")) {
|
|
|
|
if (!vm.count("log.phy_hex_limit")) {
|
|
|
|
args->log.phy_hex_limit = args->log.all_hex_limit;
|
|
|
|
args->log.phy_hex_limit = args->log.all_hex_limit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.mac_hex_limit")) {
|
|
|
|
if (!vm.count("log.mac_hex_limit")) {
|
|
|
|
args->log.mac_hex_limit = args->log.all_hex_limit;
|
|
|
|
args->log.mac_hex_limit = args->log.all_hex_limit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.rlc_hex_limit")) {
|
|
|
|
if (!vm.count("log.rlc_hex_limit")) {
|
|
|
|
args->log.rlc_hex_limit = args->log.all_hex_limit;
|
|
|
|
args->log.rlc_hex_limit = args->log.all_hex_limit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.pdcp_hex_limit")) {
|
|
|
|
if (!vm.count("log.pdcp_hex_limit")) {
|
|
|
|
args->log.pdcp_hex_limit = args->log.all_hex_limit;
|
|
|
|
args->log.pdcp_hex_limit = args->log.all_hex_limit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.rrc_hex_limit")) {
|
|
|
|
if (!vm.count("log.rrc_hex_limit")) {
|
|
|
|
args->log.rrc_hex_limit = args->log.all_hex_limit;
|
|
|
|
args->log.rrc_hex_limit = args->log.all_hex_limit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.nas_hex_limit")) {
|
|
|
|
if (!vm.count("log.nas_hex_limit")) {
|
|
|
|
args->log.nas_hex_limit = args->log.all_hex_limit;
|
|
|
|
args->log.nas_hex_limit = args->log.all_hex_limit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.gw_hex_limit")) {
|
|
|
|
if (!vm.count("log.gw_hex_limit")) {
|
|
|
|
args->log.gw_hex_limit = args->log.all_hex_limit;
|
|
|
|
args->log.gw_hex_limit = args->log.all_hex_limit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!vm.count("log.usim_hex_limit")) {
|
|
|
|
if (!vm.count("log.usim_hex_limit")) {
|
|
|
|
args->log.usim_hex_limit = args->log.all_hex_limit;
|
|
|
|
args->log.usim_hex_limit = args->log.all_hex_limit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -313,20 +320,18 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
|
|
|
|
static bool running = true;
|
|
|
|
static bool running = true;
|
|
|
|
static bool do_metrics = false;
|
|
|
|
static bool do_metrics = false;
|
|
|
|
|
|
|
|
|
|
|
|
void sig_int_handler(int signo)
|
|
|
|
void sig_int_handler(int signo) {
|
|
|
|
{
|
|
|
|
|
|
|
|
running = false;
|
|
|
|
running = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void *input_loop(void *m)
|
|
|
|
void *input_loop(void *m) {
|
|
|
|
{
|
|
|
|
metrics_stdout *metrics = (metrics_stdout *) m;
|
|
|
|
metrics_stdout *metrics = (metrics_stdout*)m;
|
|
|
|
|
|
|
|
char key;
|
|
|
|
char key;
|
|
|
|
while(running) {
|
|
|
|
while (running) {
|
|
|
|
cin >> key;
|
|
|
|
cin >> key;
|
|
|
|
if('t' == key) {
|
|
|
|
if ('t' == key) {
|
|
|
|
do_metrics = !do_metrics;
|
|
|
|
do_metrics = !do_metrics;
|
|
|
|
if(do_metrics) {
|
|
|
|
if (do_metrics) {
|
|
|
|
cout << "Enter t to stop trace." << endl;
|
|
|
|
cout << "Enter t to stop trace." << endl;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
cout << "Enter t to restart trace." << endl;
|
|
|
|
cout << "Enter t to restart trace." << endl;
|
|
|
@ -337,8 +342,7 @@ void *input_loop(void *m)
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
{
|
|
|
|
|
|
|
|
signal(SIGINT, sig_int_handler);
|
|
|
|
signal(SIGINT, sig_int_handler);
|
|
|
|
all_args_t args;
|
|
|
|
all_args_t args;
|
|
|
|
metrics_stdout metrics;
|
|
|
|
metrics_stdout metrics;
|
|
|
@ -347,7 +351,7 @@ int main(int argc, char *argv[])
|
|
|
|
cout << "--- Software Radio Systems LTE UE ---" << endl << endl;
|
|
|
|
cout << "--- Software Radio Systems LTE UE ---" << endl << endl;
|
|
|
|
|
|
|
|
|
|
|
|
parse_args(&args, argc, argv);
|
|
|
|
parse_args(&args, argc, argv);
|
|
|
|
if(!ue->init(&args)) {
|
|
|
|
if (!ue->init(&args)) {
|
|
|
|
exit(1);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
metrics.init(ue, args.expert.metrics_period_secs);
|
|
|
|
metrics.init(ue, args.expert.metrics_period_secs);
|
|
|
@ -357,7 +361,7 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
|
|
|
|
|
|
bool plot_started = false;
|
|
|
|
bool plot_started = false;
|
|
|
|
bool signals_pregenerated = false;
|
|
|
|
bool signals_pregenerated = false;
|
|
|
|
while(running) {
|
|
|
|
while (running) {
|
|
|
|
if (ue->is_attached()) {
|
|
|
|
if (ue->is_attached()) {
|
|
|
|
if (!signals_pregenerated && args.expert.pregenerate_signals) {
|
|
|
|
if (!signals_pregenerated && args.expert.pregenerate_signals) {
|
|
|
|
ue->pregenerate_signals(true);
|
|
|
|
ue->pregenerate_signals(true);
|
|
|
|