avoid releasing ues doing s1 handover before TS1relocoverall expiry

master
Francisco 4 years ago committed by Ismael Gomez
parent b093576634
commit e07ef0aa18

@ -63,11 +63,19 @@ int rrc::ue::init()
// Set timeout to release UE context after RLF detection // Set timeout to release UE context after RLF detection
uint32_t deadline_ms = parent->cfg.rlf_release_timer_ms; uint32_t deadline_ms = parent->cfg.rlf_release_timer_ms;
if (rnti != SRSRAN_MRNTI) {
auto timer_expire_func = [this](uint32_t tid) { rlf_timer_expired(tid); }; auto timer_expire_func = [this](uint32_t tid) { rlf_timer_expired(tid); };
phy_dl_rlf_timer.set(deadline_ms, timer_expire_func); phy_dl_rlf_timer.set(deadline_ms, timer_expire_func);
phy_ul_rlf_timer.set(deadline_ms, timer_expire_func); phy_ul_rlf_timer.set(deadline_ms, timer_expire_func);
rlc_rlf_timer.set(deadline_ms, timer_expire_func); rlc_rlf_timer.set(deadline_ms, timer_expire_func);
parent->logger.info("Setting RLF timer for rnti=0x%x to %dms", rnti, deadline_ms); parent->logger.info("Setting RLF timer for rnti=0x%x to %dms", rnti, deadline_ms);
} else {
// in case of M-RNTI do not handle rlf timer expiration
auto timer_expire_func = [](uint32_t tid) {};
phy_dl_rlf_timer.set(deadline_ms, timer_expire_func);
phy_ul_rlf_timer.set(deadline_ms, timer_expire_func);
rlc_rlf_timer.set(deadline_ms, timer_expire_func);
}
mobility_handler = make_rnti_obj<rrc_mobility>(rnti, this); mobility_handler = make_rnti_obj<rrc_mobility>(rnti, this);
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
@ -94,12 +102,13 @@ void rrc::ue::get_metrics(rrc_ue_metrics_t& ue_metrics) const
void rrc::ue::set_activity() void rrc::ue::set_activity()
{ {
if (rnti == SRSRAN_MRNTI) {
return;
}
// re-start activity timer with current timeout value // re-start activity timer with current timeout value
activity_timer.run(); activity_timer.run();
if (parent) {
parent->logger.debug("Activity registered for rnti=0x%x (timeout_value=%dms)", rnti, activity_timer.duration()); parent->logger.debug("Activity registered for rnti=0x%x (timeout_value=%dms)", rnti, activity_timer.duration());
} }
}
void rrc::ue::set_radiolink_dl_state(bool crc_res) void rrc::ue::set_radiolink_dl_state(bool crc_res)
{ {
@ -165,14 +174,11 @@ void rrc::ue::set_radiolink_ul_state(bool crc_res)
void rrc::ue::activity_timer_expired(const activity_timeout_type_t type) void rrc::ue::activity_timer_expired(const activity_timeout_type_t type)
{ {
if (parent) {
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());
if (parent->s1ap->user_exists(rnti)) { if (parent->s1ap->user_exists(rnti)) {
if (type == UE_INACTIVITY_TIMEOUT) { if (type == UE_INACTIVITY_TIMEOUT) {
if (not parent->s1ap->user_release(rnti, asn1::s1ap::cause_radio_network_opts::user_inactivity)) { parent->s1ap->user_release(rnti, asn1::s1ap::cause_radio_network_opts::user_inactivity);
parent->rem_user_thread(rnti);
}
con_release_result = procedure_result_code::activity_timeout; con_release_result = procedure_result_code::activity_timeout;
} else if (type == MSG3_RX_TIMEOUT) { } else if (type == MSG3_RX_TIMEOUT) {
// MSG3 timeout, no need to notify S1AP, just remove UE // MSG3 timeout, no need to notify S1AP, just remove UE
@ -186,11 +192,8 @@ void rrc::ue::activity_timer_expired(const activity_timeout_type_t type)
"Unhandled reason for activity timer expiration. rnti=0x%x, cause %d", rnti, static_cast<unsigned>(type)); "Unhandled reason for activity timer expiration. rnti=0x%x, cause %d", rnti, static_cast<unsigned>(type));
} }
} else { } else {
if (rnti != SRSRAN_MRNTI) {
parent->rem_user_thread(rnti); parent->rem_user_thread(rnti);
} }
}
}
state = RRC_STATE_RELEASE_REQUEST; state = RRC_STATE_RELEASE_REQUEST;
} }
@ -211,11 +214,8 @@ void rrc::ue::rlf_timer_expired(uint32_t timeout_id)
rlc_rlf_timer.stop(); rlc_rlf_timer.stop();
state = RRC_STATE_RELEASE_REQUEST; state = RRC_STATE_RELEASE_REQUEST;
if (parent->s1ap->user_release(rnti, asn1::s1ap::cause_radio_network_opts::radio_conn_with_ue_lost)) { parent->s1ap->user_release(rnti, asn1::s1ap::cause_radio_network_opts::radio_conn_with_ue_lost);
con_release_result = procedure_result_code::radio_conn_with_ue_lost; con_release_result = procedure_result_code::radio_conn_with_ue_lost;
} else if (rnti != SRSRAN_MRNTI) {
parent->rem_user(rnti);
}
} }
void rrc::ue::max_rlc_retx_reached() void rrc::ue::max_rlc_retx_reached()
@ -390,9 +390,7 @@ void rrc::ue::handle_rrc_con_req(rrc_conn_request_s* msg)
if (user.first != rnti && user.second->has_tmsi && user.second->mmec == mmec && user.second->m_tmsi == m_tmsi) { if (user.first != rnti && user.second->has_tmsi && user.second->mmec == mmec && user.second->m_tmsi == m_tmsi) {
parent->logger.info("RRC connection request: UE context already exists. M-TMSI=%d", m_tmsi); parent->logger.info("RRC connection request: UE context already exists. M-TMSI=%d", m_tmsi);
user.second->state = RRC_STATE_IDLE; // Set old rnti to IDLE so that enb doesn't send RRC Connection Release user.second->state = RRC_STATE_IDLE; // Set old rnti to IDLE so that enb doesn't send RRC Connection Release
if (not parent->s1ap->user_release(user.first, asn1::s1ap::cause_radio_network_opts::radio_conn_with_ue_lost)) { parent->s1ap->user_release(user.first, asn1::s1ap::cause_radio_network_opts::radio_conn_with_ue_lost);
parent->rem_user_thread(user.first);
}
break; break;
} }
} }

@ -414,6 +414,7 @@ bool s1ap::user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_r
ue* u = users.find_ue_rnti(rnti); ue* u = users.find_ue_rnti(rnti);
if (u == nullptr) { if (u == nullptr) {
logger.warning("Released UE with rnti=0x%x not found", rnti); logger.warning("Released UE with rnti=0x%x not found", rnti);
rrc->release_ue(rnti);
return false; return false;
} }
@ -1396,18 +1397,21 @@ bool s1ap::ue::send_uectxtreleaserequest(const cause_c& cause)
{ {
if (was_uectxtrelease_requested()) { if (was_uectxtrelease_requested()) {
logger.warning("UE context for RNTI:0x%x is in zombie state. Releasing...", ctxt.rnti); logger.warning("UE context for RNTI:0x%x is in zombie state. Releasing...", ctxt.rnti);
s1ap_ptr->rrc->release_ue(ctxt.rnti);
s1ap_ptr->users.erase(this); s1ap_ptr->users.erase(this);
return false; return false;
} }
if (not ctxt.mme_ue_s1ap_id.has_value()) { if (not ctxt.mme_ue_s1ap_id.has_value()) {
logger.error("Cannot send UE context release request without a MME-UE-S1AP-Id allocated."); logger.error("Cannot send UE context release request without a MME-UE-S1AP-Id allocated.");
s1ap_ptr->rrc->release_ue(ctxt.rnti);
s1ap_ptr->users.erase(this); s1ap_ptr->users.erase(this);
return false; return false;
} }
if (ts1_reloc_overall.is_running()) { if (ts1_reloc_overall.is_running()) {
logger.info("Not sending UEContextReleaseRequest for UE rnti=0x%x performing S1 Handover.", ctxt.rnti); logger.info("Ignoring UE context release request from lower layers for UE rnti=0x%x performing S1 Handover.",
s1ap_ptr->users.erase(this); ctxt.rnti);
// leave the UE context alive until ts1_reloc_overall expiry
return false; return false;
} }
@ -1423,6 +1427,7 @@ bool s1ap::ue::send_uectxtreleaserequest(const cause_c& cause)
release_requested = s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextReleaseRequest"); release_requested = s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextReleaseRequest");
if (not release_requested) { if (not release_requested) {
s1ap_ptr->rrc->release_ue(ctxt.rnti);
s1ap_ptr->users.erase(this); s1ap_ptr->users.erase(this);
} }
return release_requested; return release_requested;

Loading…
Cancel
Save