mirror of https://github.com/PentHertz/srsLTE.git
SRSUE: Refactored/Fixed RRC connection Re-establishment and minor CLang Format/Tidy fixes
This commit is contained in:
parent
36c45c7d64
commit
f37a096f10
|
@ -118,20 +118,18 @@ class cell_t
|
||||||
}
|
}
|
||||||
|
|
||||||
cell_t() {
|
cell_t() {
|
||||||
phy_interface_rrc_lte::phy_cell_t tmp;
|
phy_interface_rrc_lte::phy_cell_t tmp = {};
|
||||||
ZERO_OBJECT(tmp);
|
|
||||||
ZERO_OBJECT(phy_cell);
|
|
||||||
cell_t(tmp, 0);
|
cell_t(tmp, 0);
|
||||||
}
|
}
|
||||||
cell_t(phy_interface_rrc_lte::phy_cell_t phy_cell, float rsrp)
|
cell_t(phy_interface_rrc_lte::phy_cell_t phy_cell, float rsrp_)
|
||||||
{
|
{
|
||||||
gettimeofday(&last_update, NULL);
|
gettimeofday(&last_update, nullptr);
|
||||||
this->has_valid_sib1 = false;
|
this->has_valid_sib1 = false;
|
||||||
this->has_valid_sib2 = false;
|
this->has_valid_sib2 = false;
|
||||||
this->has_valid_sib3 = false;
|
this->has_valid_sib3 = false;
|
||||||
this->has_valid_sib13 = false;
|
this->has_valid_sib13 = false;
|
||||||
this->phy_cell = phy_cell;
|
this->phy_cell = phy_cell;
|
||||||
this->rsrp = rsrp;
|
rsrp = rsrp_;
|
||||||
in_sync = true;
|
in_sync = true;
|
||||||
bzero(&sib1, sizeof(sib1));
|
bzero(&sib1, sizeof(sib1));
|
||||||
bzero(&sib2, sizeof(sib2));
|
bzero(&sib2, sizeof(sib2));
|
||||||
|
@ -147,12 +145,13 @@ class cell_t
|
||||||
return phy_cell.cell.id;
|
return phy_cell.cell.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_rsrp(float rsrp) {
|
void set_rsrp(float rsrp_)
|
||||||
if (!std::isnan(rsrp)) {
|
{
|
||||||
this->rsrp = rsrp;
|
if (!std::isnan(rsrp_)) {
|
||||||
|
rsrp = rsrp_;
|
||||||
}
|
}
|
||||||
in_sync = true;
|
in_sync = true;
|
||||||
gettimeofday(&last_update, NULL);
|
gettimeofday(&last_update, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_rsrp() {
|
float get_rsrp() {
|
||||||
|
@ -262,24 +261,24 @@ class cell_t
|
||||||
return std::string{buf};
|
return std::string{buf};
|
||||||
}
|
}
|
||||||
|
|
||||||
phy_interface_rrc_lte::phy_cell_t phy_cell;
|
phy_interface_rrc_lte::phy_cell_t phy_cell = {};
|
||||||
bool in_sync;
|
bool in_sync = false;
|
||||||
bool has_mcch;
|
bool has_mcch = false;
|
||||||
asn1::rrc::sib_type1_s sib1;
|
asn1::rrc::sib_type1_s sib1;
|
||||||
asn1::rrc::sib_type2_s sib2;
|
asn1::rrc::sib_type2_s sib2;
|
||||||
asn1::rrc::sib_type3_s sib3;
|
asn1::rrc::sib_type3_s sib3;
|
||||||
asn1::rrc::sib_type13_r9_s sib13;
|
asn1::rrc::sib_type13_r9_s sib13;
|
||||||
asn1::rrc::mcch_msg_s mcch;
|
asn1::rrc::mcch_msg_s mcch;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float rsrp;
|
float rsrp = NAN;
|
||||||
|
|
||||||
struct timeval last_update;
|
|
||||||
|
|
||||||
bool has_valid_sib1;
|
struct timeval last_update = {};
|
||||||
bool has_valid_sib2;
|
|
||||||
bool has_valid_sib3;
|
bool has_valid_sib1 = false;
|
||||||
bool has_valid_sib13;
|
bool has_valid_sib2 = false;
|
||||||
|
bool has_valid_sib3 = false;
|
||||||
|
bool has_valid_sib13 = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class rrc : public rrc_interface_nas,
|
class rrc : public rrc_interface_nas,
|
||||||
|
@ -417,8 +416,8 @@ private:
|
||||||
|
|
||||||
// RRC constants and timers
|
// RRC constants and timers
|
||||||
srslte::timer_handler* timers = nullptr;
|
srslte::timer_handler* timers = nullptr;
|
||||||
uint32_t n310_cnt, N310 = 0;
|
uint32_t n310_cnt = 0, N310 = 0;
|
||||||
uint32_t n311_cnt, N311 = 0;
|
uint32_t n311_cnt = 0, N311 = 0;
|
||||||
srslte::timer_handler::unique_timer t300, t301, t302, t310, t311, t304;
|
srslte::timer_handler::unique_timer t300, t301, t302, t310, t311, t304;
|
||||||
|
|
||||||
// Radio bearers
|
// Radio bearers
|
||||||
|
@ -470,12 +469,8 @@ private:
|
||||||
void delete_last_neighbour();
|
void delete_last_neighbour();
|
||||||
std::string print_neighbour_cells();
|
std::string print_neighbour_cells();
|
||||||
|
|
||||||
bool initiated = false;
|
bool initiated = false;
|
||||||
asn1::rrc::reest_cause_e m_reest_cause = asn1::rrc::reest_cause_e::nulltype;
|
bool reestablishment_successful = false;
|
||||||
uint16_t m_reest_rnti = 0;
|
|
||||||
uint16_t m_reest_source_pci = 0;
|
|
||||||
bool reestablishment_started = false;
|
|
||||||
bool reestablishment_successful = false;
|
|
||||||
|
|
||||||
// Measurements sub-class
|
// Measurements sub-class
|
||||||
class rrc_meas
|
class rrc_meas
|
||||||
|
@ -621,15 +616,17 @@ private:
|
||||||
class process_pcch_proc;
|
class process_pcch_proc;
|
||||||
class go_idle_proc;
|
class go_idle_proc;
|
||||||
class cell_reselection_proc;
|
class cell_reselection_proc;
|
||||||
|
class connection_reest_proc;
|
||||||
srslte::proc_t<cell_search_proc, phy_interface_rrc_lte::cell_search_ret_t> cell_searcher;
|
srslte::proc_t<cell_search_proc, phy_interface_rrc_lte::cell_search_ret_t> cell_searcher;
|
||||||
srslte::proc_t<si_acquire_proc> si_acquirer;
|
srslte::proc_t<si_acquire_proc> si_acquirer;
|
||||||
srslte::proc_t<serving_cell_config_proc> serv_cell_cfg;
|
srslte::proc_t<serving_cell_config_proc> serv_cell_cfg;
|
||||||
srslte::proc_t<cell_selection_proc, cs_result_t> cell_selector;
|
srslte::proc_t<cell_selection_proc, cs_result_t> cell_selector;
|
||||||
srslte::proc_t<go_idle_proc> idle_setter;
|
srslte::proc_t<go_idle_proc> idle_setter;
|
||||||
srslte::proc_t<process_pcch_proc> pcch_processor;
|
srslte::proc_t<process_pcch_proc> pcch_processor;
|
||||||
srslte::proc_t<connection_request_proc> conn_req_proc;
|
srslte::proc_t<connection_request_proc> conn_req_proc;
|
||||||
srslte::proc_t<plmn_search_proc> plmn_searcher;
|
srslte::proc_t<plmn_search_proc> plmn_searcher;
|
||||||
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_manager_list_t callback_list;
|
srslte::proc_manager_list_t callback_list;
|
||||||
|
|
||||||
|
@ -647,7 +644,7 @@ private:
|
||||||
|
|
||||||
// Senders
|
// Senders
|
||||||
void send_con_request(srslte::establishment_cause_t cause);
|
void send_con_request(srslte::establishment_cause_t cause);
|
||||||
void send_con_restablish_request();
|
void send_con_restablish_request(asn1::rrc::reest_cause_e cause, uint16_t rnti, uint16_t pci);
|
||||||
void send_con_restablish_complete();
|
void send_con_restablish_complete();
|
||||||
void send_con_setup_complete(srslte::unique_byte_buffer_t nas_msg);
|
void send_con_setup_complete(srslte::unique_byte_buffer_t nas_msg);
|
||||||
void send_ul_info_transfer(srslte::unique_byte_buffer_t nas_msg);
|
void send_ul_info_transfer(srslte::unique_byte_buffer_t nas_msg);
|
||||||
|
@ -674,8 +671,7 @@ private:
|
||||||
void radio_link_failure();
|
void radio_link_failure();
|
||||||
void leave_connected();
|
void leave_connected();
|
||||||
void stop_timers();
|
void stop_timers();
|
||||||
void init_con_restablish_request(asn1::rrc::reest_cause_e cause);
|
void start_con_restablishment(asn1::rrc::reest_cause_e cause);
|
||||||
void proc_con_restablish_request();
|
|
||||||
void start_cell_reselection();
|
void start_cell_reselection();
|
||||||
|
|
||||||
void log_rr_config_common();
|
void log_rr_config_common();
|
||||||
|
|
|
@ -230,6 +230,28 @@ private:
|
||||||
srslte::proc_future_t<cs_result_t> cell_selection_fut;
|
srslte::proc_future_t<cs_result_t> cell_selection_fut;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class rrc::connection_reest_proc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit connection_reest_proc(rrc* rrc_);
|
||||||
|
srslte::proc_outcome_t init(asn1::rrc::reest_cause_e cause);
|
||||||
|
srslte::proc_outcome_t step();
|
||||||
|
static const char* name() { return "Connection re-establishment"; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum class state_t { init, cell_reselection, cell_configuration, cell_criteria, success, error } state;
|
||||||
|
|
||||||
|
rrc* rrc_ptr = nullptr;
|
||||||
|
asn1::rrc::reest_cause_e reest_cause = asn1::rrc::reest_cause_e::nulltype;
|
||||||
|
uint16_t reest_rnti = 0;
|
||||||
|
uint16_t reest_source_pci = 0;
|
||||||
|
|
||||||
|
void step_init();
|
||||||
|
void step_cell_reselection();
|
||||||
|
void step_cell_configuration();
|
||||||
|
void step_cell_criteria();
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace srsue
|
} // namespace srsue
|
||||||
|
|
||||||
#endif // SRSLTE_RRC_PROCEDURES_H
|
#endif // SRSLTE_RRC_PROCEDURES_H
|
||||||
|
|
|
@ -62,13 +62,13 @@ rrc::rrc(srslte::log* rrc_log_) :
|
||||||
conn_req_proc(this),
|
conn_req_proc(this),
|
||||||
plmn_searcher(this),
|
plmn_searcher(this),
|
||||||
cell_reselector(this),
|
cell_reselector(this),
|
||||||
|
connection_reest(this),
|
||||||
serving_cell(unique_cell_t(new cell_t({}, 0.0)))
|
serving_cell(unique_cell_t(new cell_t({}, 0.0)))
|
||||||
{
|
{
|
||||||
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
rrc::~rrc()
|
rrc::~rrc() = default;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void srslte_rrc_handler(asn1::srsasn_logger_level_t level, void* ctx, const char* str)
|
static void srslte_rrc_handler(asn1::srsasn_logger_level_t level, void* ctx, const char* str)
|
||||||
{
|
{
|
||||||
|
@ -233,10 +233,6 @@ void rrc::run_tti(uint32_t tti)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RRC_STATE_CONNECTED:
|
case RRC_STATE_CONNECTED:
|
||||||
// Performing reestablishment cell selection
|
|
||||||
if (m_reest_cause != asn1::rrc::reest_cause_e::nulltype) {
|
|
||||||
proc_con_restablish_request();
|
|
||||||
}
|
|
||||||
measurements.run_tti(tti);
|
measurements.run_tti(tti);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -792,7 +788,7 @@ void rrc::radio_link_failure() {
|
||||||
rrc_log->warning("Detected Radio-Link Failure\n");
|
rrc_log->warning("Detected Radio-Link Failure\n");
|
||||||
rrc_log->console("Warning: Detected Radio-Link Failure\n");
|
rrc_log->console("Warning: Detected Radio-Link Failure\n");
|
||||||
if (state == RRC_STATE_CONNECTED) {
|
if (state == RRC_STATE_CONNECTED) {
|
||||||
init_con_restablish_request(asn1::rrc::reest_cause_e::other_fail);
|
start_con_restablishment(asn1::rrc::reest_cause_e::other_fail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -882,15 +878,11 @@ void rrc::send_con_request(srslte::establishment_cause_t cause)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RRC connection re-establishment procedure (5.3.7.4) */
|
/* RRC connection re-establishment procedure (5.3.7.4) */
|
||||||
void rrc::send_con_restablish_request()
|
void rrc::send_con_restablish_request(asn1::rrc::reest_cause_e cause, uint16_t crnti, uint16_t pci)
|
||||||
{
|
{
|
||||||
uint16_t crnti;
|
|
||||||
uint16_t pci;
|
|
||||||
uint32_t cellid;
|
uint32_t cellid;
|
||||||
|
|
||||||
// Clean reestablishment type
|
// Clean reestablishment type
|
||||||
asn1::rrc::reest_cause_e cause = m_reest_cause;
|
|
||||||
m_reest_cause = asn1::rrc::reest_cause_e::nulltype;
|
|
||||||
reestablishment_successful = false;
|
reestablishment_successful = false;
|
||||||
|
|
||||||
if (cause == asn1::rrc::reest_cause_e::ho_fail) {
|
if (cause == asn1::rrc::reest_cause_e::ho_fail) {
|
||||||
|
@ -899,11 +891,8 @@ void rrc::send_con_restablish_request()
|
||||||
cellid = ho_src_cell.get_cell_id();
|
cellid = ho_src_cell.get_cell_id();
|
||||||
} else if (cause == asn1::rrc::reest_cause_e::other_fail) {
|
} else if (cause == asn1::rrc::reest_cause_e::other_fail) {
|
||||||
// use source PCI after RLF
|
// use source PCI after RLF
|
||||||
crnti = m_reest_rnti;
|
|
||||||
pci = m_reest_source_pci;
|
|
||||||
cellid = serving_cell->get_cell_id();
|
cellid = serving_cell->get_cell_id();
|
||||||
} else {
|
} else {
|
||||||
crnti = m_reest_rnti;
|
|
||||||
pci = serving_cell->get_pci();
|
pci = serving_cell->get_pci();
|
||||||
cellid = serving_cell->get_cell_id();
|
cellid = serving_cell->get_cell_id();
|
||||||
}
|
}
|
||||||
|
@ -1264,7 +1253,7 @@ bool rrc::con_reconfig(asn1::rrc::rrc_conn_recfg_s* reconfig)
|
||||||
// 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()
|
||||||
{
|
{
|
||||||
init_con_restablish_request(asn1::rrc::reest_cause_e::ho_fail);
|
start_con_restablishment(asn1::rrc::reest_cause_e::ho_fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reconfiguration failure or Section 5.3.5.5
|
// Reconfiguration failure or Section 5.3.5.5
|
||||||
|
@ -1280,7 +1269,7 @@ void rrc::con_reconfig_failed()
|
||||||
|
|
||||||
if (security_is_activated) {
|
if (security_is_activated) {
|
||||||
// Start the Reestablishment Procedure
|
// Start the Reestablishment Procedure
|
||||||
init_con_restablish_request(asn1::rrc::reest_cause_e::recfg_fail);
|
start_con_restablishment(asn1::rrc::reest_cause_e::recfg_fail);
|
||||||
} else {
|
} else {
|
||||||
start_go_idle();
|
start_go_idle();
|
||||||
}
|
}
|
||||||
|
@ -1315,7 +1304,6 @@ void rrc::leave_connected()
|
||||||
{
|
{
|
||||||
rrc_log->console("RRC IDLE\n");
|
rrc_log->console("RRC IDLE\n");
|
||||||
rrc_log->info("Leaving RRC_CONNECTED state\n");
|
rrc_log->info("Leaving RRC_CONNECTED state\n");
|
||||||
m_reest_cause = asn1::rrc::reest_cause_e::nulltype;
|
|
||||||
state = RRC_STATE_IDLE;
|
state = RRC_STATE_IDLE;
|
||||||
drb_up = false;
|
drb_up = false;
|
||||||
security_is_activated = false;
|
security_is_activated = false;
|
||||||
|
@ -1357,108 +1345,13 @@ void rrc::stop_timers()
|
||||||
*
|
*
|
||||||
* The parameter cause shall indicate the cause of the reestablishment according to the sections mentioned adobe.
|
* The parameter cause shall indicate the cause of the reestablishment according to the sections mentioned adobe.
|
||||||
*/
|
*/
|
||||||
void rrc::init_con_restablish_request(asn1::rrc::reest_cause_e cause)
|
void rrc::start_con_restablishment(asn1::rrc::reest_cause_e cause)
|
||||||
{
|
{
|
||||||
// Save Current RNTI before MAC Reset
|
if (not connection_reest.launch(cause)) {
|
||||||
mac_interface_rrc::ue_rnti_t uernti;
|
rrc_log->info("Failed to launch connection re-establishment pocedure\n");
|
||||||
mac->get_rntis(&uernti);
|
|
||||||
|
|
||||||
// If security is activated, RRC connected and C-RNTI available
|
|
||||||
if (security_is_activated && state == RRC_STATE_CONNECTED && uernti.crnti != 0) {
|
|
||||||
// Save reestablishment cause and current C-RNTI
|
|
||||||
m_reest_rnti = uernti.crnti;
|
|
||||||
m_reest_cause = cause;
|
|
||||||
m_reest_source_pci = serving_cell->get_pci(); // needed for reestablishment with another cell
|
|
||||||
|
|
||||||
reestablishment_started = false;
|
|
||||||
|
|
||||||
// initiation of reestablishment procedure as indicates in 3GPP 36.331 Section 5.3.7.2
|
|
||||||
rrc_log->info("Initiating RRC Connection Reestablishment Procedure\n");
|
|
||||||
} 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
|
|
||||||
start_go_idle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Implementation of procedure in 3GPP 36.331 Section 5.3.7.3: Actions following cell selection while T311 is running
|
|
||||||
*/
|
|
||||||
void rrc::proc_con_restablish_request()
|
|
||||||
{
|
|
||||||
if (!reestablishment_started) {
|
|
||||||
|
|
||||||
reestablishment_started = true;
|
|
||||||
|
|
||||||
rrc_log->info("Resetting timers and MAC in RRC Connection Reestablishment Procedure\n");
|
|
||||||
|
|
||||||
// stop timer T310, if running;
|
|
||||||
t310.stop();
|
|
||||||
|
|
||||||
// start timer T311;
|
|
||||||
t311.run();
|
|
||||||
|
|
||||||
// Suspend all RB except SRB0
|
|
||||||
for (int i = 1; i < SRSLTE_N_RADIO_BEARERS; i++) {
|
|
||||||
if (rlc->has_bearer(i)) {
|
|
||||||
rlc->suspend_bearer(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset MAC;
|
|
||||||
mac->reset();
|
|
||||||
|
|
||||||
// apply the default physical channel configuration as specified in 9.2.4;
|
|
||||||
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;
|
|
||||||
apply_mac_config_dedicated_default();
|
|
||||||
|
|
||||||
// perform cell selection in accordance with the cell selection process as specified in TS 36.304 [4];
|
|
||||||
start_cell_reselection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check timer...
|
callback_list.add_proc(connection_reest);
|
||||||
if (t311.is_running()) {
|
|
||||||
// Wait until we're synced and have obtained SIBs
|
|
||||||
if (serving_cell->in_sync && serving_cell->has_sib1() && serving_cell->has_sib2() && serving_cell->has_sib3()) {
|
|
||||||
// Perform cell selection in accordance to 36.304
|
|
||||||
if (cell_selection_criteria(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:
|
|
||||||
rrc_log->info("Cell Selection criteria passed after %dms. Sending RRC Connection Reestablishment Request\n",
|
|
||||||
t311.value());
|
|
||||||
|
|
||||||
// stop timer T311;
|
|
||||||
t311.stop();
|
|
||||||
|
|
||||||
// start timer T301;
|
|
||||||
t301.run();
|
|
||||||
|
|
||||||
// apply the timeAlignmentTimerCommon included in SystemInformationBlockType2;
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
// initiate transmission of the RRCConnectionReestablishmentRequest message in accordance with 5.3.7.4;
|
|
||||||
send_con_restablish_request();
|
|
||||||
} else {
|
|
||||||
// Upon selecting an inter-RAT cell
|
|
||||||
rrc_log->warning("Reestablishment Cell Selection criteria failed.\n");
|
|
||||||
rrc_log->console("Reestablishment Cell Selection criteria failed (rsrp=%.2f)\n",
|
|
||||||
serving_cell->get_rsrp());
|
|
||||||
leave_connected();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No synchronized, do nothing
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// t311 expired or stopped
|
|
||||||
rrc_log->info("T311 expired while selecting cell. Going to IDLE\n");
|
|
||||||
rrc_log->console("T311 expired while selecting cell. Going to IDLE\n");
|
|
||||||
leave_connected();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rrc::start_cell_reselection()
|
void rrc::start_cell_reselection()
|
||||||
|
|
|
@ -869,4 +869,211 @@ proc_outcome_t rrc::cell_reselection_proc::step()
|
||||||
return srslte::proc_outcome_t::success;
|
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
|
} // namespace srsue
|
||||||
|
|
Loading…
Reference in New Issue