diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index 200319023..d75ab4329 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -37,10 +37,10 @@ using srslte::byte_buffer_t; namespace srsue { -class nas : public nas_interface_rrc, public nas_interface_ue +class nas : public nas_interface_rrc, public nas_interface_ue, public srslte::timer_callback { public: - nas(srslte::log* log_); + nas(srslte::log* log_, srslte::timers* timers_); void init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_, const nas_args_t& args_); void stop(); void run_tti(uint32_t tti) final; @@ -69,6 +69,9 @@ public: srslte::unique_byte_buffer_t ded_info_nas); bool connection_request_completed(bool outcome) final; + // timer callback + void timer_expired(uint32_t timeout_id); + // PCAP void start_pcap(srslte::nas_pcap *pcap_); @@ -129,6 +132,14 @@ private: uint8_t transaction_id = 0; + // timers + srslte::timers* timers = nullptr; + uint32_t t3410 = 0; // started when attach request is sent, on expiry, start t3411 + uint32_t t3411 = 0; // started when attach failed + + const uint32_t t3410_duration_ms = 15 * 1000; // 15s according to TS 24.301 Sec 10.2 + const uint32_t t3411_duration_ms = 10 * 1000; // 10s according to TS 24.301 Sec 10.2 + // Security bool eia_caps[8] = {}; bool eea_caps[8] = {}; diff --git a/srsue/src/stack/ue_stack_lte.cc b/srsue/src/stack/ue_stack_lte.cc index 984be81e2..8a157296e 100644 --- a/srsue/src/stack/ue_stack_lte.cc +++ b/srsue/src/stack/ue_stack_lte.cc @@ -37,7 +37,7 @@ ue_stack_lte::ue_stack_lte() : mac(&mac_log), rrc(&rrc_log), pdcp(&pdcp_log), - nas(&nas_log), + nas(&nas_log, &timers), thread("STACK"), pending_tasks(1024), background_tasks(2) diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index 07471c691..a8457c1f2 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -208,7 +208,12 @@ proc_outcome_t nas::rrc_connect_proc::step() * NAS ********************************************************************/ -nas::nas(srslte::log* log_) : nas_log(log_), pool(byte_buffer_pool::get_instance()) {} +nas::nas(srslte::log* log_, srslte::timers* timers_) : + nas_log(log_), + pool(byte_buffer_pool::get_instance()), + timers(timers_) +{ +} void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_nas* gw_, const nas_args_t& cfg_) { @@ -259,6 +264,12 @@ void nas::init(usim_interface_nas* usim_, rrc_interface_nas* rrc_, gw_interface_ have_ctxt = true; } + // Configure T3410 and T3411 + t3410 = timers->get_unique_id(); + timers->get(t3410)->set(this, t3410_duration_ms); + t3411 = timers->get_unique_id(); + timers->get(t3411)->set(this, t3411_duration_ms); + running = true; } @@ -286,6 +297,20 @@ void nas::run_tti(uint32_t tti) callbacks.run(); } +void nas::timer_expired(uint32_t timeout_id) +{ + if (timeout_id == t3410) { + nas_log->info("Timer T3410 expired: starting T3411\n"); + timers->get(t3411)->reset(); + timers->get(t3411)->run(); + } else if (timeout_id == t3411) { + nas_log->info("Timer T3411 expired: trying to attach again\n"); + start_attach_request(nullptr); + } else { + nas_log->error("Timeout from unknown timer id %d\n", timeout_id); + } +} + /******************************************************************************* * UE interface ******************************************************************************/ @@ -299,6 +324,19 @@ void nas::start_attach_request(srslte::proc_state_t* result) nas_log->info("Attach Request\n"); switch (state) { case EMM_STATE_DEREGISTERED: + + // start T3410 + nas_log->debug("Starting T3410\n"); + timers->get(t3410)->reset(); + timers->get(t3410)->run(); + + // stop T3411 + if (timers->get(t3411)->is_running()) { + timers->get(t3411)->stop(); + } + + // Todo: stop T3402 + // Search PLMN is not selected if (!plmn_is_selected) { nas_log->info("No PLMN selected. Starting PLMN Search...\n"); @@ -317,6 +355,11 @@ void nas::start_attach_request(srslte::proc_state_t* result) if (result != nullptr) { *result = p.is_success() ? proc_state_t::success : proc_state_t::error; } + // start T3411 + nas_log->debug("Starting T3411\n"); + timers->get(t3411)->reset(); + timers->get(t3411)->run(); + if (not p.is_success()) { enter_emm_deregistered(); } @@ -844,6 +887,11 @@ void nas::parse_attach_accept(uint32_t lcid, unique_byte_buffer_t pdu) nas_log->info("Received Attach Accept\n"); + // stop T3410 + if (timers->get(t3410)->is_running()) { + timers->get(t3410)->stop(); + } + LIBLTE_MME_ATTACH_ACCEPT_MSG_STRUCT attach_accept = {}; liblte_mme_unpack_attach_accept_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &attach_accept); @@ -1066,6 +1114,12 @@ void nas::parse_attach_reject(uint32_t lcid, unique_byte_buffer_t pdu) liblte_mme_unpack_attach_reject_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &attach_rej); nas_log->warning("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause); nas_log->console("Received Attach Reject. Cause= %02X\n", attach_rej.emm_cause); + + // stop T3410 + if (timers->get(t3410)->is_running()) { + timers->get(t3410)->stop(); + } + enter_emm_deregistered(); // FIXME: Command RRC to release? } @@ -1560,6 +1614,12 @@ void nas::gen_attach_request(byte_buffer_t* msg) set_k_enb_count(ctxt.tx_count); ctxt.tx_count++; } + + // stop T3411 + if (timers->get(t3411)->is_running()) { + nas_log->debug("Stopping T3411\n"); + timers->get(t3411)->stop(); + } } void nas::gen_service_request(byte_buffer_t* msg)