implement Handover direct forwarding path availability configuration feature

master
Francisco 4 years ago committed by Francisco Paisana
parent 4b9e59e8cf
commit 14d32db92f

@ -32,6 +32,7 @@ struct meas_cell_cfg_t {
uint16_t pci;
uint32_t eci;
float q_offset;
bool direct_forward_path_available;
};
// neigh measurement Cell info

@ -76,7 +76,8 @@ public:
uint32_t target_eci,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container) = 0;
srsran::unique_byte_buffer_t rrc_container,
bool has_direct_fwd_path) = 0;
/**
* Command the s1ap to transmit eNBStatusTransfer message to MME. This message passes the PDCP context of the UE

@ -82,6 +82,7 @@ private:
struct ho_meas_report_ev {
uint32_t target_eci = 0;
const asn1::rrc::meas_obj_to_add_mod_s* meas_obj = nullptr;
bool direct_fwd_path = false;
};
struct ho_req_rx_ev {
const asn1::s1ap::ho_request_s* ho_req_msg;

@ -86,7 +86,8 @@ public:
uint32_t target_eci,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container) override;
srsran::unique_byte_buffer_t rrc_container,
bool has_direct_fwd_path) override;
bool send_enb_status_transfer_proc(uint16_t rnti, std::vector<bearer_status_info>& bearer_status_list) override;
bool send_ho_req_ack(const asn1::s1ap::ho_request_s& msg,
uint16_t rnti,
@ -213,7 +214,8 @@ private:
srsran::proc_outcome_t init(uint32_t target_eci_,
srsran::plmn_id_t target_plmn_,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container);
srsran::unique_byte_buffer_t rrc_container,
bool has_direct_fwd_path);
srsran::proc_outcome_t step() { return srsran::proc_outcome_t::yield; }
srsran::proc_outcome_t react(ts1_reloc_prep_expired e);
srsran::proc_outcome_t react(const asn1::s1ap::ho_prep_fail_s& msg);
@ -263,7 +265,8 @@ private:
bool send_ho_required(uint32_t target_eci_,
srsran::plmn_id_t target_plmn_,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container);
srsran::unique_byte_buffer_t rrc_container,
bool has_direct_fwd_path);
void get_erab_addr(uint16_t erab_id, transp_addr_t& transp_addr, asn1::fixed_octstring<4, true>& gtpu_teid_id);
// args

@ -75,6 +75,7 @@ cell_list =
eci = 0x19C02;
dl_earfcn = 2850;
pci = 2;
//direct_forward_path_available = false;
}
);

@ -675,15 +675,12 @@ static int parse_meas_cell_list(rrc_meas_cfg_t* meas_cfg, Setting& root)
{
meas_cfg->meas_cells.resize(root.getLength());
for (uint32_t i = 0; i < meas_cfg->meas_cells.size(); ++i) {
meas_cfg->meas_cells[i].earfcn = root[i]["dl_earfcn"];
meas_cfg->meas_cells[i].pci = (unsigned int)root[i]["pci"] % SRSRAN_NUM_PCI;
meas_cfg->meas_cells[i].eci = (unsigned int)root[i]["eci"];
meas_cfg->meas_cells[i].q_offset = 0; // LIBLTE_RRC_Q_OFFSET_RANGE_DB_0; // TODO
// // TODO: TEMP
// printf("PARSER: neighbor cell: {dl_earfcn=%d pci=%d cell_idx=0x%x}\n",
// meas_cfg->meas_cells[i].earfcn,
// meas_cfg->meas_cells[i].pci,
// meas_cfg->meas_cells[i].eci);
auto& cell = meas_cfg->meas_cells[i];
cell.earfcn = root[i]["dl_earfcn"];
cell.pci = (unsigned int)root[i]["pci"] % SRSRAN_NUM_PCI;
cell.eci = (unsigned int)root[i]["eci"];
cell.q_offset = 0; // LIBLTE_RRC_Q_OFFSET_RANGE_DB_0; // TODO
parse_default_field(cell.direct_forward_path_available, root[i], "direct_forward_path_available", false);
}
return 0;
}

@ -251,6 +251,7 @@ 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.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;
} else {
@ -281,11 +282,6 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci,
uint8_t measobj_id,
bool fwd_direct_path_available)
{
if (fwd_direct_path_available) {
Error("Direct tunnels not supported supported");
return false;
}
srsran::plmn_id_t target_plmn =
srsran::make_plmn_id_t(rrc_enb->cfg.sib1.cell_access_related_info.plmn_id_list[0].plmn_id);
const ue_cell_ded* src_cell_ded = rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX);
@ -392,7 +388,8 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci,
fwd_erabs.push_back(erab_pair.first);
}
return rrc_enb->s1ap->send_ho_required(rrc_ue->rnti, target_eci, target_plmn, fwd_erabs, std::move(buffer));
return rrc_enb->s1ap->send_ho_required(
rrc_ue->rnti, target_eci, target_plmn, fwd_erabs, std::move(buffer), fwd_direct_path_available);
}
/**
@ -628,7 +625,7 @@ 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, false)) {
if (not parent_fsm()->start_ho_preparation(report.target_eci, report.meas_obj->meas_obj_id, ev.direct_fwd_path)) {
trigger(srsran::failure_ev{});
}
}

@ -117,14 +117,16 @@ s1ap::ue::ho_prep_proc_t::ho_prep_proc_t(s1ap::ue* ue_) : ue_ptr(ue_), s1ap_ptr(
srsran::proc_outcome_t s1ap::ue::ho_prep_proc_t::init(uint32_t target_eci_,
srsran::plmn_id_t target_plmn_,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container_)
srsran::unique_byte_buffer_t rrc_container_,
bool has_direct_fwd_path)
{
ho_cmd_msg = nullptr;
target_eci = target_eci_;
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_))) {
if (not ue_ptr->send_ho_required(
target_eci, 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;
}
@ -1686,7 +1688,8 @@ bool s1ap::send_ho_required(uint16_t rnti,
uint32_t target_eci,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container)
srsran::unique_byte_buffer_t rrc_container,
bool has_direct_fwd_path)
{
if (!mme_connected) {
return false;
@ -1697,7 +1700,7 @@ 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))) {
if (not u->ho_prep_proc.launch(target_eci, 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;
}
@ -1945,7 +1948,8 @@ 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,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container)
srsran::unique_byte_buffer_t rrc_container,
bool has_direct_fwd_path)
{
/*** Setup S1AP PDU as HandoverRequired ***/
s1ap_pdu_c tx_pdu;
@ -1955,10 +1959,15 @@ bool s1ap::ue::send_ho_required(uint32_t target_eci,
/*** fill HO Required message ***/
container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id;
container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value();
container.direct_forwarding_path_availability_present = false; // NOTE: X2 for fwd path not supported
container.handov_type.value.value = handov_type_opts::intralte; // NOTE: only intra-LTE HO supported
container.cause.value.set_radio_network().value = cause_radio_network_opts::ho_desirable_for_radio_reason;
container.direct_forwarding_path_availability_present = has_direct_fwd_path;
if (container.direct_forwarding_path_availability_present) {
container.direct_forwarding_path_availability.value.value =
asn1::s1ap::direct_forwarding_path_availability_opts::direct_path_available;
}
/*** set the target eNB ***/
container.csg_id_present = false; // NOTE: CSG/hybrid target cell not supported
container.cell_access_mode_present = false; // only for hybrid cells

@ -110,7 +110,8 @@ public:
uint32_t target_eci,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container) override
srsran::unique_byte_buffer_t rrc_container,
bool has_direct_fwd_path) override
{
return true;
}

@ -83,7 +83,8 @@ public:
uint32_t target_eci,
srsran::plmn_id_t target_plmn,
srsran::span<uint32_t> fwd_erabs,
srsran::unique_byte_buffer_t rrc_container) final
srsran::unique_byte_buffer_t rrc_container,
bool has_direct_fwd_path) final
{
last_ho_required = ho_req_data{rnti, target_eci, target_plmn, std::move(rrc_container)};
return true;

Loading…
Cancel
Save