diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index f8fa61913..ac949a4df 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -40,7 +40,7 @@ namespace srsue { class nas : public nas_interface_rrc, public nas_interface_ue, public srslte::timer_callback { public: - nas(srslte::timer_handler* timers_); + nas(srsue::task_handler_interface_lte* task_handler_); void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_, const nas_args_t& args_); void stop(); void run_tti(); @@ -129,7 +129,7 @@ private: uint8_t transaction_id = 0; // timers - srslte::timer_handler* timers = nullptr; + srsue::task_handler_interface_lte* task_handler = nullptr; 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 srslte::timer_handler::unique_timer t3421; // started when detach request is sent @@ -269,18 +269,24 @@ private: struct connection_request_completed_t { bool outcome; }; + struct attach_timeout { + }; - explicit rrc_connect_proc(nas* nas_ptr_) : nas_ptr(nas_ptr_) {} + explicit rrc_connect_proc(nas* nas_ptr_); srslte::proc_outcome_t init(srslte::establishment_cause_t cause_, srslte::unique_byte_buffer_t pdu); srslte::proc_outcome_t step(); void then(const srslte::proc_state_t& result); srslte::proc_outcome_t react(connection_request_completed_t event); + srslte::proc_outcome_t react(attach_timeout event); static const char* name() { return "RRC Connect"; } private: - nas* nas_ptr; + static const uint32_t attach_timeout_ms = 5000; + + nas* nas_ptr; + srslte::timer_handler::unique_timer timeout_timer; + enum class state_t { conn_req, wait_attach } state; - uint32_t wait_timeout; }; class plmn_search_proc { diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index de4ffd3bb..81f7d91ad 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -133,6 +133,13 @@ proc_outcome_t nas::plmn_search_proc::react(const plmn_search_complete_t& t) return proc_outcome_t::yield; } +nas::rrc_connect_proc::rrc_connect_proc(nas* nas_ptr_) : nas_ptr(nas_ptr_) +{ + timeout_timer = nas_ptr->task_handler->get_unique_timer(); + timeout_timer.set(attach_timeout_ms, + [this](uint32_t tid) { nas_ptr->rrc_connector.trigger(nas::rrc_connect_proc::attach_timeout{}); }); +} + proc_outcome_t nas::rrc_connect_proc::init(srslte::establishment_cause_t cause_, srslte::unique_byte_buffer_t pdu) { if (nas_ptr->rrc->is_connected()) { @@ -177,28 +184,36 @@ proc_outcome_t nas::rrc_connect_proc::step() if (state != state_t::wait_attach) { return proc_outcome_t::yield; } - wait_timeout++; // Wait until attachment. If doing a service request is already attached - if (wait_timeout < 5000 and nas_ptr->state != EMM_STATE_REGISTERED and nas_ptr->running and - nas_ptr->rrc->is_connected()) { - return proc_outcome_t::yield; - } - if (nas_ptr->state == EMM_STATE_REGISTERED) { + if (not nas_ptr->running) { + ProcError("NAS stopped running\n"); + return proc_outcome_t::error; + } else if (not nas_ptr->rrc->is_connected()) { + ProcError("Was disconnected while attaching\n"); + return proc_outcome_t::error; + } else if (nas_ptr->state == EMM_STATE_REGISTERED) { ProcInfo("Success: EMM Registered correctly.\n"); return proc_outcome_t::success; - } else if (nas_ptr->state == EMM_STATE_DEREGISTERED) { + } + // still expecting attach finish + return proc_outcome_t::yield; +} + +srslte::proc_outcome_t nas::rrc_connect_proc::react(attach_timeout event) +{ + if (state != state_t::wait_attach) { + return proc_outcome_t::yield; + } + if (nas_ptr->state == EMM_STATE_DEREGISTERED) { ProcError("Timeout or received attach reject while trying to attach\n"); nas_ptr->nas_log->console("Failed to Attach\n"); - } else if (!nas_ptr->rrc->is_connected()) { - ProcError("Was disconnected while attaching\n"); - } else { - ProcError("Timed out while trying to attach\n"); } return proc_outcome_t::error; } void nas::rrc_connect_proc::then(const srslte::proc_state_t& result) { + timeout_timer.stop(); nas_ptr->plmn_searcher.trigger(result); } @@ -206,11 +221,10 @@ proc_outcome_t nas::rrc_connect_proc::react(nas::rrc_connect_proc::connection_re { if (state == state_t::conn_req and event.outcome) { ProcInfo("Connection established correctly. Waiting for Attach\n"); - wait_timeout = 0; // Wait until attachment. If doing a service request is already attached state = state_t::wait_attach; - // wake up proc - return step(); + timeout_timer.run(); + return proc_outcome_t::yield; } else { ProcError("Could not establish RRC connection\n"); return proc_outcome_t::error; @@ -221,15 +235,15 @@ proc_outcome_t nas::rrc_connect_proc::react(nas::rrc_connect_proc::connection_re * NAS ********************************************************************/ -nas::nas(srslte::timer_handler* timers_) : +nas::nas(srsue::task_handler_interface_lte* task_handler_) : pool(byte_buffer_pool::get_instance()), plmn_searcher(this), rrc_connector(this), - timers(timers_), - t3410(timers_->get_unique_timer()), - t3411(timers_->get_unique_timer()), - t3421(timers_->get_unique_timer()), - reattach_timer(timers_->get_unique_timer()) + task_handler(task_handler_), + t3410(task_handler_->get_unique_timer()), + t3411(task_handler_->get_unique_timer()), + t3421(task_handler_->get_unique_timer()), + reattach_timer(task_handler_->get_unique_timer()) { } @@ -1850,13 +1864,13 @@ void nas::send_detach_request(bool switch_off) ctxt.tx_count++; } -void nas::send_attach_complete(const uint8_t& transaction_id, const uint8_t& eps_bearer_id) +void nas::send_attach_complete(const uint8_t& transaction_id_, const uint8_t& eps_bearer_id) { // Send EPS bearer context accept and attach complete LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_complete = {}; LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT act_def_eps_bearer_context_accept = {}; act_def_eps_bearer_context_accept.eps_bearer_id = eps_bearer_id; - act_def_eps_bearer_context_accept.proc_transaction_id = transaction_id; + act_def_eps_bearer_context_accept.proc_transaction_id = transaction_id_; act_def_eps_bearer_context_accept.protocol_cnfg_opts_present = false; liblte_mme_pack_activate_default_eps_bearer_context_accept_msg(&act_def_eps_bearer_context_accept, &attach_complete.esm_msg); diff --git a/srsue/test/common/dummy_classes.h b/srsue/test/common/dummy_classes.h index 4da6390c0..3455011da 100644 --- a/srsue/test/common/dummy_classes.h +++ b/srsue/test/common/dummy_classes.h @@ -31,7 +31,7 @@ class stack_dummy : public task_handler_interface_lte public: srslte::timer_handler::unique_timer get_unique_timer() override { return timers.get_unique_timer(); } - srslte::timer_handler timers; + srslte::timer_handler timers{100}; }; } // namespace srsue diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index e302c50aa..b428a9727 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -32,6 +32,7 @@ #include "srsue/hdr/stack/upper/nas.h" #include "srsue/hdr/stack/upper/usim.h" #include "srsue/hdr/stack/upper/usim_base.h" +#include "srsue/test/common/dummy_classes.h" #include #include @@ -140,11 +141,15 @@ private: bool is_connected_flag = false; }; -class stack_dummy : public stack_interface_gw, public thread +class test_stack_dummy : public srsue::stack_dummy, public stack_interface_gw, public thread { public: - stack_dummy(pdcp_interface_gw* pdcp_, srsue::nas* nas_) : pdcp(pdcp_), nas(nas_), thread("DUMMY STACK") {} - void init() { start(-1); } + test_stack_dummy(pdcp_interface_gw* pdcp_) : pdcp(pdcp_), thread("DUMMY STACK") {} + void init(srsue::nas* nas_) + { + nas = nas_; + start(-1); + } bool switch_on() final { proc_state_t proc_result; @@ -163,6 +168,7 @@ public: { running = true; while (running) { + timers.step_all(); nas->run_tti(); } } @@ -204,7 +210,7 @@ int security_command_test() rrc_log.set_level(srslte::LOG_LEVEL_DEBUG); rrc_log.set_hex_limit(100000); - srslte::timer_handler timers(10); + stack_dummy stack; rrc_dummy rrc_dummy; gw_dummy gw; @@ -222,7 +228,7 @@ int security_command_test() usim.init(&args); { - srsue::nas nas(&timers); + srsue::nas nas(&stack); nas_args_t cfg; cfg.eia = "1,2,3"; cfg.eea = "0,1,2,3"; @@ -271,8 +277,6 @@ int mme_attach_request_test() usim_log.set_hex_limit(100000); gw_log.set_hex_limit(100000); - srslte::timer_handler timers(10); - rrc_dummy rrc_dummy; pdcp_dummy pdcp_dummy; @@ -290,9 +294,9 @@ int mme_attach_request_test() nas_args_t nas_cfg; nas_cfg.force_imsi_attach = true; nas_cfg.apn_name = "test123"; - srsue::nas nas(&timers); - srsue::gw gw; - stack_dummy stack(&pdcp_dummy, &nas); + test_stack_dummy stack(&pdcp_dummy); + srsue::nas nas(&stack); + srsue::gw gw; nas.init(&usim, &rrc_dummy, &gw, nas_cfg); rrc_dummy.init(&nas); @@ -304,8 +308,8 @@ int mme_attach_request_test() srslte::logger_stdout def_logstdout; srslte::logger* logger = &def_logstdout; gw.init(gw_args, logger, &stack); + stack.init(&nas); - stack.init(); // trigger test stack.switch_on(); stack.stop(); @@ -348,7 +352,7 @@ int esm_info_request_test() rrc_log.set_level(srslte::LOG_LEVEL_DEBUG); rrc_log.set_hex_limit(100000); - srslte::timer_handler timers(10); + srsue::stack_dummy stack{}; rrc_dummy rrc_dummy; gw_dummy gw; @@ -368,7 +372,7 @@ int esm_info_request_test() pool = byte_buffer_pool::get_instance(); { - srsue::nas nas(&timers); + srsue::nas nas(&stack); nas_args_t cfg; cfg.apn_name = "srslte"; cfg.apn_user = "srsuser"; @@ -402,7 +406,7 @@ int dedicated_eps_bearer_test() rrc_log.set_level(srslte::LOG_LEVEL_DEBUG); rrc_log.set_hex_limit(100000); - srslte::timer_handler timers(10); + srsue::stack_dummy stack; rrc_dummy rrc_dummy; gw_dummy gw; @@ -420,7 +424,7 @@ int dedicated_eps_bearer_test() srslte::byte_buffer_pool* pool = byte_buffer_pool::get_instance(); - srsue::nas nas(&timers); + srsue::nas nas(&stack); nas_args_t cfg = {}; cfg.force_imsi_attach = true; // make sure we get a fresh security context nas.init(&usim, &rrc_dummy, &gw, cfg);