created the method chain in RRC to receive and handle the response to a S1AP HORequired

This commit is contained in:
Francisco Paisana 2019-11-06 10:43:51 +00:00
parent 50ed2ccfec
commit ff62ae6ad0
7 changed files with 66 additions and 22 deletions

View File

@ -268,10 +268,11 @@ public:
virtual void write_dl_info(uint16_t rnti, srslte::unique_byte_buffer_t sdu) = 0;
virtual void release_complete(uint16_t rnti) = 0;
virtual bool setup_ue_ctxt(uint16_t rnti, LIBLTE_S1AP_MESSAGE_INITIALCONTEXTSETUPREQUEST_STRUCT *msg) = 0;
virtual bool modify_ue_ctxt(uint16_t rnti, LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONREQUEST_STRUCT *msg) = 0;
virtual bool setup_ue_erabs(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT *msg) = 0;
virtual bool release_erabs(uint32_t rnti) = 0;
virtual void add_paging_id(uint32_t ueid, LIBLTE_S1AP_UEPAGINGID_STRUCT UEPagingID) = 0;
virtual bool modify_ue_ctxt(uint16_t rnti, LIBLTE_S1AP_MESSAGE_UECONTEXTMODIFICATIONREQUEST_STRUCT* msg) = 0;
virtual bool setup_ue_erabs(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT* msg) = 0;
virtual bool release_erabs(uint32_t rnti) = 0;
virtual void add_paging_id(uint32_t ueid, LIBLTE_S1AP_UEPAGINGID_STRUCT UEPagingID) = 0;
virtual void ho_preparation_complete(uint16_t rnti, bool is_success) = 0;
};
// GTPU interface for PDCP

View File

@ -180,6 +180,7 @@ public:
bool setup_ue_erabs(uint16_t rnti, LIBLTE_S1AP_MESSAGE_E_RABSETUPREQUEST_STRUCT* msg) override;
bool release_erabs(uint32_t rnti) override;
void add_paging_id(uint32_t ueid, LIBLTE_S1AP_UEPAGINGID_STRUCT UEPagingID) override;
void ho_preparation_complete(uint16_t rnti, bool is_success) override;
// rrc_interface_pdcp
void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) override;
@ -259,6 +260,9 @@ public:
LIBLTE_S1AP_NAS_PDU_STRUCT* nas_pdu);
bool release_erabs();
// handover
void handle_ho_preparation_complete(bool is_success);
void notify_s1ap_ue_ctxt_setup_complete();
void notify_s1ap_ue_erab_setup_response(LIBLTE_S1AP_E_RABTOBESETUPLISTBEARERSUREQ_STRUCT* e);

View File

@ -85,11 +85,12 @@ public:
explicit rrc_mobility(srsenb::rrc::ue* outer_ue);
bool fill_conn_recfg_msg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg);
void handle_ue_meas_report(const asn1::rrc::meas_report_s& msg);
void handle_ho_preparation_complete(bool is_success);
private:
enum class ho_interface_t { S1, X2, interSector };
bool send_s1_ho_required(uint32_t target_eci, uint8_t measobj_id, bool fwd_direct_path_available);
bool start_ho_preparation(uint32_t target_eci, uint8_t measobj_id, bool fwd_direct_path_available);
rrc::ue* rrc_ue = nullptr;
rrc* rrc_enb = nullptr;
@ -103,6 +104,10 @@ private:
class sourceenb_ho_proc_t
{
public:
struct ho_prep_result {
bool is_success;
};
explicit sourceenb_ho_proc_t(rrc_mobility* ue_mobility_);
srslte::proc_outcome_t init(const asn1::rrc::meas_id_to_add_mod_s& measid_,
const asn1::rrc::meas_obj_to_add_mod_s& measobj_,
@ -111,6 +116,7 @@ private:
const asn1::rrc::meas_result_eutra_s& meas_res_,
uint32_t target_eci_);
srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; }
srslte::proc_outcome_t react(ho_prep_result);
static const char* name() { return "Handover"; }
private:

View File

@ -155,6 +155,7 @@ private:
srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; }
srslte::proc_outcome_t react(ts1_reloc_prep_expired e);
srslte::proc_outcome_t react(const LIBLTE_S1AP_MESSAGE_HANDOVERPREPARATIONFAILURE_STRUCT& msg);
void then(const srslte::proc_state_t& result);
const char* name() { return "HandoverPreparation"; }
private:
@ -167,9 +168,6 @@ private:
explicit ue(uint16_t rnti, s1ap* s1ap_ptr_);
bool start_ho_preparation(uint32_t target_eci_,
srslte::plmn_id_t target_plmn_,
srslte::unique_byte_buffer_t rrc_container);
ue_ctxt_t& get_ctxt() { return ctxt; }
srslte::proc_t<ho_prep_proc_t>& get_ho_prep_proc() { return ho_prep_proc; }

View File

@ -624,6 +624,15 @@ void rrc::read_pdu_pcch(uint8_t* payload, uint32_t buffer_size)
pthread_mutex_unlock(&paging_mutex);
}
/*******************************************************************************
Handover functions
*******************************************************************************/
void rrc::ho_preparation_complete(uint16_t rnti, bool is_success)
{
users[rnti]->handle_ho_preparation_complete(is_success);
}
/*******************************************************************************
Private functions
All private functions are not mutexed and must be called from a mutexed enviornment
@ -2012,6 +2021,13 @@ void rrc::ue::send_ue_cap_enquiry()
send_dl_dcch(&dl_dcch_msg);
}
/********************** Handover **************************/
void rrc::ue::handle_ho_preparation_complete(bool is_success)
{
mobility_handler->handle_ho_preparation_complete(is_success);
}
/********************** HELPERS ***************************/
bool rrc::ue::select_security_algorithms()

View File

@ -740,7 +740,9 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg)
* - 1st Message of the handover preparation phase
* - includes info about the target eNB and the radio resources of the source eNB
*/
bool rrc::ue::rrc_mobility::send_s1_ho_required(uint32_t target_eci, uint8_t measobj_id, bool fwd_direct_path_available)
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\n");
@ -874,6 +876,11 @@ bool rrc::ue::rrc_mobility::send_s1_ho_required(uint32_t target_eci, uint8_t mea
return success;
}
void rrc::ue::rrc_mobility::handle_ho_preparation_complete(bool is_success)
{
source_ho_proc.trigger(sourceenb_ho_proc_t::ho_prep_result{is_success});
}
/*************************************************************************************************
* sourceenb_ho_proc_t class
************************************************************************************************/
@ -901,11 +908,22 @@ srslte::proc_outcome_t rrc::ue::rrc_mobility::sourceenb_ho_proc_t::init(const me
state = state_t::ho_preparation;
procInfo("Started Handover of rnti=0x%x to %s.\n", parent->rrc_ue->rnti, rrc_details::to_string(*cell).c_str());
if (not parent->send_s1_ho_required(target_eci, measobj->meas_obj_id, fwd_direct_path_available)) {
if (not parent->start_ho_preparation(target_eci, measobj->meas_obj_id, fwd_direct_path_available)) {
procError("Failed to send HO Required to MME.\n");
return srslte::proc_outcome_t::error;
}
return srslte::proc_outcome_t::yield;
}
srslte::proc_outcome_t rrc::ue::rrc_mobility::sourceenb_ho_proc_t::react(ho_prep_result e)
{
if (not e.is_success) {
procError("Failure during handover preparation.\n");
return srslte::proc_outcome_t::error;
}
procError("Handover preparation successful\n");
// TODO: send HO command to UE
return srslte::proc_outcome_t::success;
}
} // namespace srsenb

View File

@ -76,6 +76,11 @@ srslte::proc_outcome_t s1ap::ue::ho_prep_proc_t::react(const LIBLTE_S1AP_MESSAGE
return srslte::proc_outcome_t::error;
}
void s1ap::ue::ho_prep_proc_t::then(const srslte::proc_state_t& result)
{
s1ap_ptr->rrc->ho_preparation_complete(ue_ptr->ctxt.rnti, result.is_success());
}
/*********************************************************
* S1AP class
*********************************************************/
@ -1254,7 +1259,14 @@ bool s1ap::send_ho_required(uint16_t rnti,
if (it == users.end()) {
return false;
}
return it->second->start_ho_preparation(target_eci, target_plmn, std::move(rrc_container));
// launch procedure
if (not it->second->get_ho_prep_proc().launch(target_eci, target_plmn, std::move(rrc_container))) {
s1ap_log->error("Failed to initiate an HandoverPreparation procedure for user rnti=0x%x\n",
it->second->get_ctxt().rnti);
return false;
}
return true;
}
// bool s1ap::send_ue_capabilities(uint16_t rnti, LIBLTE_RRC_UE_EUTRA_CAPABILITY_STRUCT *caps)
@ -1388,17 +1400,6 @@ s1ap::ue::ue(uint16_t rnti_, s1ap* s1ap_ptr_) : s1ap_ptr(s1ap_ptr_), s1ap_log(s1
ts1_reloc_prep.set(10000, [this](uint32_t tid) { ho_prep_proc.trigger(ho_prep_proc_t::ts1_reloc_prep_expired{}); });
}
bool s1ap::ue::start_ho_preparation(uint32_t target_eci,
srslte::plmn_id_t target_plmn,
srslte::unique_byte_buffer_t rrc_container)
{
if (not ho_prep_proc.launch(target_eci, target_plmn, std::move(rrc_container))) {
s1ap_log->error("Failed to initiate an HandoverPreparation procedure for user rnti=0x%x\n", ctxt.rnti);
return false;
}
return true;
}
bool s1ap::ue::send_ho_required(uint32_t target_eci,
srslte::plmn_id_t target_plmn,
srslte::unique_byte_buffer_t rrc_container)