mirror of https://github.com/PentHertz/srsLTE.git
rrc,nr: add msg5 and inactivity timers to RRC-NR
Signed-off-by: Carlo Galiotto <carlo@srs.io>
This commit is contained in:
parent
0cfcd612b0
commit
9c74dda039
|
@ -85,6 +85,13 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) = 0;
|
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
|
* @brief Signal release of all UE resources on the NR cell
|
||||||
*
|
*
|
||||||
|
|
|
@ -121,6 +121,10 @@ public:
|
||||||
{
|
{
|
||||||
x2_task_queue.push([this, eutra_rnti, nr_rnti]() { rrc.sgnb_addition_complete(eutra_rnti, nr_rnti); });
|
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
|
void set_activity_user(uint16_t eutra_rnti) final
|
||||||
{
|
{
|
||||||
// Note: RRC processes activity asynchronously, so there is no need to use x2_task_queue
|
// Note: RRC processes activity asynchronously, so there is no need to use x2_task_queue
|
||||||
|
|
|
@ -131,6 +131,7 @@ public:
|
||||||
void sgnb_addition_ack(uint16_t eutra_rnti, const sgnb_addition_ack_params_t params) override;
|
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_reject(uint16_t eutra_rnti) override;
|
||||||
void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_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;
|
void sgnb_release_ack(uint16_t eutra_rnti) override;
|
||||||
|
|
||||||
// rrc_interface_pdcp
|
// rrc_interface_pdcp
|
||||||
|
|
|
@ -83,6 +83,13 @@ public:
|
||||||
}
|
}
|
||||||
eutra_stack->sgnb_addition_complete(eutra_rnti, nr_rnti);
|
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
|
void sgnb_release_ack(uint16_t eutra_rnti) override
|
||||||
{
|
{
|
||||||
|
|
|
@ -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});
|
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)
|
void rrc::sgnb_release_ack(uint16_t eutra_rnti)
|
||||||
{
|
{
|
||||||
auto ue_it = users.find(eutra_rnti);
|
auto ue_it = users.find(eutra_rnti);
|
||||||
|
|
|
@ -245,6 +245,8 @@ void rrc_nr::set_activity_user(uint16_t rnti)
|
||||||
|
|
||||||
// inform EUTRA RRC about user activity
|
// inform EUTRA RRC about user activity
|
||||||
if (ue_ptr->is_endc()) {
|
if (ue_ptr->is_endc()) {
|
||||||
|
// Restart inactivity timer for RRC-NR
|
||||||
|
ue_ptr->set_activity();
|
||||||
// inform EUTRA RRC about user activity
|
// inform EUTRA RRC about user activity
|
||||||
rrc_eutra->set_activity_user(ue_ptr->get_eutra_rnti());
|
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
|
// Set timer for MSG3_RX_TIMEOUT or UE_INACTIVITY_TIMEOUT
|
||||||
activity_timer = parent->task_sched.get_unique_timer();
|
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)
|
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
|
// TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 100ms
|
||||||
deadline_ms = 100;
|
deadline_ms = 100;
|
||||||
break;
|
break;
|
||||||
|
case MSG5_RX_TIMEOUT:
|
||||||
|
// TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 1s
|
||||||
|
deadline_ms = 1000;
|
||||||
|
break;
|
||||||
case UE_INACTIVITY_TIMEOUT:
|
case UE_INACTIVITY_TIMEOUT:
|
||||||
// TODO: Add a value for the inactivity timeout - currently no activity set this case
|
// TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 5s
|
||||||
return;
|
deadline_ms = 5000;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
parent->logger.error("Unknown timeout type %d", type);
|
parent->logger.error("Unknown timeout type %d", type);
|
||||||
return;
|
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); });
|
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);
|
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());
|
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) {
|
switch (type) {
|
||||||
|
case MSG5_RX_TIMEOUT:
|
||||||
case UE_INACTIVITY_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;
|
break;
|
||||||
case MSG3_RX_TIMEOUT: {
|
case MSG3_RX_TIMEOUT: {
|
||||||
// MSG3 timeout, no need to notify NGAP or LTE stack. Just remove UE
|
// 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;
|
uint32_t rnti_to_rem = rnti;
|
||||||
parent->task_sched.defer_task([this, rnti_to_rem]() { parent->rem_user(rnti_to_rem); });
|
parent->task_sched.defer_task([this, rnti_to_rem]() { parent->rem_user(rnti_to_rem); });
|
||||||
break;
|
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)
|
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);
|
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
|
// send SgNB addition complete for ENDC users
|
||||||
parent->rrc_eutra->sgnb_addition_complete(eutra_rnti, rnti);
|
parent->rrc_eutra->sgnb_addition_complete(eutra_rnti, rnti);
|
||||||
|
|
||||||
// stop RX MSG3 activity timer on MAC CE RNTI reception
|
// stop RX MSG3/MSG5 activity timer on MAC CE RNTI reception
|
||||||
activity_timer.stop();
|
set_activity_timeout(UE_INACTIVITY_TIMEOUT);
|
||||||
parent->logger.debug("Received MAC CE-RNTI for 0x%x - stopping MSG3 timer", rnti);
|
parent->logger.debug("Received MAC CE-RNTI for 0x%x - stopping MSG3/MSG5 timer, starting inactivity timer", rnti);
|
||||||
|
|
||||||
// Add DRB1 to MAC
|
// Add DRB1 to MAC
|
||||||
for (auto& drb : cell_group_cfg.rlc_bearer_to_add_mod_list) {
|
for (auto& drb : cell_group_cfg.rlc_bearer_to_add_mod_list) {
|
||||||
|
|
Loading…
Reference in New Issue