mirror of https://github.com/PentHertz/srsLTE.git
implemented rrc reconfiguration procedure that includes a continuation when phy configuration is complete
This commit is contained in:
parent
4c88404801
commit
fc49b5a030
|
@ -295,6 +295,7 @@ private:
|
||||||
class serving_cell_config_proc;
|
class serving_cell_config_proc;
|
||||||
class cell_selection_proc;
|
class cell_selection_proc;
|
||||||
class connection_request_proc;
|
class connection_request_proc;
|
||||||
|
class connection_reconf_no_ho_proc;
|
||||||
class plmn_search_proc;
|
class plmn_search_proc;
|
||||||
class process_pcch_proc;
|
class process_pcch_proc;
|
||||||
class go_idle_proc;
|
class go_idle_proc;
|
||||||
|
@ -312,6 +313,7 @@ private:
|
||||||
srslte::proc_t<cell_reselection_proc> cell_reselector;
|
srslte::proc_t<cell_reselection_proc> cell_reselector;
|
||||||
srslte::proc_t<connection_reest_proc> connection_reest;
|
srslte::proc_t<connection_reest_proc> connection_reest;
|
||||||
srslte::proc_t<ho_proc> ho_handler;
|
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;
|
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);
|
void parse_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu);
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
bool con_reconfig(const asn1::rrc::rrc_conn_recfg_s& reconfig);
|
|
||||||
void con_reconfig_failed();
|
void con_reconfig_failed();
|
||||||
bool con_reconfig_ho(const asn1::rrc::rrc_conn_recfg_s& reconfig);
|
bool con_reconfig_ho(const asn1::rrc::rrc_conn_recfg_s& reconfig);
|
||||||
void ho_failed();
|
void ho_failed();
|
||||||
|
|
|
@ -197,6 +197,26 @@ private:
|
||||||
srslte::proc_future_t<void> serv_cfg_fut;
|
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
|
class rrc::process_pcch_proc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -68,7 +68,8 @@ rrc::rrc(stack_interface_rrc* stack_, srslte::task_sched_handle task_sched_) :
|
||||||
plmn_searcher(this),
|
plmn_searcher(this),
|
||||||
cell_reselector(this),
|
cell_reselector(this),
|
||||||
connection_reest(this),
|
connection_reest(this),
|
||||||
ho_handler(this)
|
ho_handler(this),
|
||||||
|
conn_recfg_proc(this)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
rrc::~rrc() = default;
|
rrc::~rrc() = default;
|
||||||
|
@ -360,7 +361,13 @@ void rrc::cell_select_complete(bool cs_ret)
|
||||||
phy_ctrl->cell_selection_completed(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) {}
|
void rrc::set_scell_complete(bool status) {}
|
||||||
|
|
||||||
|
@ -906,69 +913,6 @@ void rrc::start_go_idle()
|
||||||
callback_list.add_proc(idle_setter);
|
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
|
// HO failure from T304 expiry 5.3.5.6
|
||||||
void rrc::ho_failed()
|
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) {
|
if (reconfig_r8.mob_ctrl_info_present) {
|
||||||
con_reconfig_ho(reconfig);
|
con_reconfig_ho(reconfig);
|
||||||
} else {
|
} else {
|
||||||
if (!con_reconfig(reconfig)) {
|
if (not conn_recfg_proc.launch(reconfig)) {
|
||||||
con_reconfig_failed();
|
rrc_log->error("Unable to launch Handover Preparation procedure\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
callback_list.add_proc(conn_recfg_proc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
* Process PCCH procedure
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
Loading…
Reference in New Issue