rrc: fetch old ue context when reestablishment corresponds to a UE performing S1 Handover

master
Francisco Paisana 2 years ago committed by Justin Tallon
parent 9a64958514
commit 4143e8f743

@ -50,6 +50,8 @@ public:
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container,
asn1::s1ap::cause_c& cause);
std::pair<uint16_t, uint32_t> get_source_ue_rnti_and_pci();
private:
// helper methods
bool update_ue_var_meas_cfg(uint32_t src_earfcn,
@ -109,6 +111,8 @@ private:
struct s1_target_ho_st {
asn1::s1ap::cause_c failure_cause;
std::vector<uint32_t> pending_tunnels;
uint16_t src_rnti;
uint32_t src_pci;
};
struct wait_recfg_comp {};
struct s1_source_ho_st : public subfsm_t<s1_source_ho_st> {

@ -253,6 +253,9 @@ private:
void apply_pdcp_srb_updates(const asn1::rrc::rr_cfg_ded_s& pending_rr_cfg);
void apply_pdcp_drb_updates(const asn1::rrc::rr_cfg_ded_s& pending_rr_cfg);
void apply_rlc_rb_updates(const asn1::rrc::rr_cfg_ded_s& pending_rr_cfg);
/// Find UE whose Handover source identity matches the passed arguments.
ue* find_handover_source_ue(uint16_t old_rnti, uint32_t old_pci);
}; // class ue
} // namespace srsenb

@ -207,7 +207,8 @@ uint16_t rrc::start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s&
rrc::ue::rrc_mobility::rrc_mobility(rrc::ue* outer_ue) :
base_t(outer_ue->parent->logger), rrc_ue(outer_ue), rrc_enb(outer_ue->parent), logger(outer_ue->parent->logger)
{}
{
}
//! Method to add Mobility Info to a RRC Connection Reconfiguration Message
bool rrc::ue::rrc_mobility::fill_conn_recfg_no_ho_cmd(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg)
@ -584,7 +585,8 @@ bool rrc::ue::rrc_mobility::needs_intraenb_ho(idle_st& s, const ho_meas_report_e
rrc::ue::rrc_mobility::s1_source_ho_st::s1_source_ho_st(rrc_mobility* parent_) :
base_t(parent_), rrc_enb(parent_->rrc_enb), rrc_ue(parent_->rrc_ue), logger(parent_->logger)
{}
{
}
/**
* TS 36.413, Section 8.4.6 - eNB Status Transfer
@ -854,6 +856,9 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev&
rrc_ue->mac_ctrl.handle_target_enb_ho_cmd(recfg_r8, rrc_ue->ue_capabilities);
// Apply PHY updates
rrc_ue->apply_reconf_phy_config(recfg_r8, true);
// Save source UE PCI and RNTI.
get_state<s1_target_ho_st>()->src_rnti = hoprep_r8.as_cfg.source_ue_id.to_number();
get_state<s1_target_ho_st>()->src_pci = hoprep_r8.as_context.reest_info.source_pci;
// Set admitted E-RABs
std::vector<asn1::s1ap::erab_admitted_item_s> admitted_erabs;
@ -1178,4 +1183,13 @@ void rrc::ue::rrc_mobility::handle_recfg_complete(intraenb_ho_st& s, const recfg
logger.info("User rnti=0x%x successfully handovered to cell_id=0x%x", rrc_ue->rnti, s.target_cell->cell_cfg.cell_id);
}
std::pair<uint16_t, uint32_t> rrc::ue::rrc_mobility::get_source_ue_rnti_and_pci()
{
if (not is_ho_running() or (not is_in_state<s1_target_ho_st>() and not is_in_state<wait_recfg_comp>())) {
return std::make_pair(SRSRAN_INVALID_RNTI, (uint32_t)0);
}
const s1_target_ho_st* st = get_state<s1_target_ho_st>();
return std::make_pair(st->src_rnti, st->src_pci);
}
} // namespace srsenb

@ -43,7 +43,8 @@ rrc::ue::ue(rrc* outer_rrc, uint16_t rnti_, const sched_interface::ue_cfg_t& sch
bearer_list(rnti_, parent->cfg, outer_rrc->gtpu),
ue_security_cfg(parent->cfg),
mac_ctrl(rnti, ue_cell_list, bearer_list, parent->cfg, parent->mac, *parent->cell_common_list, sched_ue_cfg)
{}
{
}
rrc::ue::~ue() {}
@ -425,7 +426,8 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srsran::unique_byte_buffer_t pdu)
std::string rrc::ue::to_string(const activity_timeout_type_t& type)
{
constexpr static const char* options[] = {"Msg3 reception", "UE inactivity", "UE establishment", "UE reestablishment"};
constexpr static const char* options[] = {
"Msg3 reception", "UE inactivity", "UE establishment", "UE reestablishment"};
return srsran::enum_to_text(options, (uint32_t)activity_timeout_type_t::nulltype, (uint32_t)type);
}
@ -641,19 +643,28 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg)
}
uint16_t old_pci = msg->crit_exts.rrc_conn_reest_request_r8().ue_id.pci;
ue* old_ue = nullptr;
{
const enb_cell_common* old_cell = parent->cell_common_list->get_pci(old_pci);
auto old_ue_it = parent->users.find(old_rnti);
// Reject unrecognized rntis, and PCIs that do not belong to eNB
if (old_ue_it == parent->users.end() or old_cell == nullptr or
old_ue_it->second->ue_cell_list.get_enb_cc_idx(old_cell->enb_cc_idx) == nullptr) {
// Check if old UE context does not belong to an S1-Handover UE.
old_ue = find_handover_source_ue(old_rnti, old_pci);
if (old_ue == nullptr) {
send_connection_reest_rej(procedure_result_code::error_unknown_rnti);
parent->logger.info(
"RRCReestablishmentReject for rnti=0x%x. Cause: no rnti=0x%x context available", rnti, old_rnti);
srsran::console("RRCReestablishmentReject for rnti=0x%x. Cause: no context available\n", rnti);
return;
}
ue* old_ue = old_ue_it->second.get();
} else {
old_ue = old_ue_it->second.get();
}
}
bool old_ue_supported_endc = old_ue->endc_handler and old_ue->endc_handler->is_endc_supported();
if (not old_ue_supported_endc and req_r8.reest_cause.value == reest_cause_opts::recfg_fail) {
// Reestablishment Reject for ReconfigFailures of LTE-only mode
@ -1636,4 +1647,22 @@ int rrc::ue::get_ri(uint32_t m_ri, uint16_t* ri_idx)
return ret;
}
rrc::ue* rrc::ue::find_handover_source_ue(uint16_t old_rnti, uint32_t old_pci)
{
for (auto& ue_pair : parent->users) {
rrc::ue& u = *ue_pair.second;
if (u.mobility_handler != nullptr and u.mobility_handler->is_ho_running()) {
std::pair<uint16_t, uint32_t> src_ctxt = u.mobility_handler->get_source_ue_rnti_and_pci();
if (src_ctxt.first == old_rnti and src_ctxt.second == old_pci) {
parent->logger.info("Found old UE Context RNTI=0x%x,PCI=%d used for Reestablishment. It corresponds to a UE "
"performing handover.",
old_rnti,
old_pci);
return &u;
}
}
}
return nullptr;
}
} // namespace srsenb

Loading…
Cancel
Save