implemented rrc reconfiguration procedure that includes a continuation when phy configuration is complete

This commit is contained in:
Francisco Paisana 2020-09-25 20:28:50 +02:00
parent 4c88404801
commit fc49b5a030
4 changed files with 143 additions and 68 deletions

View File

@ -295,6 +295,7 @@ private:
class serving_cell_config_proc;
class cell_selection_proc;
class connection_request_proc;
class connection_reconf_no_ho_proc;
class plmn_search_proc;
class process_pcch_proc;
class go_idle_proc;
@ -312,6 +313,7 @@ private:
srslte::proc_t<cell_reselection_proc> cell_reselector;
srslte::proc_t<connection_reest_proc> connection_reest;
srslte::proc_t<ho_proc> ho_handler;
srslte::proc_t<connection_reconf_no_ho_proc> conn_recfg_proc;
srslte::proc_manager_list_t callback_list;
@ -345,7 +347,6 @@ private:
void parse_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu);
// Helpers
bool con_reconfig(const asn1::rrc::rrc_conn_recfg_s& reconfig);
void con_reconfig_failed();
bool con_reconfig_ho(const asn1::rrc::rrc_conn_recfg_s& reconfig);
void ho_failed();

View File

@ -197,6 +197,26 @@ private:
srslte::proc_future_t<void> serv_cfg_fut;
};
class rrc::connection_reconf_no_ho_proc
{
public:
explicit connection_reconf_no_ho_proc(rrc* parent_);
srslte::proc_outcome_t init(const asn1::rrc::rrc_conn_recfg_s& recfg_);
srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; }
static const char* name() { return "Connection Reconfiguration"; }
srslte::proc_outcome_t react(const bool& config_complete);
void then(const srslte::proc_state_t& result);
private:
srslte::proc_outcome_t handle_recfg_complete();
// const
rrc* rrc_ptr;
// args
asn1::rrc::rrc_conn_recfg_r8_ies_s rx_recfg;
enum state_t { wait_scell_config, wait_phy_config } state;
};
class rrc::process_pcch_proc
{
public:

View File

@ -68,7 +68,8 @@ rrc::rrc(stack_interface_rrc* stack_, srslte::task_sched_handle task_sched_) :
plmn_searcher(this),
cell_reselector(this),
connection_reest(this),
ho_handler(this)
ho_handler(this),
conn_recfg_proc(this)
{}
rrc::~rrc() = default;
@ -360,7 +361,13 @@ void rrc::cell_select_complete(bool cs_ret)
phy_ctrl->cell_selection_completed(cs_ret);
}
void rrc::set_config_complete(bool status) {}
void rrc::set_config_complete(bool status)
{
// Signal Reconfiguration Procedure that PHY configuration has completed
if (conn_recfg_proc.is_busy()) {
conn_recfg_proc.trigger(status);
}
}
void rrc::set_scell_complete(bool status) {}
@ -906,69 +913,6 @@ void rrc::start_go_idle()
callback_list.add_proc(idle_setter);
}
// Handle RRC Reconfiguration without MobilityInformation Section 5.3.5.3
bool rrc::con_reconfig(const rrc_conn_recfg_s& reconfig)
{
const rrc_conn_recfg_r8_ies_s* reconfig_r8 = &reconfig.crit_exts.c1().rrc_conn_recfg_r8();
// If first message after reestablishment, resume SRB2 and all DRB
if (reestablishment_successful) {
for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) {
if (rlc->has_bearer(i)) {
rlc->resume_bearer(i);
}
}
}
// If this is the first con_reconfig after a reestablishment
if (reestablishment_successful) {
// Reestablish PDCP and RLC for SRB2 and all DRB
// TODO: Which is the maximum LCID?
reestablishment_successful = false;
for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) {
if (rlc->has_bearer(i)) {
pdcp->reestablish(i);
rlc->reestablish(i);
}
}
}
// Apply RR config as in 5.3.10
if (reconfig_r8->rr_cfg_ded_present) {
if (!apply_rr_config_dedicated(&reconfig_r8->rr_cfg_ded)) {
return false;
}
}
// Apply Scell RR configurations (call is non-blocking). Make a copy since can be changed inside apply_scell_config()
// Note that apply_scell_config() calls set_scell() and set_config() which run in the background.
rrc_conn_recfg_r8_ies_s reconfig_r8_ = *reconfig_r8;
apply_scell_config(&reconfig_r8_, true);
if (!measurements->parse_meas_config(
reconfig_r8, reestablishment_successful, connection_reest.get()->get_source_earfcn())) {
return false;
}
// FIXME-@frankist: From here to the end need to be processed when set_config_complete() is called
send_rrc_con_reconfig_complete();
unique_byte_buffer_t nas_sdu;
for (uint32_t i = 0; i < reconfig_r8->ded_info_nas_list.size(); i++) {
nas_sdu = srslte::allocate_unique_buffer(*pool);
if (nas_sdu.get()) {
memcpy(nas_sdu->msg, reconfig_r8->ded_info_nas_list[i].data(), reconfig_r8->ded_info_nas_list[i].size());
nas_sdu->N_bytes = reconfig_r8->ded_info_nas_list[i].size();
nas->write_pdu(RB_ID_SRB1, std::move(nas_sdu));
} else {
rrc_log->error("Fatal Error: Couldn't allocate PDU in %s.\n", __FUNCTION__);
return false;
}
}
return true;
}
// HO failure from T304 expiry 5.3.5.6
void rrc::ho_failed()
{
@ -1004,9 +948,11 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, const rrc_conn_recfg_s& reconfi
if (reconfig_r8.mob_ctrl_info_present) {
con_reconfig_ho(reconfig);
} else {
if (!con_reconfig(reconfig)) {
con_reconfig_failed();
if (not conn_recfg_proc.launch(reconfig)) {
rrc_log->error("Unable to launch Handover Preparation procedure\n");
return;
}
callback_list.add_proc(conn_recfg_proc);
}
}

View File

@ -940,6 +940,114 @@ srslte::proc_outcome_t rrc::connection_request_proc::react(const cell_selection_
}
}
/******************************************
* Connection Reconfiguration Procedure
*****************************************/
// Handle RRC Reconfiguration without MobilityInformation Section 5.3.5.3
rrc::connection_reconf_no_ho_proc::connection_reconf_no_ho_proc(srsue::rrc* parent_) : rrc_ptr(parent_) {}
srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& recfg_)
{
Info("Starting...\n");
rx_recfg = recfg_.crit_exts.c1().rrc_conn_recfg_r8();
// If first message after reestablishment, resume SRB2 and all DRB
if (rrc_ptr->reestablishment_successful) {
for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) {
if (rrc_ptr->rlc->has_bearer(i)) {
rrc_ptr->rlc->resume_bearer(i);
}
}
}
// If this is the first con_reconfig after a reestablishment
if (rrc_ptr->reestablishment_successful) {
// Reestablish PDCP and RLC for SRB2 and all DRB
// TODO: Which is the maximum LCID?
rrc_ptr->reestablishment_successful = false;
for (int i = 2; i < SRSLTE_N_RADIO_BEARERS; i++) {
if (rrc_ptr->rlc->has_bearer(i)) {
rrc_ptr->pdcp->reestablish(i);
rrc_ptr->rlc->reestablish(i);
}
}
}
// Apply RR config as in 5.3.10
if (rx_recfg.rr_cfg_ded_present) {
if (!rrc_ptr->apply_rr_config_dedicated(&rx_recfg.rr_cfg_ded)) {
return proc_outcome_t::error;
}
}
// Apply Scell RR configurations (call is non-blocking). Make a copy since can be changed inside apply_scell_config()
// Note that apply_scell_config() calls set_scell() and set_config() which run in the background.
rrc_ptr->apply_scell_config(&rx_recfg, true);
if (!rrc_ptr->measurements->parse_meas_config(
&rx_recfg, rrc_ptr->reestablishment_successful, rrc_ptr->connection_reest.get()->get_source_earfcn())) {
return proc_outcome_t::error;
}
// Wait for PHY configurations to be complete
if (std::count(&rrc_ptr->current_scell_configured[0], &rrc_ptr->current_scell_configured[SRSLTE_MAX_CARRIERS], true) >
0) {
state = wait_scell_config;
} else {
state = wait_phy_config;
}
return proc_outcome_t::yield;
}
srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::react(const bool& config_complete)
{
if (not config_complete) {
rrc_ptr->rrc_log->error("Failed to config PHY\n");
return proc_outcome_t::error;
}
// in case there are scell to configure, wait for second phy configuration
if (state == wait_scell_config) {
state = wait_phy_config;
return proc_outcome_t::yield;
}
return handle_recfg_complete();
}
srslte::proc_outcome_t rrc::connection_reconf_no_ho_proc::handle_recfg_complete()
{
rrc_ptr->send_rrc_con_reconfig_complete();
srslte::unique_byte_buffer_t nas_sdu;
for (uint32_t i = 0; i < rx_recfg.ded_info_nas_list.size(); i++) {
nas_sdu = srslte::allocate_unique_buffer(*rrc_ptr->pool);
if (nas_sdu.get()) {
memcpy(nas_sdu->msg, rx_recfg.ded_info_nas_list[i].data(), rx_recfg.ded_info_nas_list[i].size());
nas_sdu->N_bytes = rx_recfg.ded_info_nas_list[i].size();
rrc_ptr->nas->write_pdu(RB_ID_SRB1, std::move(nas_sdu));
} else {
rrc_ptr->rrc_log->error("Fatal Error: Couldn't allocate PDU in %s.\n", __FUNCTION__);
return proc_outcome_t::error;
}
}
return proc_outcome_t::success;
}
void rrc::connection_reconf_no_ho_proc::then(const srslte::proc_state_t& result)
{
if (result.is_success()) {
rrc_ptr->rrc_log->info("Finished %s successfully\n", name());
return;
}
// Section 5.3.5.5 - Reconfiguration failure
rrc_ptr->con_reconfig_failed();
}
/**************************************
* Process PCCH procedure
*************************************/