diff --git a/lib/include/srsran/interfaces/enb_rrc_interfaces.h b/lib/include/srsran/interfaces/enb_rrc_interfaces.h index 85f961080..e1ac72d33 100644 --- a/lib/include/srsran/interfaces/enb_rrc_interfaces.h +++ b/lib/include/srsran/interfaces/enb_rrc_interfaces.h @@ -126,8 +126,15 @@ public: class rrc_nr_interface_rrc { public: - /// Request addition of NR carrier for UE (TODO: add configuration check, QCI, security, etc.) - virtual int sgnb_addition_request(uint16_t eutra_rnti) = 0; + struct sgnb_addition_req_params_t { + uint32_t eps_bearer_id; + // add configuration check + // E-RAB Parameters, Tunnel address (IP address, TEID) + // QCI, security, etc + }; + + /// Request addition of NR carrier for UE + virtual int sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) = 0; /// Provide information whether the requested configuration was applied successfully by the UE virtual int sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstring reconfig_response) = 0; @@ -137,16 +144,26 @@ public: class rrc_eutra_interface_rrc_nr { public: + /** + * @brief List of parameters included in the SgNB addition Ack message + * @param nr_secondary_cell_group_cfg_r15 Encoded part of the RRC Reconfiguration + * @param nr_radio_bearer_cfg1_r15 Encoded part of the RRC Reconfiguration + * @param eps_bearer_id ID of the transfered bearer + */ + struct sgnb_addition_ack_params_t { + uint16_t nr_rnti = SRSRAN_INVALID_RNTI; // RNTI that was assigned to the UE + asn1::dyn_octstring nr_secondary_cell_group_cfg_r15; + asn1::dyn_octstring nr_radio_bearer_cfg1_r15; + uint32_t eps_bearer_id = 0; // (list of) successfully transfered EPS bearers + }; + /** * @brief Signal successful addition of UE * * @param eutra_rnti The RNTI that the EUTRA RRC used to request the SgNB addition - * @param nr_secondary_cell_group_cfg_r15 Encoded part of the RRC Reconfiguration - * @param nr_radio_bearer_cfg1_r15 Encoded part of the RRC Reconfiguration + * @param params Parameter list */ - virtual void sgnb_addition_ack(uint16_t eutra_rnti, - const asn1::dyn_octstring& nr_secondary_cell_group_cfg_r15, - const asn1::dyn_octstring& nr_radio_bearer_cfg1_r15) = 0; + virtual void sgnb_addition_ack(uint16_t eutra_rnti, sgnb_addition_ack_params_t params) = 0; /** * @brief Signal unsuccessful SgNB addition @@ -158,9 +175,10 @@ public: /** * @brief Signal completion of SgNB addition after UE (with new NR identity) has attached * - * @param nr_rnti The RNTI that the EUTRA RRC used to request the SgNB addition + * @param eutra_rnti The RNTI that the EUTRA RRC used to request the SgNB addition + * @param nr_rnti The RNTI that has been assigned to the UE on the SgNB */ - virtual void sgnb_addition_complete(uint16_t eutra_rnti) = 0; + virtual void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) = 0; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index a9f038c12..332ef793e 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -127,11 +127,9 @@ public: int notify_ue_erab_updates(uint16_t rnti, srsran::const_byte_span nas_pdu) override; // rrc_eutra_interface_rrc_nr - void sgnb_addition_ack(uint16_t eutra_rnti, - const asn1::dyn_octstring& nr_secondary_cell_group_cfg_r15, - const asn1::dyn_octstring& nr_radio_bearer_cfg1_r15) override; + void sgnb_addition_ack(uint16_t eutra_rnti, const sgnb_addition_ack_params_t params) override; void sgnb_addition_reject(uint16_t eutra_rnti) override; - void sgnb_addition_complete(uint16_t eutra_rnti) override; + void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) override; // rrc_interface_pdcp void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override; diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index c33c9752c..842367d88 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -29,15 +29,23 @@ namespace srsenb { class rrc::ue::rrc_endc : public srsran::fsm_t { public: - // public events - struct user_crnti_upd_ev { - uint16_t crnti; - uint16_t temp_crnti; - }; - struct ho_cancel_ev { - asn1::s1ap::cause_c cause; + // public events called from EUTRA-RRC + struct sgnb_add_req_sent_ev {}; - ho_cancel_ev(const asn1::s1ap::cause_c& cause_) : cause(cause_) {} + /// called when 5G RRC accepted new user + struct sgnb_add_req_ack_ev { + sgnb_addition_ack_params_t params; + }; + + struct sgnb_add_req_reject_ev {}; + + /** + * @brief Non-standard event sent from NR-RRC to EUTRA when UE has attached to NR cell + * + * sent after Reconfig complete and contention resolution on NR side + */ + struct sgnb_add_complete_ev { + uint16_t nr_rnti; /// RNTI assigned to UE on NR carrier }; rrc_endc(srsenb::rrc::ue* outer_ue); @@ -45,17 +53,14 @@ public: bool fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg); void handle_eutra_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_caps); void handle_ue_meas_report(const asn1::rrc::meas_report_s& msg); - void handle_sgnb_addition_ack(const asn1::dyn_octstring& nr_secondary_cell_group_cfg_r15, - const asn1::dyn_octstring& nr_radio_bearer_cfg1_r15); - void handle_sgnb_addition_reject(); - void handle_sgnb_addition_complete(); + bool is_endc_supported(); private: // Send SgNB addition request to gNB bool start_sgnb_addition(); - bool is_endc_activation_running() const { return not is_in_state(); } + bool is_endc_activation_running() const { return not is_in_state(); } rrc::ue* rrc_ue = nullptr; rrc* rrc_enb = nullptr; @@ -65,51 +70,57 @@ private: bool endc_supported = false; asn1::rrc::rrc_conn_recfg_complete_s pending_recfg_complete; - // temporary storage for NR reconfiguration - asn1::dyn_octstring nr_secondary_cell_group_cfg_r15; - asn1::dyn_octstring nr_radio_bearer_cfg1_r15; + // fixed ENDC variables + const uint32_t eutra_drb_id = 1; // The DRB ID that converted to NR + const uint32_t lcid_drb_nr = 4; - // events - struct sgnb_add_req_sent_ev {}; - struct sgnb_add_req_ack_ev {}; - struct sgnb_add_req_reject_ev {}; + // internal events struct rrc_recfg_sent_ev {}; - struct prach_nr_received_ev {}; - - using recfg_complete_ev = asn1::rrc::rrc_conn_recfg_complete_s; - using status_transfer_ev = asn1::s1ap::bearers_subject_to_status_transfer_list_l; // states - struct idle_st {}; - struct wait_sgnb_add_req_resp {}; - struct prepare_recfg {}; - struct wait_recfg_comp {}; - struct wait_prach_nr {}; + struct endc_deactivated_st {}; // initial state where user is served over EUTRA only + struct wait_sgnb_add_req_resp_st {}; + struct prepare_recfg_st { + sgnb_addition_ack_params_t sgnb_config; // Store NR cell group config, etc. + + void enter(rrc_endc* f, const sgnb_add_req_ack_ev& ev); + + explicit prepare_recfg_st(rrc_endc* parent_); + + private: + srslog::basic_logger& logger; + }; + struct wait_add_complete_st {}; // user needs to complete RA procedure and send C-RNTI CE + struct endc_activated_st {}; // user has enabled EN-DC successfully and is currently served // FSM guards // FSM transition handlers - void handle_recfg_complete(wait_recfg_comp& s, const recfg_complete_ev& ev); - void handle_sgnb_addition_request_sent(const sgnb_add_req_sent_ev& ev); + void handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, const sgnb_add_req_ack_ev& ev); protected: // states - state_list - states{this, idle_st{}, wait_sgnb_add_req_resp{}, prepare_recfg{}, wait_recfg_comp{}, wait_prach_nr{}}; + state_list + states{this, + endc_deactivated_st{}, + wait_sgnb_add_req_resp_st{}, + prepare_recfg_st{this}, + wait_add_complete_st{}, + endc_activated_st{}}; // transitions using fsm = rrc_endc; // clang-format off - using transitions = transition_table< - // Start Target Event Action Guard - // +-----------------------+-----------------------+------------------------+----------------------------+-------------------------+ - row< idle_st, wait_sgnb_add_req_resp, sgnb_add_req_sent_ev, nullptr >, - // +-----------------------+-----------------------+------------------------+----------------------------+-------------------------+ - row< wait_sgnb_add_req_resp, prepare_recfg, sgnb_add_req_ack_ev >, - row< wait_sgnb_add_req_resp, idle_st, sgnb_add_req_reject_ev >, - row< prepare_recfg, wait_recfg_comp, rrc_recfg_sent_ev >, - row< wait_recfg_comp, idle_st, recfg_complete_ev, &fsm::handle_recfg_complete > - // +-----------------------+-----------------------+------------------------+----------------------------+-------------------------+ + using transitions = transition_table< + // Start Target Event Action Guard + // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ + row< endc_deactivated_st, wait_sgnb_add_req_resp_st, sgnb_add_req_sent_ev, nullptr >, + // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ + row< wait_sgnb_add_req_resp_st, prepare_recfg_st, sgnb_add_req_ack_ev, &fsm::handle_sgnb_add_req_ack >, + row< wait_sgnb_add_req_resp_st, endc_deactivated_st, sgnb_add_req_reject_ev >, + row< prepare_recfg_st, wait_add_complete_st, rrc_recfg_sent_ev >, + row< wait_add_complete_st, endc_activated_st, sgnb_add_complete_ev > + // +---------------------------+--------------------------+------------------------+------------------------------+-------------------------+ >; // clang-format on }; diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index e1b73269b..5b3200edc 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -81,7 +81,7 @@ public: void notify_pdcp_integrity_error(uint16_t rnti, uint32_t lcid) final; // Interface for EUTRA RRC - int sgnb_addition_request(uint16_t rnti); + int sgnb_addition_request(uint16_t rnti, const sgnb_addition_req_params_t& params); int sgnb_reconfiguration_complete(uint16_t rnti, asn1::dyn_octstring reconfig_response); // Interfaces for NGAP @@ -99,12 +99,14 @@ public: void send_connection_setup(); void send_dl_ccch(asn1::rrc_nr::dl_ccch_msg_s* dl_dcch_msg); - int handle_sgnb_addition_request(uint16_t eutra_rnti); + int handle_sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params); + void crnti_ce_received(); // getters bool is_connected() { return state == rrc_nr_state_t::RRC_CONNECTED; } bool is_idle() { return state == rrc_nr_state_t::RRC_IDLE; } bool is_inactive() { return state == rrc_nr_state_t::RRC_INACTIVE; } + bool is_endc() { return endc; } // setters @@ -129,6 +131,10 @@ public: asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg; const uint32_t drb1_lcid = 4; + + // NSA specific variables + bool endc = false; + uint16_t eutra_rnti = SRSRAN_INVALID_RNTI; }; private: diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index bc61d1bd5..0097f8aca 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -559,12 +559,10 @@ void rrc::set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_st EN-DC/NSA helper functions *******************************************************************************/ -void rrc::sgnb_addition_ack(uint16_t eutra_rnti, - const asn1::dyn_octstring& nr_secondary_cell_group_cfg_r15, - const asn1::dyn_octstring& nr_radio_bearer_cfg1_r15) +void rrc::sgnb_addition_ack(uint16_t eutra_rnti, sgnb_addition_ack_params_t params) { - users.at(eutra_rnti) - ->endc_handler->handle_sgnb_addition_ack(nr_secondary_cell_group_cfg_r15, nr_radio_bearer_cfg1_r15); + logger.info("Received SgNB addition acknowledgement for rnti=%d", eutra_rnti); + users.at(eutra_rnti)->endc_handler->trigger(ue::rrc_endc::sgnb_add_req_ack_ev{params}); // trigger RRC Reconfiguration to send NR config to UE users.at(eutra_rnti)->send_connection_reconf(); @@ -572,12 +570,14 @@ void rrc::sgnb_addition_ack(uint16_t eutra_rnti, void rrc::sgnb_addition_reject(uint16_t eutra_rnti) { - users.at(eutra_rnti)->endc_handler->handle_sgnb_addition_reject(); + logger.error("Received SgNB addition reject for rnti=%d", eutra_rnti); + users.at(eutra_rnti)->endc_handler->trigger(ue::rrc_endc::sgnb_add_req_reject_ev{}); } -void rrc::sgnb_addition_complete(uint16_t eutra_rnti) +void rrc::sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) { - users.at(eutra_rnti)->endc_handler->handle_sgnb_addition_complete(); + logger.info("User rnti=0x%x successfully enabled EN-DC", eutra_rnti); + users.at(eutra_rnti)->endc_handler->trigger(ue::rrc_endc::sgnb_add_complete_ev{nr_rnti}); } /******************************************************************************* diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index da4f2d883..4b16ca61b 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -124,7 +124,7 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn meas_cfg.meas_gap_cfg_present = true; meas_cfg.meas_gap_cfg.set_setup(); meas_cfg.meas_gap_cfg.setup().gap_offset.set_gp0() = 16; - } else if (is_in_state()) { + } else if (is_in_state()) { // FIXME: use bearer manager to remove EUTRA DRB conn_recfg->rr_cfg_ded.drb_to_release_list_present = true; conn_recfg->rr_cfg_ded.drb_to_release_list.resize(1); @@ -148,13 +148,14 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn reconf_v1510.nr_cfg_r15.setup().endc_release_and_add_r15 = false; reconf_v1510.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15_present = true; - reconf_v1510.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15 = nr_secondary_cell_group_cfg_r15; + reconf_v1510.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15 = + get_state()->sgnb_config.nr_secondary_cell_group_cfg_r15; reconf_v1510.sk_counter_r15_present = true; reconf_v1510.sk_counter_r15 = 0; reconf_v1510.nr_radio_bearer_cfg1_r15_present = true; - reconf_v1510.nr_radio_bearer_cfg1_r15 = nr_radio_bearer_cfg1_r15; + reconf_v1510.nr_radio_bearer_cfg1_r15 = get_state()->sgnb_config.nr_radio_bearer_cfg1_r15; // inform FSM rrc_recfg_sent_ev recfg_sent{}; @@ -225,7 +226,7 @@ void rrc::ue::rrc_endc::handle_ue_meas_report(const meas_report_s& msg) return; } - if (not is_in_state()) { + if (not is_in_state()) { Info("Received a MeasReport while already enabling ENDC support. Ignoring..."); return; } @@ -242,45 +243,48 @@ void rrc::ue::rrc_endc::handle_ue_meas_report(const meas_report_s& msg) return; } - // Start EN-DC activation + // Start EN-DC activation using EPS bearer of EUTRA DRB1 + rrc_nr_interface_rrc::sgnb_addition_req_params_t params = {}; + params.eps_bearer_id = + rrc_enb->bearer_manager.get_lcid_bearer(rrc_ue->rnti, drb_to_lcid((lte_drb)eutra_drb_id)).eps_bearer_id; logger.info("Triggering SgNB addition"); - rrc_enb->rrc_nr->sgnb_addition_request(rrc_ue->rnti); + rrc_enb->rrc_nr->sgnb_addition_request(rrc_ue->rnti, params); sgnb_add_req_sent_ev sgnb_add_req{}; trigger(sgnb_add_req); } -void rrc::ue::rrc_endc::handle_sgnb_addition_ack(const asn1::dyn_octstring& nr_secondary_cell_group_cfg_r15_, - const asn1::dyn_octstring& nr_radio_bearer_cfg1_r15_) +rrc::ue::rrc_endc::prepare_recfg_st::prepare_recfg_st(rrc_endc* parent_) : logger(parent_->logger) {} + +void rrc::ue::rrc_endc::prepare_recfg_st::enter(rrc_endc* f, const sgnb_add_req_ack_ev& ev) { - logger.info("Received SgNB addition acknowledgement for rnti=%d", rrc_ue->rnti); + // store SgNB provided config + sgnb_config = ev.params; - // store received configurations - nr_secondary_cell_group_cfg_r15 = nr_secondary_cell_group_cfg_r15_; - nr_radio_bearer_cfg1_r15 = nr_radio_bearer_cfg1_r15_; - - logger.debug(nr_secondary_cell_group_cfg_r15.data(), - nr_secondary_cell_group_cfg_r15.size(), + logger.debug(sgnb_config.nr_secondary_cell_group_cfg_r15.data(), + sgnb_config.nr_secondary_cell_group_cfg_r15.size(), "nr-SecondaryCellGroupConfig-r15:"); - logger.debug(nr_radio_bearer_cfg1_r15.data(), nr_radio_bearer_cfg1_r15.size(), "nr-RadioBearerConfig1-r15:"); - - sgnb_add_req_ack_ev sgnb_add_ack{}; - trigger(sgnb_add_ack); + logger.debug(sgnb_config.nr_radio_bearer_cfg1_r15.data(), + sgnb_config.nr_radio_bearer_cfg1_r15.size(), + "nr-RadioBearerConfig1-r15:"); } -void rrc::ue::rrc_endc::handle_sgnb_addition_reject() +// The gNB has accepted the SgNB addition and has already allocated the user and established all bearers +void rrc::ue::rrc_endc::handle_sgnb_add_req_ack(wait_sgnb_add_req_resp_st& s, const sgnb_add_req_ack_ev& ev) { - logger.error("Received SgNB addition reject for rnti=%d", rrc_ue->rnti); -} + // TODO: copy buffered PDCP data to SeNB -void rrc::ue::rrc_endc::handle_recfg_complete(wait_recfg_comp& s, const recfg_complete_ev& ev) -{ - logger.info("User rnti=0x%x successfully enabled EN-DC", rrc_ue->rnti); -} + // TODO: path update procedure with GTPU modify bearer request (for mode 3A and 3X) -void rrc::ue::rrc_endc::handle_sgnb_addition_complete() -{ - logger.info("Received SgNB addition complete for rnti=%d", rrc_ue->rnti); + // delete EPS bearer mapping over EUTRA PDCP + rrc_enb->bearer_manager.remove_eps_bearer(rrc_ue->rnti, ev.params.eps_bearer_id); + + // re-register EPS bearer over NR PDCP + rrc_enb->bearer_manager.add_eps_bearer( + ev.params.nr_rnti, ev.params.eps_bearer_id, srsran::srsran_rat_t::nr, lcid_drb_nr); + + // change GTPU tunnel RNTI to match NR RNTI + rrc_enb->gtpu->mod_bearer_rnti(rrc_ue->rnti, ev.params.nr_rnti); } bool rrc::ue::rrc_endc::is_endc_supported() diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 8a6623d13..1e8180951 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -186,11 +186,9 @@ int rrc_nr::update_user(uint16_t new_rnti, uint16_t old_rnti) } ue* ue_ptr = old_it->second.get(); - // Assume that SgNB addition is running logger.info("Resuming rnti=0x%x RRC connection due to received C-RNTI CE from rnti=0x%x.", old_rnti, new_rnti); - if (ue_ptr->is_connected()) { - rrc_eutra->sgnb_addition_complete(new_rnti); - } + ue_ptr->crnti_ce_received(); + return SRSRAN_SUCCESS; } @@ -404,9 +402,9 @@ void rrc_nr::write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {} Interface for EUTRA RRC *******************************************************************************/ -int rrc_nr::sgnb_addition_request(uint16_t eutra_rnti) +int rrc_nr::sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) { - task_sched.defer_task([this, eutra_rnti]() { + task_sched.defer_task([this, eutra_rnti, params]() { // try to allocate new user uint16_t nr_rnti = mac->reserve_rnti(0); if (nr_rnti == SRSRAN_INVALID_RNTI) { @@ -427,7 +425,7 @@ int rrc_nr::sgnb_addition_request(uint16_t eutra_rnti) logger.warning("Unrecognised rnti: 0x%x", nr_rnti); return; } - user_it->second->handle_sgnb_addition_request(eutra_rnti); + user_it->second->handle_sgnb_addition_request(eutra_rnti, params); }); // return straight away @@ -436,6 +434,8 @@ int rrc_nr::sgnb_addition_request(uint16_t eutra_rnti) int rrc_nr::sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstring reconfig_response) { + // user has completeted the reconfiguration and has acked on 4G side, wait until RA on NR + logger.info("Received Reconfiguration complete for RNTI=0x%x", eutra_rnti); return SRSRAN_SUCCESS; } @@ -1101,36 +1101,50 @@ int rrc_nr::ue::pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_beare return SRSRAN_SUCCESS; } -int rrc_nr::ue::handle_sgnb_addition_request(uint16_t eutra_rnti) +int rrc_nr::ue::handle_sgnb_addition_request(uint16_t eutra_rnti_, const sgnb_addition_req_params_t& req_params) { // Add DRB1 to RLC and PDCP if (add_drb() != SRSRAN_SUCCESS) { parent->logger.error("Failed to configure DRB"); - parent->rrc_eutra->sgnb_addition_reject(eutra_rnti); + parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); return SRSRAN_ERROR; } // provide hard-coded NR configs - asn1::dyn_octstring nr_secondary_cell_group_cfg; - if (pack_rrc_reconfiguraiton(nr_secondary_cell_group_cfg) == SRSRAN_ERROR) { + rrc_eutra_interface_rrc_nr::sgnb_addition_ack_params_t ack_params = {}; + if (pack_rrc_reconfiguraiton(ack_params.nr_secondary_cell_group_cfg_r15) == SRSRAN_ERROR) { parent->logger.error("Failed to pack RRC Reconfiguration. Sending SgNB addition reject."); - parent->rrc_eutra->sgnb_addition_reject(eutra_rnti); + parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); return SRSRAN_ERROR; } - asn1::dyn_octstring radio_bearer_config_buffer; - if (pack_nr_radio_bearer_config(radio_bearer_config_buffer) == SRSRAN_ERROR) { + if (pack_nr_radio_bearer_config(ack_params.nr_radio_bearer_cfg1_r15) == SRSRAN_ERROR) { parent->logger.error("Failed to pack NR radio bearer config. Sending SgNB addition reject."); - parent->rrc_eutra->sgnb_addition_reject(eutra_rnti); + parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); return SRSRAN_ERROR; } // send response to EUTRA - parent->rrc_eutra->sgnb_addition_ack(eutra_rnti, nr_secondary_cell_group_cfg, radio_bearer_config_buffer); + ack_params.nr_rnti = rnti; + ack_params.eps_bearer_id = req_params.eps_bearer_id; + parent->rrc_eutra->sgnb_addition_ack(eutra_rnti_, ack_params); + + // recognize RNTI as ENDC user + endc = true; + eutra_rnti = eutra_rnti_; return SRSRAN_SUCCESS; } +void rrc_nr::ue::crnti_ce_received() +{ + // Assume NSA mode active + if (endc) { + // send SgNB addition complete for ENDC users + parent->rrc_eutra->sgnb_addition_complete(eutra_rnti, rnti); + } +} + /** * @brief Set DRB configuration * diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 70dbb4d4f..b6510c7e7 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -396,7 +396,7 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) } else { parent->logger.warning("Received MeasReport but no mobility configuration is available"); } - if (endc_handler) { + if (endc_handler != nullptr) { endc_handler->handle_ue_meas_report(ul_dcch_msg.msg.c1().meas_report()); } break; @@ -1009,7 +1009,7 @@ int rrc::ue::handle_ue_cap_info(ue_cap_info_s* msg) parent->logger.info("UE rnti: 0x%x category: %d", rnti, eutra_capabilities.ue_category); - if (endc_handler) { + if (endc_handler != nullptr) { endc_handler->handle_eutra_capabilities(eutra_capabilities); } }