diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index b06a4e4ad..a56d6df72 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -262,13 +262,17 @@ class rrc::connection_reest_proc public: struct t311_expiry {}; struct serv_cell_cfg_completed {}; + struct t301_expiry {}; explicit connection_reest_proc(rrc* rrc_); srslte::proc_outcome_t init(asn1::rrc::reest_cause_e cause); - srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; } + srslte::proc_outcome_t step(); srslte::proc_outcome_t react(const t311_expiry& ev); srslte::proc_outcome_t react(const cell_selection_proc::cell_selection_complete_ev& e); srslte::proc_outcome_t react(const serv_cell_cfg_completed& result); + srslte::proc_outcome_t react(const asn1::rrc::rrc_conn_reest_s& reest_msg); + srslte::proc_outcome_t react(const t301_expiry& ev); + srslte::proc_outcome_t react(const asn1::rrc::rrc_conn_reject_s& reest_msg); static const char* name() { return "Connection re-establishment"; } uint32_t get_source_earfcn() const { return reest_source_freq; } diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 87b449f52..a6bfd3de2 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -670,7 +670,7 @@ void rrc::timer_expired(uint32_t timeout_id) rrc_log->info("Timer T301 expired: Already in IDLE.\n"); } else { rrc_log->info("Timer T301 expired: Going to RRC IDLE\n"); - start_go_idle(); + connection_reest.trigger(connection_reest_proc::t301_expiry{}); } } else if (timeout_id == t302.id()) { rrc_log->info("Timer T302 expired. Informing NAS about barrier alleviation\n"); @@ -821,6 +821,8 @@ void rrc::send_con_restablish_complete() ul_dcch_msg.msg.c1().rrc_conn_reest_complete().rrc_transaction_id = transaction_id; send_ul_dcch_msg(RB_ID_SRB1, ul_dcch_msg); + + reestablishment_successful = true; } void rrc::send_con_setup_complete(srslte::unique_byte_buffer_t nas_msg) @@ -1558,8 +1560,7 @@ void rrc::parse_dl_ccch(unique_byte_buffer_t pdu) } /* Reception of RRCConnectionReestablishmentReject 5.3.7.8 */ case dl_ccch_msg_type_c::c1_c_::types::rrc_conn_reest_reject: - rrc_log->console("Reestablishment Reject\n"); - start_go_idle(); + connection_reest.trigger(c1->rrc_conn_reject()); break; default: rrc_log->error("The provided DL-CCCH message type is not recognized\n"); @@ -2348,30 +2349,7 @@ void rrc::handle_con_setup(const rrc_conn_setup_s& setup) /* Reception of RRCConnectionReestablishment by the UE 5.3.7.5 */ void rrc::handle_con_reest(const rrc_conn_reest_s& reest) { - t301.stop(); - - // Reestablish PDCP and RLC for SRB1 - pdcp->reestablish(1); - rlc->reestablish(1); - - // Update RRC Integrity keys - int ncc = reest.crit_exts.c1().rrc_conn_reest_r8().next_hop_chaining_count; - usim->generate_as_keys_ho(meas_cells.serving_cell().get_pci(), meas_cells.serving_cell().get_earfcn(), ncc, &sec_cfg); - pdcp->config_security_all(sec_cfg); - - // Apply the Radio Resource configuration - apply_rr_config_dedicated(&reest.crit_exts.c1().rrc_conn_reest_r8().rr_cfg_ded); - - // Resume SRB1 - rlc->resume_bearer(1); - - // perform the measurement related actions as specified in 5.5.6.1; - measurements->ho_reest_actions(get_serving_cell()->get_earfcn(), get_serving_cell()->get_earfcn()); - - // Send ConnectionSetupComplete message - send_con_restablish_complete(); - - reestablishment_successful = true; + connection_reest.trigger(reest); } void rrc::add_srb(const srb_to_add_mod_s& srb_cnfg) diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 8ae036567..ef67bed56 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -1260,7 +1260,7 @@ srslte::proc_outcome_t rrc::connection_reest_proc::cell_criteria() rrc_ptr->send_con_restablish_request(reest_cause, reest_rnti, reest_source_pci); state = state_t::wait_reest_msg; - return proc_outcome_t::success; + return proc_outcome_t::yield; } srslte::proc_outcome_t rrc::connection_reest_proc::start_cell_selection() @@ -1312,11 +1312,91 @@ rrc::connection_reest_proc::react(const cell_selection_proc::cell_selection_comp return cell_criteria(); } +// 5.3.7.5 - Reception of the RRCConnectionReestablishment by the UE +srslte::proc_outcome_t rrc::connection_reest_proc::react(const asn1::rrc::rrc_conn_reest_s& reest_msg) +{ + // 1> stop timer T301; + rrc_ptr->t301.stop(); + + // 1> re-establish PDCP for SRB1; + rrc_ptr->pdcp->reestablish(1); + + // 1> re-establish RLC for SRB1; + rrc_ptr->rlc->reestablish(1); + + // 1> perform the radio resource configuration procedure in accordance with the received + // radioResourceConfigDedicated and as specified in 5.3.10; + rrc_ptr->apply_rr_config_dedicated(&reest_msg.crit_exts.c1().rrc_conn_reest_r8().rr_cfg_ded); + + // 1> Resume SRB1; + rrc_ptr->rlc->resume_bearer(1); + + // 1> update the KeNB key based on the KASME key to which the current KeNB is associated, + // using the nextHopChainingCount value indicated in the RRCConnectionReestablishment message, + // as specified in TS 33.401 [32]; + // 1> store the nextHopChainingCount value; + // 1> derive the KRRCint key associated with the previously configured integrity algorithm, as specified in + // TS 33.401 [32]; + // 1> derive the KRRCenc key and the KUPenc key associated with the previously configured ciphering algorithm, + // as specified in TS 33.401 [32]; + int ncc = reest_msg.crit_exts.c1().rrc_conn_reest_r8().next_hop_chaining_count; + rrc_ptr->usim->generate_as_keys_ho(rrc_ptr->meas_cells.serving_cell().get_pci(), + rrc_ptr->meas_cells.serving_cell().get_earfcn(), + ncc, + &rrc_ptr->sec_cfg); + + // 1> configure lower layers to activate integrity protection using the previously configured algorithm and the + // KRRCint key immediately + // 1> configure lower layers to apply ciphering using the previously configured algorithm, the KRRCenc key and the + // KUPenc key immediately + rrc_ptr->pdcp->config_security_all(rrc_ptr->sec_cfg); + + // 1> perform the measurement related actions as specified in 5.5.6.1; + rrc_ptr->measurements->ho_reest_actions(rrc_ptr->get_serving_cell()->get_earfcn(), + rrc_ptr->get_serving_cell()->get_earfcn()); + + // 1> submit the RRCConnectionReestablishmentComplete message to lower layers for transmission, upon which the + // procedure ends; + rrc_ptr->send_con_restablish_complete(); + + Info("Finished successfully\n"); + return proc_outcome_t::success; +} + +// 5.3.7.7 - T301 expiry or selected cell no longer suitable +srslte::proc_outcome_t rrc::connection_reest_proc::react(const t301_expiry& ev) +{ + Info("Timer T301 expired: Going to RRC IDLE\n"); + rrc_ptr->rrc_log->console("Timer T301 expired: Going to RRC IDLE\n"); + rrc_ptr->start_go_idle(); + + return proc_outcome_t::error; +} +srslte::proc_outcome_t rrc::connection_reest_proc::step() +{ + if (rrc_ptr->t301.is_running() and not passes_cell_criteria()) { + Info("Selected cell no longer suitable: Going to RRC IDLE\n"); + rrc_ptr->rrc_log->console("Selected cell no longer suitable: Going to RRC IDLE\n"); + rrc_ptr->start_go_idle(); + return proc_outcome_t::error; + } + return proc_outcome_t::yield; +} + +// 5.3.7.8 - Reception of RRCConnectionReestablishmentReject by the UE +srslte::proc_outcome_t rrc::connection_reest_proc::react(const asn1::rrc::rrc_conn_reject_s& reject_msg) +{ + rrc_ptr->rrc_log->console("Reestablishment Reject. Going to RRC IDLE\n"); + rrc_ptr->t301.stop(); + rrc_ptr->start_go_idle(); + return proc_outcome_t::error; +} + // 5.3.7.6 - T311 expiry srslte::proc_outcome_t rrc::connection_reest_proc::react(const t311_expiry& ev) { // Abort procedure if T311 expires - Info("T311 expired during cell configuration. Going to RRC idle\n"); + Info("T311 expired during cell configuration. Going to RRC IDLE\n"); rrc_ptr->start_go_idle(); return proc_outcome_t::error; }