rrc,s1ap: configurable target eNB TACs during LTE handover.

This commit is contained in:
Francisco 2022-04-04 14:49:35 +01:00 committed by Francisco Paisana
parent 1aa13cee9e
commit 0de1565e52
9 changed files with 36 additions and 9 deletions

View File

@ -34,6 +34,7 @@ struct meas_cell_cfg_t {
asn1::rrc::q_offset_range_e cell_individual_offset;
uint32_t allowed_meas_bw;
bool direct_forward_path_available;
int tac;
};
// neigh measurement Cell info

View File

@ -80,6 +80,7 @@ public:
*/
virtual bool send_ho_required(uint16_t rnti,
uint32_t target_eci,
uint16_t target_tac,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container,

View File

@ -57,7 +57,8 @@ private:
asn1::rrc::meas_cfg_s* diff_meas_cfg);
// Handover from source cell
bool start_ho_preparation(uint32_t target_eci, uint8_t measobj_id, bool fwd_direct_path_available);
bool
start_ho_preparation(uint32_t target_eci, uint16_t target_tac, uint8_t measobj_id, bool fwd_direct_path_available);
// Handover to target cell
void fill_mobility_reconf_common(asn1::rrc::dl_dcch_msg_s& msg,
@ -81,6 +82,7 @@ private:
// events
struct ho_meas_report_ev {
uint32_t target_eci = 0;
uint16_t target_tac = 0;
const asn1::rrc::meas_obj_to_add_mod_s* meas_obj = nullptr;
bool direct_fwd_path = false;
};

View File

@ -81,6 +81,7 @@ public:
bool is_mme_connected() override;
bool send_ho_required(uint16_t rnti,
uint32_t target_eci,
uint16_t target_tac,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container,
@ -107,7 +108,7 @@ public:
// Stack interface
bool
handle_mme_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags);
handle_mme_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags);
void start_pcap(srsran::s1ap_pcap* pcap_);
private:
@ -212,6 +213,7 @@ private:
struct ts1_reloc_prep_expired {};
ho_prep_proc_t(s1ap::ue* ue_);
srsran::proc_outcome_t init(uint32_t target_eci_,
uint16_t target_tac_,
srsran::plmn_id_t target_plmn_,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container,
@ -228,6 +230,7 @@ private:
s1ap* s1ap_ptr = nullptr;
uint32_t target_eci = 0;
uint16_t target_tac = 0;
srsran::plmn_id_t target_plmn;
srsran::unique_byte_buffer_t rrc_container;
const asn1::s1ap::ho_cmd_s* ho_cmd_msg = nullptr;
@ -260,7 +263,7 @@ private:
bool was_uectxtrelease_requested() const { return release_requested; }
void
set_state(s1ap_proc_id_t state, const erab_id_list& erabs_updated, const erab_item_list& erabs_failed_to_update);
set_state(s1ap_proc_id_t state, const erab_id_list& erabs_updated, const erab_item_list& erabs_failed_to_update);
s1ap_proc_id_t get_state() const { return current_state; }
ue_ctxt_t ctxt = {};
@ -268,6 +271,7 @@ private:
private:
bool send_ho_required(uint32_t target_eci_,
uint16_t target_tac_,
srsran::plmn_id_t target_plmn_,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container,

View File

@ -776,6 +776,7 @@ static int parse_meas_cell_list(rrc_meas_cfg_t* meas_cfg, Setting& root)
parse_default_field(cell.allowed_meas_bw, root[i], "allowed_meas_bw", 6u);
asn1_parsers::default_number_to_enum(
cell.cell_individual_offset, root[i], "cell_individual_offset", asn1::rrc::q_offset_range_opts::db0);
parse_default_field(cell.tac, root[i], "tac", -1);
srsran_assert(srsran::is_lte_cell_nof_prb(cell.allowed_meas_bw), "Invalid measurement Bandwidth");
}
return 0;
@ -1347,7 +1348,7 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_
// Create dedicated cell configuration from RRC configuration
for (auto it = rrc_cfg_->cell_list.begin(); it != rrc_cfg_->cell_list.end(); ++it) {
auto& cfg = *it;
cell_cfg_t& cfg = *it;
phy_cell_cfg_t phy_cell_cfg = {};
phy_cell_cfg.cell = cell_cfg_;
phy_cell_cfg.cell.id = cfg.pci;
@ -1396,6 +1397,13 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_
}
}
for (meas_cell_cfg_t& meas_cell : cfg.meas_cfg.meas_cells) {
if (meas_cell.tac < 0) {
// if meas cell TAC was not set, use current cell TAC.
meas_cell.tac = cfg.tac;
}
}
// Check if the enb cells PCIs won't lead to PSS detection issues
auto is_pss_collision = [&cfg](const cell_cfg_t& c) {
return c.pci % 3 == cfg.pci % 3 and c.dl_earfcn == cfg.dl_earfcn;

View File

@ -273,9 +273,11 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg, srsr
const enb_cell_common* c = rrc_enb->cell_common_list->get_pci(e.pci);
if (meas_it != meas_list_cfg.end()) {
meas_ev.target_eci = meas_it->eci;
meas_ev.target_tac = meas_it->tac;
meas_ev.direct_fwd_path = meas_it->direct_forward_path_available;
} else if (c != nullptr) {
meas_ev.target_eci = (rrc_enb->cfg.enb_id << 8u) + c->cell_cfg.cell_id;
meas_ev.target_tac = pcell->cell_common->cell_cfg.tac;
} else {
logger.warning("The PCI=%d inside the MeasReport is not recognized.", e.pci);
continue;
@ -296,6 +298,7 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg, srsr
* - This struct goes in a transparent container to the S1AP
*/
bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci,
uint16_t target_tac,
uint8_t measobj_id,
bool fwd_direct_path_available)
{
@ -405,7 +408,7 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci,
}
return rrc_enb->s1ap->send_ho_required(
rrc_ue->rnti, target_eci, target_plmn, fwd_erabs, std::move(buffer), fwd_direct_path_available);
rrc_ue->rnti, target_eci, target_tac, target_plmn, fwd_erabs, std::move(buffer), fwd_direct_path_available);
}
/**
@ -653,7 +656,8 @@ void rrc::ue::rrc_mobility::s1_source_ho_st::enter(rrc_mobility* f, const ho_mea
logger.info("Starting S1 Handover of rnti=0x%x to cellid=0x%x.", rrc_ue->rnti, ev.target_eci);
report = ev;
if (not parent_fsm()->start_ho_preparation(report.target_eci, report.meas_obj->meas_obj_id, ev.direct_fwd_path)) {
if (not parent_fsm()->start_ho_preparation(
report.target_eci, report.target_tac, report.meas_obj->meas_obj_id, ev.direct_fwd_path)) {
trigger(srsran::failure_ev{});
}
}

View File

@ -118,6 +118,7 @@ void fill_erab_failed_setup_list(OutList& output_list, const s1ap::erab_item_lis
s1ap::ue::ho_prep_proc_t::ho_prep_proc_t(s1ap::ue* ue_) : ue_ptr(ue_), s1ap_ptr(ue_->s1ap_ptr) {}
srsran::proc_outcome_t s1ap::ue::ho_prep_proc_t::init(uint32_t target_eci_,
uint16_t target_tac_,
srsran::plmn_id_t target_plmn_,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container_,
@ -125,11 +126,12 @@ srsran::proc_outcome_t s1ap::ue::ho_prep_proc_t::init(uint32_t
{
ho_cmd_msg = nullptr;
target_eci = target_eci_;
target_tac = target_tac_;
target_plmn = target_plmn_;
procInfo("Sending HandoverRequired to MME id=%d", ue_ptr->ctxt.mme_ue_s1ap_id.value());
if (not ue_ptr->send_ho_required(
target_eci, target_plmn, fwd_erabs, std::move(rrc_container_), has_direct_fwd_path)) {
target_eci, target_tac, target_plmn, fwd_erabs, std::move(rrc_container_), has_direct_fwd_path)) {
procError("Failed to send HORequired to cell 0x%x", target_eci);
return srsran::proc_outcome_t::error;
}
@ -1821,6 +1823,7 @@ void s1ap::ue::get_erab_addr(uint16_t erab_id, transp_addr_t& transp_addr, asn1:
bool s1ap::send_ho_required(uint16_t rnti,
uint32_t target_eci,
uint16_t target_tac,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container,
@ -1835,7 +1838,8 @@ bool s1ap::send_ho_required(uint16_t rnti,
}
// launch procedure
if (not u->ho_prep_proc.launch(target_eci, target_plmn, fwd_erabs, std::move(rrc_container), has_direct_fwd_path)) {
if (not u->ho_prep_proc.launch(
target_eci, target_tac, target_plmn, fwd_erabs, std::move(rrc_container), has_direct_fwd_path)) {
logger.error("Failed to initiate an HandoverPreparation procedure for user rnti=0x%x", u->ctxt.rnti);
return false;
}
@ -2101,6 +2105,7 @@ s1ap::ue::ue(s1ap* s1ap_ptr_) : s1ap_ptr(s1ap_ptr_), ho_prep_proc(this), logger(
}
bool s1ap::ue::send_ho_required(uint32_t target_eci,
uint16_t target_tac,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container,
@ -2131,7 +2136,7 @@ bool s1ap::ue::send_ho_required(uint32_t target_eci,
// set PLMN and TAI of target
// NOTE: Only HO without TAU supported.
uint16_t tmp16;
tmp16 = htons(s1ap_ptr->args.tac);
tmp16 = htons(target_tac);
memcpy(targetenb.sel_tai.tac.data(), &tmp16, sizeof(uint16_t));
target_plmn.to_s1ap_plmn_bytes(targetenb.sel_tai.plm_nid.data());
// NOTE: Only HO to different Macro eNB is supported.

View File

@ -67,6 +67,7 @@ public:
bool is_mme_connected() override { return true; }
bool send_ho_required(uint16_t rnti,
uint32_t target_eci,
uint16_t target_tac,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container,

View File

@ -81,6 +81,7 @@ public:
bool send_ho_required(uint16_t rnti,
uint32_t target_eci,
uint16_t target_tac,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container,