diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 5a3de3ac6..8388083ff 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -35,7 +35,7 @@ typedef struct{ uint16_t tac; // 16-bit tac uint16_t mcc; // BCD-coded with 0xF filler uint16_t mnc; // BCD-coded with 0xF filler - std::string mme_bindx_addr; + std::string mme_bind_addr; std::string mme_name; } s1ap_args_t; @@ -56,7 +56,7 @@ private: uint16_t m_tac; // 16-bit tac uint16_t m_mcc; // BCD-coded with 0xF filler uint16_t m_mnc; // BCD-coded with 0xF filler - std::string m_mme_bindx_addr; + std::string m_mme_bind_addr; std::string m_mme_name; srslte::log *m_log_h; diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index f1809af7f..42759749f 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -31,6 +31,7 @@ #include #include #include +#include "srslte/common/bcd_helpers.h" #include "mme/mme.h" using namespace std; @@ -44,16 +45,21 @@ sig_int_handler(int signo){ running = false; } +/********************************************************************** + * Program arguments processing + ***********************************************************************/ +string config_file; -/* void parse_args(all_args_t *args, int argc, char* argv[]) { + string mme_name; string mme_code; string mme_group; string tac; string mcc; string mnc; + string mme_bind_addr; // Command line only options bpo::options_description general("General options"); @@ -66,42 +72,86 @@ parse_args(all_args_t *args, int argc, char* argv[]) { bpo::options_description common("Configuration options"); common.add_options() - ("mme.enb_id", bpo::value(&enb_id)->default_value("0x0"), "eNodeB ID") - ("mme.name", bpo::value(&args->enb.s1ap.enb_name)->default_value("srsenb01"), "eNodeB Name") - ("mme.cell_id", bpo::value(&cell_id)->default_value("0x0"), "Cell ID") - ("mme.tac", bpo::value(&tac)->default_value("0x0"), "Tracking Area Code") - ("mme.mcc", bpo::value(&mcc)->default_value("001"), "Mobile Country Code") - ("mme.mnc", bpo::value(&mnc)->default_value("01"), "Mobile Network Code") - ("mme.mme_bindx_addr", bpo::value(&args->enb.s1ap.mme_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connnection") + ("mme.mme_code", bpo::value(&mme_code)->default_value("0x01"), "MME Code") + ("mme.name", bpo::value(&mme_name)->default_value("srsmme01"), "MME Name") + ("mme.mme_group", bpo::value(&mme_group)->default_value("0x01"), "Cell ID") + ("mme.tac", bpo::value(&tac)->default_value("0x0"), "Tracking Area Code") + ("mme.mcc", bpo::value(&mcc)->default_value("001"), "Mobile Country Code") + ("mme.mnc", bpo::value(&mnc)->default_value("01"), "Mobile Network Code") + ("mme.mme_bind_addr", bpo::value(&mme_bind_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connnection") ; - + + // Positional options - config file location bpo::options_description position("Positional options"); position.add_options() - ("config_file", bpo::value< string >(&config_file), "eNodeB configuration file") + ("config_file", bpo::value< string >(&config_file), "MME configuration file") ; bpo::positional_options_description p; - p.add("config_file", -1) - + p.add("config_file", -1); + + // these options are allowed on the command line + bpo::options_description cmdline_options; + cmdline_options.add(common).add(position).add(general); + + // parse the command line and store result in vm + bpo::variables_map vm; + bpo::store(bpo::command_line_parser(argc, argv).options(cmdline_options).positional(p).run(), vm); + bpo::notify(vm); + + // help option was given - print usage and exit + if (vm.count("help")) { + cout << "Usage: " << argv[0] << " [OPTIONS] config_file" << endl << endl; + cout << common << endl << general << endl; + exit(0); + } + //Concert hex strings + { + std::stringstream sstr; + sstr << std::hex << vm["mme.mme_group"].as(); + sstr >> args->s1ap_args.mme_group; + } + { + std::stringstream sstr; + sstr << std::hex << vm["mme.mme_code"].as(); + uint16_t tmp; // Need intermediate uint16_t as uint8_t is treated as char + sstr >> tmp; + args->s1ap_args.mme_code = tmp; + } + { + std::stringstream sstr; + sstr << std::hex << vm["mme.tac"].as(); + sstr >> args->s1ap_args.tac; + } + // Convert MCC/MNC strings + if(!srslte::string_to_mcc(mcc, &args->s1ap_args.mcc)) { + cout << "Error parsing enb.mcc:" << mcc << " - must be a 3-digit string." << endl; + } + if(!srslte::string_to_mnc(mnc, &args->s1ap_args.mnc)) { + cout << "Error parsing enb.mnc:" << mnc << " - must be a 2 or 3-digit string." << endl; + } + + args->s1ap_args.mme_bind_addr = mme_bind_addr; return; } -*/ + int main (int argc,char * argv[] ) { - cout << "--- Software Radio Systems EPC MME ---" << endl << endl; - + cout << "--- Software Radio Systems EPC ---" << endl << endl; signal(SIGINT, sig_int_handler); + all_args_t args; + parse_args(&args, argc, argv); + //TODO these should be passed from config files - all_args_t args; - args.s1ap_args.mme_code = 0x01; - args.s1ap_args.mme_group = 0x0001; - args.s1ap_args.tac = 0x0001; - args.s1ap_args.mcc = 0x01; - args.s1ap_args.mnc = 0x01; - args.s1ap_args.mme_bindx_addr="127.0.0.0/24"; + //args.s1ap_args.mme_code = 0x01; + //args.s1ap_args.mme_group = 0x0001; + //args.s1ap_args.tac = 0x0001; + //args.s1ap_args.mcc = 0x01; + //args.s1ap_args.mnc = 0x01; + //args.s1ap_args.mme_bindx_addr="127.0.0.0/24"; args.log_args.filename = std::string("/tmp/epc.log"); struct sockaddr_in enb_addr; diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 6199fd3e9..bbf36180e 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -54,7 +54,7 @@ s1ap::init(s1ap_args_t s1ap_args, srslte::log *s1ap_log) m_tac = s1ap_args.tac; m_mcc = s1ap_args.mcc; m_mnc = s1ap_args.mnc; - m_mme_bindx_addr = s1ap_args.mme_bindx_addr; + m_mme_bind_addr = s1ap_args.mme_bind_addr; m_mme_name = std::string("SRS MME"); m_log_h = s1ap_log; @@ -111,8 +111,9 @@ s1ap::enb_listen() //S1-MME bind bzero(&s1mme_addr, sizeof(s1mme_addr)); - s1mme_addr.sin_family = AF_INET; - s1mme_addr.sin_addr.s_addr = htonl(INADDR_ANY); //TODO this should use the bindx information + s1mme_addr.sin_family = AF_INET; + inet_pton(AF_INET, m_mme_bind_addr.c_str(), &(s1mme_addr.sin_addr) ); + //s1mme_addr.sin_addr.s_addr = htonl(INADDR_ANY); //TODO this should use the bindx information s1mme_addr.sin_port = htons(S1MME_PORT); err = bind(sock_fd, (struct sockaddr*) &s1mme_addr, sizeof (s1mme_addr)); if (err != 0){