extended handover procedure to accommodate all the handover (phy cell select + ra)

master
Francisco Paisana 5 years ago committed by Francisco Paisana
parent 556fcb69e7
commit 81848deae2

@ -330,13 +330,13 @@ public:
void new_cell_meas(const std::vector<phy_meas_t>& meas);
// MAC interface
void ho_ra_completed(bool ra_successful);
void ho_ra_completed(bool ra_successful) final;
void release_pucch_srs();
void run_tti();
void ra_problem();
// GW interface
bool is_connected(); // this is also NAS interface
bool is_connected() final; // this is also NAS interface
bool have_drb();
// PDCP interface
@ -405,8 +405,6 @@ private:
srslte::phy_cfg_t current_phy_cfg, previous_phy_cfg = {};
srslte::mac_cfg_t current_mac_cfg, previous_mac_cfg = {};
bool current_scell_configured[SRSLTE_MAX_CARRIERS] = {};
bool pending_mob_reconf = false;
asn1::rrc::rrc_conn_recfg_s mob_reconf = {};
srslte::as_security_config_t sec_cfg = {};
@ -473,9 +471,6 @@ private:
bool reestablishment_started = false;
bool reestablishment_successful = false;
// Process HO completition in the background
void process_ho_ra_completed(bool ra_successful);
// Measurements private subclass
class rrc_meas;
std::unique_ptr<rrc_meas> measurements;
@ -525,7 +520,7 @@ private:
class go_idle_proc;
class cell_reselection_proc;
class connection_reest_proc;
class ho_prep_proc;
class ho_proc;
srslte::proc_t<phy_cell_select_proc> phy_cell_selector;
srslte::proc_t<cell_search_proc, phy_interface_rrc_lte::cell_search_ret_t> cell_searcher;
srslte::proc_t<si_acquire_proc> si_acquirer;
@ -537,7 +532,7 @@ private:
srslte::proc_t<plmn_search_proc> plmn_searcher;
srslte::proc_t<cell_reselection_proc> cell_reselector;
srslte::proc_t<connection_reest_proc> connection_reest;
srslte::proc_t<ho_prep_proc> ho_prep_proc;
srslte::proc_t<ho_proc> ho_handler;
srslte::proc_manager_list_t callback_list;

@ -302,18 +302,22 @@ private:
srslte::proc_outcome_t cell_criteria();
};
class rrc::ho_prep_proc
class rrc::ho_proc
{
public:
struct t304_expiry {};
struct ra_completed_ev {
bool success;
};
explicit ho_prep_proc(rrc* rrc_);
explicit ho_proc(rrc* rrc_);
srslte::proc_outcome_t init(const asn1::rrc::rrc_conn_recfg_s& rrc_reconf);
srslte::proc_outcome_t react(cell_select_event_t ev);
srslte::proc_outcome_t react(t304_expiry ev);
srslte::proc_outcome_t react(ra_completed_ev ev);
srslte::proc_outcome_t step();
void then(const srslte::proc_state_t& result);
static const char* name() { return "Handover Preparation"; }
static const char* name() { return "Handover"; }
private:
rrc* rrc_ptr = nullptr;
@ -325,7 +329,7 @@ private:
// state
uint32_t target_earfcn;
enum state_t { launch_phy_cell_select, wait_phy_cell_select_complete } state;
enum state_t { launch_phy_cell_select, wait_phy_cell_select_complete, wait_ra_completion } state;
};
} // namespace srsue

@ -100,7 +100,7 @@ rrc::rrc(stack_interface_rrc* stack_) :
plmn_searcher(this),
cell_reselector(this),
connection_reest(this),
ho_prep_proc(this),
ho_handler(this),
serving_cell(unique_cell_t(new cell_t()))
{
measurements = std::unique_ptr<rrc_meas>(new rrc_meas());
@ -169,8 +169,6 @@ void rrc::init(phy_interface_rrc_lte* phy_,
cell_clean_cnt = 0;
pending_mob_reconf = false;
// Set default values for RRC. MAC and PHY are set to default themselves
set_rrc_default();
@ -275,7 +273,7 @@ void rrc::run_tti()
radio_link_failure();
break;
case cmd_msg_t::HO_COMPLETE:
process_ho_ra_completed(msg.lcid > 0);
ho_handler.trigger(ho_proc::ra_completed_ev{msg.lcid > 0});
break;
case cmd_msg_t::STOP:
return;
@ -793,6 +791,7 @@ void rrc::radio_link_failure()
// TODO: Generate and store failure report
rrc_log->warning("Detected Radio-Link Failure\n");
rrc_log->console("Warning: Detected Radio-Link Failure\n");
if (state == RRC_STATE_CONNECTED) {
start_con_restablishment(reest_cause_e::other_fail);
}
@ -1052,38 +1051,13 @@ void rrc::ho_ra_completed(bool ra_successful)
cmd_q.push(std::move(msg));
}
void rrc::process_ho_ra_completed(bool ra_successful)
{
if (pending_mob_reconf) {
if (ra_successful) {
if (!measurements->parse_meas_config(
&mob_reconf.crit_exts.c1().rrc_conn_recfg_r8(), true, ho_src_cell.get_earfcn())) {
rrc_log->error("Parsing measurementConfig. TODO: Send ReconfigurationReject\n");
}
t304.stop();
}
// T304 will expiry and send ho_failure
rrc_log->info("HO %ssuccessful\n", ra_successful ? "" : "un");
rrc_log->console("HO %ssuccessful\n", ra_successful ? "" : "un");
pending_mob_reconf = false;
} else {
rrc_log->error("Received HO random access completed but no pending mobility reconfiguration info\n");
}
}
bool rrc::con_reconfig_ho(rrc_conn_recfg_s* reconfig)
{
// store mobilityControlInfo
mob_reconf = *reconfig;
pending_mob_reconf = true;
if (not ho_prep_proc.launch(mob_reconf)) {
if (not ho_handler.launch(*reconfig)) {
rrc_log->error("Unable to launch Handover Preparation procedure\n");
return false;
}
callback_list.add_proc(ho_prep_proc);
callback_list.add_proc(ho_handler);
return true;
}
@ -1157,7 +1131,7 @@ bool rrc::con_reconfig(rrc_conn_recfg_s* reconfig)
// HO failure from T304 expiry 5.3.5.6
void rrc::ho_failed()
{
ho_prep_proc.trigger(ho_prep_proc::t304_expiry{});
ho_handler.trigger(ho_proc::t304_expiry{});
start_con_restablishment(reest_cause_e::ho_fail);
}

@ -22,6 +22,7 @@
#include "srsue/hdr/stack/rrc/rrc_procedures.h"
#include "srslte/common/security.h"
#include "srslte/common/tti_point.h"
#include "srsue/hdr/stack/rrc/rrc_meas.h"
#include <inttypes.h> // for printing uint64_t
#define Error(fmt, ...) rrc_ptr->rrc_log->error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
@ -66,7 +67,7 @@ void rrc::phy_cell_select_proc::then(const srslte::proc_state_t& result)
} else if (rrc_ptr->cell_selector.is_busy()) {
rrc_ptr->cell_selector.trigger(cell_select_event_t{result.is_success()});
} else {
rrc_ptr->ho_prep_proc.trigger(cell_select_event_t{result.is_success()});
rrc_ptr->ho_handler.trigger(cell_select_event_t{result.is_success()});
}
}
@ -1337,9 +1338,9 @@ proc_outcome_t rrc::connection_reest_proc::step()
* Handover Preparation Procedure
*************************************/
rrc::ho_prep_proc::ho_prep_proc(srsue::rrc* rrc_) : rrc_ptr(rrc_) {}
rrc::ho_proc::ho_proc(srsue::rrc* rrc_) : rrc_ptr(rrc_) {}
srslte::proc_outcome_t rrc::ho_prep_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc_reconf)
srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc_reconf)
{
Info("Starting...\n");
recfg_r8 = rrc_reconf.crit_exts.c1().rrc_conn_recfg_r8();
@ -1381,8 +1382,12 @@ srslte::proc_outcome_t rrc::ho_prep_proc::init(const asn1::rrc::rrc_conn_recfg_s
return proc_outcome_t::yield;
}
srslte::proc_outcome_t rrc::ho_prep_proc::react(srsue::cell_select_event_t ev)
srslte::proc_outcome_t rrc::ho_proc::react(srsue::cell_select_event_t ev)
{
if (state != wait_phy_cell_select_complete) {
Warning("Received unexpected PHY Cell Selection event\n");
return proc_outcome_t::yield;
}
// Check if cell has not been deleted in the meantime
cell_t* target_cell = rrc_ptr->get_neighbour_cell_handle(target_earfcn, recfg_r8.mob_ctrl_info.target_pci);
if (target_cell == nullptr) {
@ -1439,10 +1444,12 @@ srslte::proc_outcome_t rrc::ho_prep_proc::react(srsue::cell_select_event_t ev)
recfg_r8.mob_ctrl_info.target_pci, rrc_ptr->serving_cell->get_earfcn(), ncc, &rrc_ptr->sec_cfg);
rrc_ptr->pdcp->config_security_all(rrc_ptr->sec_cfg);
return proc_outcome_t::success;
state = wait_ra_completion;
return proc_outcome_t::yield;
}
srslte::proc_outcome_t rrc::ho_prep_proc::step()
srslte::proc_outcome_t rrc::ho_proc::step()
{
if (rrc_ptr->state != RRC_STATE_CONNECTED) {
Info("HO interrupted, since RRC is no longer in connected state\n");
@ -1476,13 +1483,33 @@ srslte::proc_outcome_t rrc::ho_prep_proc::step()
return proc_outcome_t::yield;
}
srslte::proc_outcome_t rrc::ho_prep_proc::react(t304_expiry ev)
srslte::proc_outcome_t rrc::ho_proc::react(t304_expiry ev)
{
Info("HO preparation timed out.\n");
return proc_outcome_t::error;
}
void rrc::ho_prep_proc::then(const srslte::proc_state_t& result)
srslte::proc_outcome_t rrc::ho_proc::react(ra_completed_ev ev)
{
if (state != wait_ra_completion) {
Warning("Received unexpected RA Complete Event\n");
return proc_outcome_t::yield;
}
rrc_ptr->t304.stop();
if (ev.success) {
if (not rrc_ptr->measurements->parse_meas_config(&recfg_r8, true, rrc_ptr->ho_src_cell.get_earfcn())) {
Error("Parsing measurementConfig. TODO: Send ReconfigurationReject\n");
}
}
Info("HO %ssuccessful\n", ev.success ? "" : "un");
rrc_ptr->rrc_log->console("HO %ssuccessful\n", ev.success ? "" : "un");
return ev.success ? proc_outcome_t::success : proc_outcome_t::error;
}
void rrc::ho_proc::then(const srslte::proc_state_t& result)
{
Info("Finished HO Preparation %s\n", result.is_success() ? "successfully" : "with error");
if (result.is_error()) {

Loading…
Cancel
Save