From f9a2850d74f9e92b9111d4d2ead6657ed6684045 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 23 Nov 2021 16:46:36 +0000 Subject: [PATCH] gnb,ngap: Added interface so the NGAP can pass a NAS message to the RRC upon starting the RRC Security Mode command. This allows the gNB to pass this message only after the SM procedure is complete. Also made sure that the RRC notifies the NGAP upon the end of the reconfiguration procedure, to make sure that the NGAP sends the UE context setup response. --- lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h | 10 +++++----- srsgnb/hdr/stack/rrc/rrc_nr.h | 2 +- srsgnb/hdr/stack/rrc/rrc_nr_ue.h | 2 +- srsgnb/src/stack/ngap/ngap_ue_proc.cc | 10 ++++++---- srsgnb/src/stack/ngap/test/ngap_test.cc | 5 +++-- srsgnb/src/stack/rrc/rrc_nr.cc | 4 ++-- srsgnb/src/stack/rrc/rrc_nr_ue.cc | 10 +++++++++- srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc | 2 +- 8 files changed, 28 insertions(+), 17 deletions(-) diff --git a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h index 20c00d21d..f2b8867f6 100644 --- a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h @@ -24,12 +24,12 @@ public: virtual int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) = 0; virtual int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) = 0; virtual int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) = 0; - virtual int start_security_mode_procedure(uint16_t rnti) = 0; + virtual int start_security_mode_procedure(uint16_t rnti, srsran::unique_byte_buffer_t nas_pdu) = 0; virtual int - establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) = 0; - virtual int allocate_lcid(uint16_t rnti) = 0; - virtual int release_bearers(uint16_t rnti) = 0; - virtual void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) = 0; + establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) = 0; + virtual int allocate_lcid(uint16_t rnti) = 0; + virtual int release_bearers(uint16_t rnti) = 0; + virtual void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) = 0; }; } // namespace srsenb diff --git a/srsgnb/hdr/stack/rrc/rrc_nr.h b/srsgnb/hdr/stack/rrc/rrc_nr.h index 6619dda57..eac2f93f8 100644 --- a/srsgnb/hdr/stack/rrc/rrc_nr.h +++ b/srsgnb/hdr/stack/rrc/rrc_nr.h @@ -94,7 +94,7 @@ public: int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) final; int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) final; int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) final; - int start_security_mode_procedure(uint16_t rnti) final; + int start_security_mode_procedure(uint16_t rnti, srsran::unique_byte_buffer_t nas_pdu) final; int establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_ue.h b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h index 9eb5aecff..7135dd0d5 100644 --- a/srsgnb/hdr/stack/rrc/rrc_nr_ue.h +++ b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h @@ -81,7 +81,7 @@ public: void establish_eps_bearer(uint32_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid); /* TS 38.331 - 5.3.4 Initial AS security activation */ - void send_security_mode_command(); + void send_security_mode_command(srsran::unique_byte_buffer_t nas_pdu); private: int send_dl_ccch(const asn1::rrc_nr::dl_ccch_msg_s& dl_ccch_msg); diff --git a/srsgnb/src/stack/ngap/ngap_ue_proc.cc b/srsgnb/src/stack/ngap/ngap_ue_proc.cc index 9c2ba883a..31f7b6247 100644 --- a/srsgnb/src/stack/ngap/ngap_ue_proc.cc +++ b/srsgnb/src/stack/ngap/ngap_ue_proc.cc @@ -33,18 +33,20 @@ proc_outcome_t ngap_ue_initial_context_setup_proc::init(const asn1::ngap_nr::ini } rrc->ue_set_security_cfg_capabilities(ue_ctxt->rnti, msg.protocol_ies.ue_security_cap.value); rrc->ue_set_security_cfg_key(ue_ctxt->rnti, msg.protocol_ies.security_key.value); - rrc->start_security_mode_procedure(ue_ctxt->rnti); if (msg.protocol_ies.nas_pdu_present) { srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); if (pdu == nullptr) { - logger.error("Fatal Error: Couldn't allocate buffer in ngap_ue_initial_context_setup_proc::init()."); + logger.error("Fatal Error: Couldn't allocate buffer in %s.", __FUNCTION__); return proc_outcome_t::error; } memcpy(pdu->msg, msg.protocol_ies.nas_pdu.value.data(), msg.protocol_ies.nas_pdu.value.size()); pdu->N_bytes = msg.protocol_ies.nas_pdu.value.size(); - rrc->write_dl_info(ue_ctxt->rnti, std::move(pdu)); + rrc->start_security_mode_procedure(ue_ctxt->rnti, std::move(pdu)); + } else { + rrc->start_security_mode_procedure(ue_ctxt->rnti, nullptr); } + return proc_outcome_t::yield; }; @@ -182,4 +184,4 @@ proc_outcome_t ngap_ue_pdu_session_res_setup_proc::step() return proc_outcome_t::success; } -} // namespace srsenb \ No newline at end of file +} // namespace srsenb diff --git a/srsgnb/src/stack/ngap/test/ngap_test.cc b/srsgnb/src/stack/ngap/test/ngap_test.cc index ceba93260..c5039b1c9 100644 --- a/srsgnb/src/stack/ngap/test/ngap_test.cc +++ b/srsgnb/src/stack/ngap/test/ngap_test.cc @@ -102,7 +102,7 @@ public: sec_caps = caps; return SRSRAN_SUCCESS; } - int start_security_mode_procedure(uint16_t rnti) + int start_security_mode_procedure(uint16_t rnti, srsran::unique_byte_buffer_t nas_pdu) { rrc_logger.info("Starting securtity mode procedure"); sec_mod_proc_started = true; @@ -189,7 +189,8 @@ void run_ng_initial_ue(ngap& ngap_obj, amf_dummy& amf, rrc_nr_dummy& rrc) memcpy(nas_pdu->msg, nas_reg_req, sizeof(nas_reg_req)); nas_pdu->N_bytes = sizeof(nas_reg_req); - ngap_obj.initial_ue(0xf0f0, 0, asn1::ngap_nr::rrcestablishment_cause_opts::mo_sig, srsran::make_span(nas_pdu)); + uint32_t rnti = 0xf0f0; + ngap_obj.initial_ue(rnti, 0, asn1::ngap_nr::rrcestablishment_cause_opts::mo_sig, srsran::make_span(nas_pdu)); // gNB -> AMF: Inital UE message asn1::ngap_nr::ngap_pdu_c ngap_initial_ue_pdu; diff --git a/srsgnb/src/stack/rrc/rrc_nr.cc b/srsgnb/src/stack/rrc/rrc_nr.cc index 20523a282..3790a3b53 100644 --- a/srsgnb/src/stack/rrc/rrc_nr.cc +++ b/srsgnb/src/stack/rrc/rrc_nr.cc @@ -591,14 +591,14 @@ int rrc_nr::ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr: u.set_security_capabilities(caps); return SRSRAN_SUCCESS; } -int rrc_nr::start_security_mode_procedure(uint16_t rnti) +int rrc_nr::start_security_mode_procedure(uint16_t rnti, srsran::unique_byte_buffer_t nas_pdu) { auto user_it = users.find(rnti); if (user_it == users.end()) { logger.error("Starting SecurityModeCommand procedure failed - rnti=0x%x not found", rnti); return SRSRAN_ERROR; } - user_it->second->send_security_mode_command(); + user_it->second->send_security_mode_command(std::move(nas_pdu)); return SRSRAN_SUCCESS; } int rrc_nr::establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) diff --git a/srsgnb/src/stack/rrc/rrc_nr_ue.cc b/srsgnb/src/stack/rrc/rrc_nr_ue.cc index f3abf19d7..4c6e9d3d1 100644 --- a/srsgnb/src/stack/rrc/rrc_nr_ue.cc +++ b/srsgnb/src/stack/rrc/rrc_nr_ue.cc @@ -982,7 +982,7 @@ void rrc_nr::ue::handle_rrc_setup_complete(const asn1::rrc_nr::rrc_setup_complet } /// TS 38.331, SecurityModeCommand -void rrc_nr::ue::send_security_mode_command() +void rrc_nr::ue::send_security_mode_command(srsran::unique_byte_buffer_t nas_pdu) { // FIXME: Currently we are using the PDCP-LTE, so we need to convert from nr_as_security_cfg to as_security_config. // When we start using PDCP-NR we can avoid this step. @@ -999,6 +999,8 @@ void rrc_nr::ue::send_security_mode_command() parent->pdcp->config_security(rnti, srb_to_lcid(srsran::nr_srb::srb1), pdcp_cnfg); parent->pdcp->enable_integrity(rnti, srb_to_lcid(srsran::nr_srb::srb1)); + nas_pdu_queue.push_back(std::move(nas_pdu)); + asn1::rrc_nr::dl_dcch_msg_s dl_dcch_msg; dl_dcch_msg.msg.set_c1().set_security_mode_cmd().rrc_transaction_id = (uint8_t)((transaction_id++) % 4); security_mode_cmd_ies_s& ies = dl_dcch_msg.msg.c1().security_mode_cmd().crit_exts.set_security_mode_cmd(); @@ -1018,6 +1020,11 @@ void rrc_nr::ue::handle_security_mode_complete(const asn1::rrc_nr::security_mode parent->pdcp->enable_encryption(rnti, srb_to_lcid(srsran::nr_srb::srb1)); // Note: Skip UE capabilities + + // Send RRCReconfiguration if necessary + if (not nas_pdu_queue.empty()) { + send_rrc_reconfiguration(); + } } /// TS 38.331, RRCReconfiguration @@ -1079,6 +1086,7 @@ void rrc_nr::ue::handle_rrc_reconfiguration_complete(const asn1::rrc_nr::rrc_rec { radio_bearer_cfg = next_radio_bearer_cfg; cell_group_cfg = next_cell_group_cfg; + parent->ngap->ue_notify_rrc_reconf_complete(rnti, true); } void rrc_nr::ue::send_rrc_release() diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc index eadd91290..6ac574d87 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc @@ -128,7 +128,7 @@ void test_rrc_nr_security_mode_cmd(srsran::task_scheduler& task_sched, srsran::unique_byte_buffer_t pdu; // Trigger Send SecurityCommand (simulate request from NGAP) - rrc_obj.start_security_mode_procedure(rnti); + rrc_obj.start_security_mode_procedure(rnti, nullptr); // Test whether there exists the SRB1 initiated in the Connection Establishment // We test this as the SRB1 was setup in a different function