From 2b1ded220e59d5ed7d533074f08847557663d6ed Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Mon, 9 Nov 2020 05:20:02 +0700 Subject: [PATCH] srsue/extnas: derive abstract 'nas_base' class from 'nas' This is the first step towards the goal of having an external NAS interface. The new 'nas_base' class becomes a parent of 'nas', combining all interfaces and the basic (common) API. The 'ue_stack_lte' now holds a unique_ptr of type 'srsue::nas_base', so the underlying NAS implementation (built-in or external) can be choosen at run-time depending on configuration. The implementation specific configuration now needs to be passed to the constructor instead, not to the init() method as was before. --- srsue/hdr/stack/ue_stack_lte.h | 4 ++- srsue/hdr/stack/upper/nas.h | 51 ++++++++++++++++++++----------- srsue/src/stack/ue_stack_lte.cc | 25 +++++++++------ srsue/src/stack/upper/nas.cc | 25 ++++++++------- srsue/test/upper/nas_test.cc | 16 +++++----- srsue/test/upper/rrc_meas_test.cc | 2 +- 6 files changed, 75 insertions(+), 48 deletions(-) diff --git a/srsue/hdr/stack/ue_stack_lte.h b/srsue/hdr/stack/ue_stack_lte.h index dd1b77722..4bacaa71f 100644 --- a/srsue/hdr/stack/ue_stack_lte.h +++ b/srsue/hdr/stack/ue_stack_lte.h @@ -174,8 +174,10 @@ private: srslte::rlc rlc; srslte::pdcp pdcp; srsue::rrc rrc; - srsue::nas nas; std::unique_ptr usim; + + // NAS implementation (built-in or external) + std::unique_ptr nas; }; } // namespace srsue diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index deafbca5a..40fb15aff 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -38,15 +38,43 @@ using srslte::byte_buffer_t; namespace srsue { -class nas : public nas_interface_rrc, public nas_interface_ue, public srslte::timer_callback +class nas_base : public nas_interface_rrc, public nas_interface_ue, public srslte::timer_callback { public: - explicit nas(srslte::task_sched_handle task_sched_); - virtual ~nas() = default; - void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_, const nas_args_t& args_); - void stop(); + explicit nas_base(srslte::task_sched_handle task_sched_, const char *log_name_); + virtual ~nas_base() = default; + + virtual void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_) = 0; + virtual void get_metrics(nas_metrics_t* m) = 0; + virtual void stop() = 0; + + void start_pcap(srslte::nas_pcap* pcap_); void run_tti(); +protected: + srslte::byte_buffer_pool* pool = nullptr; + rrc_interface_nas* rrc = nullptr; + usim_interface_nas* usim = nullptr; + gw_interface_nas* gw = nullptr; + + // Task handler + srslte::task_sched_handle task_sched; + srslte::proc_manager_list_t callbacks; + + // Logging reference + srslte::log_ref nas_log; + + // PCAP + srslte::nas_pcap* pcap = nullptr; +}; + +class nas : public nas_base +{ +public: + nas(srslte::task_sched_handle task_sched_, const nas_args_t& cfg_); + void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_); + void stop(); + void get_metrics(nas_metrics_t* m); emm_state_t get_state(); @@ -72,17 +100,8 @@ public: // timer callback void timer_expired(uint32_t timeout_id) override; - // PCAP - void start_pcap(srslte::nas_pcap* pcap_); - private: - srslte::byte_buffer_pool* pool = nullptr; - srslte::log_ref nas_log; - rrc_interface_nas* rrc = nullptr; - usim_interface_nas* usim = nullptr; - gw_interface_nas* gw = nullptr; - - nas_args_t cfg = {}; + nas_args_t cfg = { }; emm_state_t state = EMM_STATE_DEREGISTERED; @@ -135,7 +154,6 @@ private: uint8_t transaction_id = 0; // timers - srslte::task_sched_handle task_sched; srslte::timer_handler::unique_timer t3402; // started when attach attempt counter reached 5 srslte::timer_handler::unique_timer t3410; // started when attach request is sent, on expiry, start t3411 srslte::timer_handler::unique_timer t3411; // started when attach failed @@ -317,7 +335,6 @@ private: nas* nas_ptr; enum class state_t { plmn_search, rrc_connect } state = state_t::plmn_search; }; - srslte::proc_manager_list_t callbacks; srslte::proc_t plmn_searcher; srslte::proc_t rrc_connector; diff --git a/srsue/src/stack/ue_stack_lte.cc b/srsue/src/stack/ue_stack_lte.cc index 25dbe1ae6..d53f473ad 100644 --- a/srsue/src/stack/ue_stack_lte.cc +++ b/srsue/src/stack/ue_stack_lte.cc @@ -37,11 +37,11 @@ ue_stack_lte::ue_stack_lte() : logger(nullptr), usim(nullptr), phy(nullptr), + nas(nullptr), rlc("RLC"), mac("MAC", &task_sched), rrc(this, &task_sched), pdcp(&task_sched, "PDCP"), - nas(&task_sched), thread("STACK"), task_sched(512, 2, 64), tti_tprof("tti_tprof", "STCK", TTI_STAT_PERIOD) @@ -103,6 +103,11 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_) nas_log->set_level(args.log.nas_level); nas_log->set_hex_limit(args.log.nas_hex_limit); + // Should we use the built-in NAS implementation + // TODO: or provide an external interface (RRCTL)? + std::unique_ptr nas_impl(new srsue::nas(&task_sched, args.nas)); + nas = std::move(nas_impl); + // Set up pcap if (args.pcap.enable) { mac_pcap.open(args.pcap.filename.c_str()); @@ -110,7 +115,7 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_) } if (args.pcap.nas_enable) { nas_pcap.open(args.pcap.nas_filename.c_str()); - nas.start_pcap(&nas_pcap); + nas->start_pcap(&nas_pcap); } // Init USIM first to allow early exit in case reader couldn't be found @@ -126,8 +131,8 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_) mac.init(phy, &rlc, &rrc); rlc.init(&pdcp, &rrc, task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */); pdcp.init(&rlc, &rrc, gw); - nas.init(usim.get(), &rrc, gw, args.nas); - rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, args.rrc); + nas->init(usim.get(), &rrc, gw); + rrc.init(phy, &mac, &rlc, &pdcp, nas.get(), usim.get(), gw, args.rrc); running = true; start(STACK_MAIN_THREAD_PRIO); @@ -148,7 +153,7 @@ void ue_stack_lte::stop_impl() running = false; usim->stop(); - nas.stop(); + nas->stop(); rrc.stop(); rlc.stop(); @@ -166,7 +171,7 @@ void ue_stack_lte::stop_impl() bool ue_stack_lte::switch_on() { if (running) { - ue_task_queue.try_push([this]() { nas.start_attach_proc(nullptr, srslte::establishment_cause_t::mo_sig); }); + ue_task_queue.try_push([this]() { nas->start_attach_proc(nullptr, srslte::establishment_cause_t::mo_sig); }); return true; } return false; @@ -175,7 +180,7 @@ bool ue_stack_lte::switch_on() bool ue_stack_lte::switch_off() { // generate detach request with switch-off flag - nas.detach_request(true); + nas->detach_request(true); // wait for max. 5s for it to be sent (according to TS 24.301 Sec 25.5.2.2) int cnt = 0, timeout_ms = 5000; @@ -202,7 +207,7 @@ bool ue_stack_lte::disable_data() { // generate detach request srslte::console("Turning on airplane mode.\n"); - return nas.detach_request(false); + return nas->detach_request(false); } bool ue_stack_lte::get_metrics(stack_metrics_t* metrics) @@ -212,7 +217,7 @@ bool ue_stack_lte::get_metrics(stack_metrics_t* metrics) stack_metrics_t metrics{}; mac.get_metrics(metrics.mac); rlc.get_metrics(metrics.rlc); - nas.get_metrics(&metrics.nas); + nas->get_metrics(&metrics.nas); rrc.get_metrics(metrics.rrc); pending_stack_metrics.push(metrics); }); @@ -313,7 +318,7 @@ void ue_stack_lte::run_tti_impl(uint32_t tti, uint32_t tti_jump) task_sched.tic(); } rrc.run_tti(); - nas.run_tti(); + nas->run_tti(); if (args.have_tti_time_stats) { std::chrono::nanoseconds dur = tti_tprof.stop(); diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index 5b8c950da..e55909657 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -235,20 +235,25 @@ proc_outcome_t nas::rrc_connect_proc::react(nas::rrc_connect_proc::connection_re * NAS ********************************************************************/ -nas::nas(srslte::task_sched_handle task_sched_) : +nas_base::nas_base(srslte::task_sched_handle task_sched_, const char *log_name_) : pool(byte_buffer_pool::get_instance()), + task_sched(task_sched_), + nas_log{log_name_} +{} + +nas::nas(srslte::task_sched_handle task_sched_, const nas_args_t& cfg_) : + nas_base::nas_base(task_sched_, "NAS"), + cfg(cfg_), plmn_searcher(this), rrc_connector(this), - task_sched(task_sched_), t3402(task_sched_.get_unique_timer()), t3410(task_sched_.get_unique_timer()), t3411(task_sched_.get_unique_timer()), t3421(task_sched_.get_unique_timer()), - reattach_timer(task_sched_.get_unique_timer()), - nas_log{"NAS"} + reattach_timer(task_sched_.get_unique_timer()) {} -void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_, const nas_args_t& cfg_) +void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_) { usim = usim_; rrc = rrc_; @@ -262,7 +267,7 @@ void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_ // parse and sanity check EIA list std::vector cap_list; - srslte::string_parse_list(cfg_.eia, ',', cap_list); + srslte::string_parse_list(cfg.eia, ',', cap_list); if (cap_list.empty()) { nas_log->error("Empty EIA list. Select at least one EIA algorithm.\n"); } @@ -275,7 +280,7 @@ void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_ } // parse and sanity check EEA list - srslte::string_parse_list(cfg_.eea, ',', cap_list); + srslte::string_parse_list(cfg.eea, ',', cap_list); if (cap_list.empty()) { nas_log->error("Empty EEA list. Select at least one EEA algorithm.\n"); } @@ -287,8 +292,6 @@ void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_ } } - cfg = cfg_; - if ((read_ctxt_file(&ctxt))) { usim->generate_nas_keys(ctxt.k_asme, k_nas_enc, k_nas_int, ctxt.cipher_algo, ctxt.integ_algo); nas_log->debug_hex(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); @@ -326,7 +329,7 @@ emm_state_t nas::get_state() return state; } -void nas::run_tti() +void nas_base::run_tti() { callbacks.run(); } @@ -756,7 +759,7 @@ bool nas::get_ipv6_addr(uint8_t* ipv6_addr) PCAP *******************************************************************************/ -void nas::start_pcap(srslte::nas_pcap* pcap_) +void nas_base::start_pcap(srslte::nas_pcap* pcap_) { pcap = pcap_; } diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 1fa33d54d..76d606468 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -231,11 +231,11 @@ int security_command_test() usim.init(&args); { - srsue::nas nas(&stack.task_sched); nas_args_t cfg; cfg.eia = "1,2,3"; cfg.eea = "0,1,2,3"; - nas.init(&usim, &rrc_dummy, &gw, cfg); + srsue::nas nas(&stack.task_sched, cfg); + nas.init(&usim, &rrc_dummy, &gw); rrc_dummy.init(&nas); // push auth request PDU to NAS to generate security context @@ -299,10 +299,10 @@ int mme_attach_request_test() nas_cfg.apn_name = "test123"; test_stack_dummy stack(&pdcp_dummy); - srsue::nas nas(&stack.task_sched); + srsue::nas nas(&stack.task_sched, nas_cfg); srsue::gw gw; - nas.init(&usim, &rrc_dummy, &gw, nas_cfg); + nas.init(&usim, &rrc_dummy, &gw); rrc_dummy.init(&nas); gw_args_t gw_args; @@ -377,13 +377,13 @@ int esm_info_request_test() pool = byte_buffer_pool::get_instance(); { - srsue::nas nas(&stack.task_sched); nas_args_t cfg; cfg.apn_name = "srslte"; cfg.apn_user = "srsuser"; cfg.apn_pass = "srspass"; cfg.force_imsi_attach = true; - nas.init(&usim, &rrc_dummy, &gw, cfg); + srsue::nas nas(&stack.task_sched, cfg); + nas.init(&usim, &rrc_dummy, &gw); // push ESM info request PDU to NAS to generate response unique_byte_buffer_t tmp = srslte::allocate_unique_buffer(*pool, true); @@ -427,10 +427,10 @@ int dedicated_eps_bearer_test() srslte::byte_buffer_pool* pool = byte_buffer_pool::get_instance(); - srsue::nas nas(&stack.task_sched); nas_args_t cfg = {}; cfg.force_imsi_attach = true; // make sure we get a fresh security context - nas.init(&usim, &rrc_dummy, &gw, cfg); + srsue::nas nas(&stack.task_sched, cfg); + nas.init(&usim, &rrc_dummy, &gw); // push dedicated EPS bearer PDU to NAS unique_byte_buffer_t tmp = srslte::allocate_unique_buffer(*pool, true); diff --git a/srsue/test/upper/rrc_meas_test.cc b/srsue/test/upper/rrc_meas_test.cc index 8277b7200..f21e0368d 100644 --- a/srsue/test/upper/rrc_meas_test.cc +++ b/srsue/test/upper/rrc_meas_test.cc @@ -173,7 +173,7 @@ public: class nas_test : public srsue::nas { public: - nas_test(srslte::task_sched_handle t) : srsue::nas(t) {} + nas_test(srslte::task_sched_handle t) : srsue::nas(t, {}) {} bool is_attached() override { return false; } };