|
|
|
@ -869,4 +869,211 @@ proc_outcome_t rrc::cell_reselection_proc::step()
|
|
|
|
|
return srslte::proc_outcome_t::success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**************************************
|
|
|
|
|
* RRC Connection Re-establishment procedure
|
|
|
|
|
*************************************/
|
|
|
|
|
|
|
|
|
|
rrc::connection_reest_proc::connection_reest_proc(srsue::rrc* rrc_) : rrc_ptr(rrc_), state(state_t::init) {}
|
|
|
|
|
|
|
|
|
|
proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause)
|
|
|
|
|
{
|
|
|
|
|
Info("Starting...\n");
|
|
|
|
|
|
|
|
|
|
// Save Current RNTI before MAC Reset
|
|
|
|
|
mac_interface_rrc::ue_rnti_t uernti;
|
|
|
|
|
rrc_ptr->mac->get_rntis(&uernti);
|
|
|
|
|
|
|
|
|
|
// If security is activated, RRC connected and C-RNTI available
|
|
|
|
|
if (rrc_ptr->security_is_activated && rrc_ptr->state == RRC_STATE_CONNECTED && uernti.crnti != 0) {
|
|
|
|
|
// Save reestablishment cause and current C-RNTI
|
|
|
|
|
reest_rnti = uernti.crnti;
|
|
|
|
|
reest_cause = cause;
|
|
|
|
|
reest_source_pci = rrc_ptr->serving_cell->get_pci(); // needed for reestablishment with another cell
|
|
|
|
|
|
|
|
|
|
// the initiation of reestablishment procedure as indicates in 3GPP 36.331 Section 5.3.7.2
|
|
|
|
|
// Cannot be called from here because it has PHY-MAC re-configuration that should be performed in a different thread
|
|
|
|
|
Info("Conditions are meet\n");
|
|
|
|
|
state = state_t::init;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// 3GPP 36.331 Section 5.3.7.1
|
|
|
|
|
// If AS security has not been activated, the UE does not initiate the procedure but instead
|
|
|
|
|
// moves to RRC_IDLE directly
|
|
|
|
|
Info("Conditions are NOT meet\n");
|
|
|
|
|
rrc_ptr->start_go_idle();
|
|
|
|
|
state = state_t::success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return proc_outcome_t::yield;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rrc::connection_reest_proc::step_init()
|
|
|
|
|
{
|
|
|
|
|
// initiation of reestablishment procedure as indicates in 3GPP 36.331 Section 5.3.7.2
|
|
|
|
|
Info("Initiating RRC Connection Reestablishment Procedure\n");
|
|
|
|
|
|
|
|
|
|
// stop timer T310, if running;
|
|
|
|
|
rrc_ptr->t310.stop();
|
|
|
|
|
|
|
|
|
|
// start timer T311;
|
|
|
|
|
rrc_ptr->t311.run();
|
|
|
|
|
|
|
|
|
|
// Suspend all RB except SRB0
|
|
|
|
|
for (int i = 1; i < SRSLTE_N_RADIO_BEARERS; i++) {
|
|
|
|
|
if (rrc_ptr->rlc->has_bearer(i)) {
|
|
|
|
|
rrc_ptr->rlc->suspend_bearer(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// reset MAC;
|
|
|
|
|
rrc_ptr->mac->reset();
|
|
|
|
|
|
|
|
|
|
// apply the default physical channel configuration as specified in 9.2.4;
|
|
|
|
|
rrc_ptr->set_phy_default_pucch_srs();
|
|
|
|
|
|
|
|
|
|
// apply the default semi-persistent scheduling configuration as specified in 9.2.3;
|
|
|
|
|
// N.A.
|
|
|
|
|
|
|
|
|
|
// apply the default MAC main configuration as specified in 9.2.2;
|
|
|
|
|
rrc_ptr->apply_mac_config_dedicated_default();
|
|
|
|
|
|
|
|
|
|
// Launch cell reselection
|
|
|
|
|
if (rrc_ptr->cell_reselector.launch()) {
|
|
|
|
|
state = state_t::cell_reselection;
|
|
|
|
|
} else {
|
|
|
|
|
Error("Failed to initiate a Cell re-selection procedure...\n");
|
|
|
|
|
state = state_t::error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rrc::connection_reest_proc::step_cell_reselection()
|
|
|
|
|
{
|
|
|
|
|
if (!rrc_ptr->t311.is_running()) {
|
|
|
|
|
Info("During cell reselection, T311 expired. Aborting.\n");
|
|
|
|
|
state = state_t::success;
|
|
|
|
|
} else if (rrc_ptr->cell_reselector.run()) {
|
|
|
|
|
// Keep running, do nothing
|
|
|
|
|
} else if (!rrc_ptr->serving_cell->in_sync) {
|
|
|
|
|
Info("Serving cell is out-of-sync, re-launching re-selection procedure\n");
|
|
|
|
|
if (rrc_ptr->cell_reselector.launch()) {
|
|
|
|
|
state = state_t::cell_reselection;
|
|
|
|
|
} else {
|
|
|
|
|
// Error launching procedure
|
|
|
|
|
state = state_t::error;
|
|
|
|
|
}
|
|
|
|
|
} else if (rrc_ptr->serving_cell->has_sib1() && rrc_ptr->serving_cell->has_sib2() &&
|
|
|
|
|
rrc_ptr->serving_cell->has_sib3()) {
|
|
|
|
|
Info("In-sync, SIBs available. Going to cell criteria\n");
|
|
|
|
|
state = state_t::cell_criteria;
|
|
|
|
|
} else {
|
|
|
|
|
Info("SIBs missing (%d, %d, %d), launching serving cell configuration procedure\n",
|
|
|
|
|
rrc_ptr->serving_cell->has_sib1(),
|
|
|
|
|
rrc_ptr->serving_cell->has_sib2(),
|
|
|
|
|
rrc_ptr->serving_cell->has_sib3());
|
|
|
|
|
std::vector<uint32_t> required_sibs = {1, 2, 3};
|
|
|
|
|
if (rrc_ptr->serv_cell_cfg.launch(required_sibs)) {
|
|
|
|
|
state = state_t::cell_configuration;
|
|
|
|
|
} else {
|
|
|
|
|
Error("Failed to initiate configure serving cell\n");
|
|
|
|
|
state = state_t::error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rrc::connection_reest_proc::step_cell_configuration()
|
|
|
|
|
{
|
|
|
|
|
if (!rrc_ptr->t311.is_running()) {
|
|
|
|
|
Info("During cell configuration, T311 expired. Aborting.\n");
|
|
|
|
|
state = state_t::success;
|
|
|
|
|
} else if (rrc_ptr->serv_cell_cfg.run()) {
|
|
|
|
|
// Keep running, do nothing
|
|
|
|
|
} else if (!rrc_ptr->serving_cell->in_sync) {
|
|
|
|
|
Info("Serving cell is out-of-sync, re-launching re-selection procedure\n");
|
|
|
|
|
if (rrc_ptr->cell_reselector.launch()) {
|
|
|
|
|
state = state_t::cell_reselection;
|
|
|
|
|
} else {
|
|
|
|
|
Error("Failed to initiate a Cell re-selection procedure...\n");
|
|
|
|
|
state = state_t::error;
|
|
|
|
|
}
|
|
|
|
|
} else if (rrc_ptr->serving_cell->has_sib1() && rrc_ptr->serving_cell->has_sib2() &&
|
|
|
|
|
rrc_ptr->serving_cell->has_sib3()) {
|
|
|
|
|
Info("SIBs available. Going to cell criteria\n");
|
|
|
|
|
state = state_t::cell_criteria;
|
|
|
|
|
} else {
|
|
|
|
|
Error("Failed to configure serving cell\n");
|
|
|
|
|
state = state_t::error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rrc::connection_reest_proc::step_cell_criteria()
|
|
|
|
|
{
|
|
|
|
|
// Wait until we're synced and have obtained SIBs
|
|
|
|
|
// Perform cell selection in accordance to 36.304
|
|
|
|
|
if (!rrc_ptr->t311.is_running()) {
|
|
|
|
|
Info("During cell selection criteria, T311 expired. Aborting.\n");
|
|
|
|
|
state = state_t::success;
|
|
|
|
|
} else if (rrc_ptr->cell_selection_criteria(rrc_ptr->serving_cell->get_rsrp())) {
|
|
|
|
|
// Actions following cell reselection while T311 is running 5.3.7.3
|
|
|
|
|
// Upon selecting a suitable E-UTRA cell, the UE shall:
|
|
|
|
|
Info("Cell Selection criteria passed after %dms. Sending RRC Connection Reestablishment Request\n",
|
|
|
|
|
rrc_ptr->t311.value());
|
|
|
|
|
|
|
|
|
|
// stop timer T311;
|
|
|
|
|
rrc_ptr->t311.stop();
|
|
|
|
|
|
|
|
|
|
// start timer T301;
|
|
|
|
|
rrc_ptr->t301.run();
|
|
|
|
|
|
|
|
|
|
// apply the timeAlignmentTimerCommon included in SystemInformationBlockType2;
|
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
|
|
// initiate transmission of the RRCConnectionReestablishmentRequest message in accordance with 5.3.7.4;
|
|
|
|
|
rrc_ptr->send_con_restablish_request(reest_cause, reest_rnti, reest_source_pci);
|
|
|
|
|
} else {
|
|
|
|
|
// Upon selecting an inter-RAT cell
|
|
|
|
|
Warning("Reestablishment Cell Selection criteria failed.\n");
|
|
|
|
|
rrc_ptr->leave_connected();
|
|
|
|
|
}
|
|
|
|
|
state = state_t::success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
proc_outcome_t rrc::connection_reest_proc::step()
|
|
|
|
|
{
|
|
|
|
|
proc_outcome_t proc_outcome = srslte::proc_outcome_t::yield;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Implementation of procedure in 3GPP 36.331 Section 5.3.7.3: Actions following cell selection while T311 is running
|
|
|
|
|
*/
|
|
|
|
|
switch (state) {
|
|
|
|
|
|
|
|
|
|
case state_t::init:
|
|
|
|
|
step_init();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case state_t::cell_reselection:
|
|
|
|
|
step_cell_reselection();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case state_t::cell_configuration:
|
|
|
|
|
step_cell_configuration();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case state_t::cell_criteria:
|
|
|
|
|
step_cell_criteria();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case state_t::success:
|
|
|
|
|
Info("Finished successfully\n");
|
|
|
|
|
proc_outcome = srslte::proc_outcome_t::success;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case state_t::error:
|
|
|
|
|
Info("Finished with error\n");
|
|
|
|
|
proc_outcome = srslte::proc_outcome_t::error;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return proc_outcome;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace srsue
|
|
|
|
|