From 9c74dda039404994d4dcca78fcdb101681196259 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Tue, 26 Oct 2021 16:44:53 +0200 Subject: [PATCH] rrc,nr: add msg5 and inactivity timers to RRC-NR Signed-off-by: Carlo Galiotto --- .../srsran/interfaces/enb_x2_interfaces.h | 7 +++++ srsenb/hdr/stack/enb_stack_lte.h | 4 +++ srsenb/hdr/stack/rrc/rrc.h | 1 + srsenb/hdr/x2_adapter.h | 7 +++++ srsenb/src/stack/rrc/rrc.cc | 11 +++++++ srsenb/src/stack/rrc/rrc_nr.cc | 29 ++++++++++++------- 6 files changed, 48 insertions(+), 11 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_x2_interfaces.h b/lib/include/srsran/interfaces/enb_x2_interfaces.h index e8d5b133c..9c28f0840 100644 --- a/lib/include/srsran/interfaces/enb_x2_interfaces.h +++ b/lib/include/srsran/interfaces/enb_x2_interfaces.h @@ -85,6 +85,13 @@ public: */ virtual void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) = 0; + /** + * @brief Signal timeout for inactivity or MSG5 timers + * + * @param eutra_rnti The RNTI that the EUTRA RRC used to request the SgNB addition + */ + virtual void sgnb_inactivity_timeout(uint16_t eutra_rnti) = 0; + /** * @brief Signal release of all UE resources on the NR cell * diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index 0a21eeab3..1f3cb8e34 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -121,6 +121,10 @@ public: { x2_task_queue.push([this, eutra_rnti, nr_rnti]() { rrc.sgnb_addition_complete(eutra_rnti, nr_rnti); }); } + void sgnb_inactivity_timeout(uint16_t eutra_rnti) final + { + x2_task_queue.push([this, eutra_rnti]() { rrc.sgnb_inactivity_timeout(eutra_rnti); }); + } void set_activity_user(uint16_t eutra_rnti) final { // Note: RRC processes activity asynchronously, so there is no need to use x2_task_queue diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index 5a1c2adb3..7d85275ab 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -131,6 +131,7 @@ public: void sgnb_addition_ack(uint16_t eutra_rnti, const sgnb_addition_ack_params_t params) override; void sgnb_addition_reject(uint16_t eutra_rnti) override; void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) override; + void sgnb_inactivity_timeout(uint16_t eutra_rnti) override; void sgnb_release_ack(uint16_t eutra_rnti) override; // rrc_interface_pdcp diff --git a/srsenb/hdr/x2_adapter.h b/srsenb/hdr/x2_adapter.h index c603e89fa..ee6eb10c7 100644 --- a/srsenb/hdr/x2_adapter.h +++ b/srsenb/hdr/x2_adapter.h @@ -83,6 +83,13 @@ public: } eutra_stack->sgnb_addition_complete(eutra_rnti, nr_rnti); } + void sgnb_inactivity_timeout(uint16_t eutra_rnti) override + { + if (eutra_stack == nullptr) { + return; + } + eutra_stack->sgnb_inactivity_timeout(eutra_rnti); + } void sgnb_release_ack(uint16_t eutra_rnti) override { diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 277f3c2f1..3cd1dfabb 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -603,6 +603,17 @@ void rrc::sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) ue_it->second->endc_handler->trigger(ue::rrc_endc::sgnb_add_complete_ev{nr_rnti}); } +void rrc::sgnb_inactivity_timeout(uint16_t eutra_rnti) +{ + logger.error("Received NR inactivity timeout for rnti=%d - releasing UE", eutra_rnti); + auto ue_it = users.find(eutra_rnti); + if (ue_it == users.end()) { + logger.warning("rnti=0x%x does not exist", eutra_rnti); + return; + } + release_ue(eutra_rnti); +} + void rrc::sgnb_release_ack(uint16_t eutra_rnti) { auto ue_it = users.find(eutra_rnti); diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index f865205e8..9b63296cf 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -245,6 +245,8 @@ void rrc_nr::set_activity_user(uint16_t rnti) // inform EUTRA RRC about user activity if (ue_ptr->is_endc()) { + // Restart inactivity timer for RRC-NR + ue_ptr->set_activity(); // inform EUTRA RRC about user activity rrc_eutra->set_activity_user(ue_ptr->get_eutra_rnti()); } @@ -567,7 +569,7 @@ rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg_, // Set timer for MSG3_RX_TIMEOUT or UE_INACTIVITY_TIMEOUT activity_timer = parent->task_sched.get_unique_timer(); - start_msg3_timer ? set_activity_timeout(MSG3_RX_TIMEOUT) : set_activity_timeout(UE_INACTIVITY_TIMEOUT); + start_msg3_timer ? set_activity_timeout(MSG3_RX_TIMEOUT) : set_activity_timeout(MSG5_RX_TIMEOUT); } void rrc_nr::ue::set_activity_timeout(activity_timeout_type_t type) @@ -579,15 +581,19 @@ void rrc_nr::ue::set_activity_timeout(activity_timeout_type_t type) // TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 100ms deadline_ms = 100; break; + case MSG5_RX_TIMEOUT: + // TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 1s + deadline_ms = 1000; + break; case UE_INACTIVITY_TIMEOUT: - // TODO: Add a value for the inactivity timeout - currently no activity set this case - return; + // TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 5s + deadline_ms = 5000; + break; default: parent->logger.error("Unknown timeout type %d", type); return; } - // Currently we only set the timer for the MSG3_RX_TIMEOUT case activity_timer.set(deadline_ms, [this, type](uint32_t tid) { activity_timer_expired(type); }); parent->logger.debug("Setting timer for %s for rnti=0x%x to %dms", to_string(type).c_str(), rnti, deadline_ms); @@ -613,14 +619,15 @@ void rrc_nr::ue::activity_timer_expired(const activity_timeout_type_t type) { parent->logger.info("Activity timer for rnti=0x%x expired after %d ms", rnti, activity_timer.time_elapsed()); - state = rrc_nr_state_t::RRC_IDLE; - switch (type) { + case MSG5_RX_TIMEOUT: case UE_INACTIVITY_TIMEOUT: - // TODO: Add action to be executed + state = rrc_nr_state_t::RRC_INACTIVE; + parent->rrc_eutra->sgnb_inactivity_timeout(eutra_rnti); break; case MSG3_RX_TIMEOUT: { // MSG3 timeout, no need to notify NGAP or LTE stack. Just remove UE + state = rrc_nr_state_t::RRC_IDLE; uint32_t rnti_to_rem = rnti; parent->task_sched.defer_task([this, rnti_to_rem]() { parent->rem_user(rnti_to_rem); }); break; @@ -635,7 +642,7 @@ void rrc_nr::ue::activity_timer_expired(const activity_timeout_type_t type) std::string rrc_nr::ue::to_string(const activity_timeout_type_t& type) { - constexpr static const char* options[] = {"Msg3 reception", "UE inactivity", "UE reestablishment"}; + constexpr static const char* options[] = {"Msg3 reception", "UE inactivity", "Msg5 reception"}; return srsran::enum_to_text(options, (uint32_t)activity_timeout_type_t::nulltype, (uint32_t)type); } @@ -1310,9 +1317,9 @@ void rrc_nr::ue::crnti_ce_received() // send SgNB addition complete for ENDC users parent->rrc_eutra->sgnb_addition_complete(eutra_rnti, rnti); - // stop RX MSG3 activity timer on MAC CE RNTI reception - activity_timer.stop(); - parent->logger.debug("Received MAC CE-RNTI for 0x%x - stopping MSG3 timer", rnti); + // stop RX MSG3/MSG5 activity timer on MAC CE RNTI reception + set_activity_timeout(UE_INACTIVITY_TIMEOUT); + parent->logger.debug("Received MAC CE-RNTI for 0x%x - stopping MSG3/MSG5 timer, starting inactivity timer", rnti); // Add DRB1 to MAC for (auto& drb : cell_group_cfg.rlc_bearer_to_add_mod_list) {