From a6226379b4210d4df8388f14171b0f7f8b96a26d Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Wed, 7 Jul 2021 16:45:15 +0200 Subject: [PATCH] Introducing NGAP UE context procedures --- .../srsran/interfaces/gnb_ngap_interfaces.h | 1 + .../srsran/interfaces/gnb_rrc_nr_interfaces.h | 7 + srsenb/hdr/stack/ngap/ngap.h | 65 ++--- srsenb/hdr/stack/ngap/ngap_interfaces.h | 24 ++ srsenb/hdr/stack/ngap/ngap_ue.h | 66 +++++ srsenb/hdr/stack/ngap/ngap_ue_proc.h | 84 ++++++ srsenb/hdr/stack/ngap/ngap_ue_utils.h | 38 +++ srsenb/hdr/stack/rrc/rrc_nr.h | 7 + srsenb/src/stack/ngap/CMakeLists.txt | 2 +- srsenb/src/stack/ngap/ngap.cc | 268 +++++++----------- srsenb/src/stack/ngap/ngap_ue.cc | 208 ++++++++++++++ srsenb/src/stack/ngap/ngap_ue_proc.cc | 92 ++++++ srsenb/src/stack/rrc/rrc_nr.cc | 22 ++ srsenb/test/ngap/ngap_test.cc | 21 +- 14 files changed, 691 insertions(+), 214 deletions(-) create mode 100644 srsenb/hdr/stack/ngap/ngap_interfaces.h create mode 100644 srsenb/hdr/stack/ngap/ngap_ue.h create mode 100644 srsenb/hdr/stack/ngap/ngap_ue_proc.h create mode 100644 srsenb/hdr/stack/ngap/ngap_ue_utils.h create mode 100644 srsenb/src/stack/ngap/ngap_ue.cc create mode 100644 srsenb/src/stack/ngap/ngap_ue_proc.cc diff --git a/lib/include/srsran/interfaces/gnb_ngap_interfaces.h b/lib/include/srsran/interfaces/gnb_ngap_interfaces.h index 5d3fd92a8..6780d0a02 100644 --- a/lib/include/srsran/interfaces/gnb_ngap_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_ngap_interfaces.h @@ -50,6 +50,7 @@ public: virtual bool user_release(uint16_t rnti, asn1::ngap_nr::cause_radio_network_e cause_radio) = 0; virtual bool is_amf_connected() = 0; virtual void ue_ctxt_setup_complete(uint16_t rnti) = 0; + virtual void ue_notify_rrc_reconf_complete(uint16_t rnti, bool outcome) = 0; }; } // namespace srsenb diff --git a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h index af7ec46a3..fbb5062ac 100644 --- a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h @@ -12,11 +12,18 @@ #ifndef SRSRAN_GNB_RRC_NR_INTERFACES_H #define SRSRAN_GNB_RRC_NR_INTERFACES_H +#include "srsran/asn1/ngap.h" +#include "srsran/common/byte_buffer.h" namespace srsenb { class rrc_interface_ngap_nr { public: + virtual int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) = 0; + virtual int ue_set_bitrates(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 void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) = 0; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/ngap/ngap.h b/srsenb/hdr/stack/ngap/ngap.h index 8220285fb..3aa3b0f39 100644 --- a/srsenb/hdr/stack/ngap/ngap.h +++ b/srsenb/hdr/stack/ngap/ngap.h @@ -37,9 +37,11 @@ namespace srsenb { class ngap : public ngap_interface_rrc_nr { public: + class ue; ngap(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, srsran::socket_manager_itf* rx_socket_handler); + ~ngap(); int init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_); void stop(); @@ -54,7 +56,7 @@ public: srsran::unique_byte_buffer_t pdu, uint32_t s_tmsi); - void write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu){}; + void write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu); bool user_exists(uint16_t rnti) { return true; }; void user_mod(uint16_t old_rnti, uint16_t new_rnti){}; bool user_release(uint16_t rnti, asn1::ngap_nr::cause_radio_network_e cause_radio) { return true; }; @@ -63,6 +65,8 @@ public: srsran::optional ran_ue_ngap_id = {}, srsran::optional amf_ue_ngap_id = {}); void ue_ctxt_setup_complete(uint16_t rnti); + void ue_notify_rrc_reconf_complete(uint16_t rnti, bool outcome); + bool send_pdu_session_resource_setup_response(); // Stack interface bool @@ -79,7 +83,7 @@ private: static const int NONUE_STREAM_ID = 0; // args - rrc_interface_ngap_nr* rrc = nullptr; + rrc_interface_ngap_nr* rrc = nullptr; ngap_args_t args = {}; srslog::basic_logger& logger; srsran::task_sched_handle task_sched; @@ -98,22 +102,6 @@ private: asn1::ngap_nr::tai_s tai; asn1::ngap_nr::nr_cgi_s nr_cgi; - // Moved into NGAP class to avoid redifinition (Introduce new namespace?) - struct ue_ctxt_t { - static const uint32_t invalid_gnb_id = std::numeric_limits::max(); - - uint16_t rnti = SRSRAN_INVALID_RNTI; - uint32_t ran_ue_ngap_id = invalid_gnb_id; - srsran::optional amf_ue_ngap_id; - uint32_t gnb_cc_idx = 0; - struct timeval init_timestamp = {}; - - // AMF identifier - uint16_t amf_set_id; - uint8_t amf_pointer; - uint8_t amf_region_id; - }; - asn1::ngap_nr::ng_setup_resp_s ngsetupresponse; int build_tai_cgi(); @@ -122,34 +110,23 @@ private: bool sctp_send_ngap_pdu(const asn1::ngap_nr::ngap_pdu_c& tx_pdu, uint32_t rnti, const char* procedure_name); bool handle_ngap_rx_pdu(srsran::byte_buffer_t* pdu); - bool handle_successfuloutcome(const asn1::ngap_nr::successful_outcome_s& msg); - bool handle_unsuccessfuloutcome(const asn1::ngap_nr::unsuccessful_outcome_s& msg); - bool handle_initiatingmessage(const asn1::ngap_nr::init_msg_s& msg); + bool handle_successful_outcome(const asn1::ngap_nr::successful_outcome_s& msg); + bool handle_unsuccessful_outcome(const asn1::ngap_nr::unsuccessful_outcome_s& msg); + bool handle_initiating_message(const asn1::ngap_nr::init_msg_s& msg); - bool handle_dlnastransport(const asn1::ngap_nr::dl_nas_transport_s& msg); - bool handle_ngsetupresponse(const asn1::ngap_nr::ng_setup_resp_s& msg); - bool handle_ngsetupfailure(const asn1::ngap_nr::ng_setup_fail_s& msg); - bool handle_initialctxtsetuprequest(const asn1::ngap_nr::init_context_setup_request_s& msg); - struct ue { - explicit ue(ngap* ngap_ptr_); - bool send_initialuemessage(asn1::ngap_nr::rrcestablishment_cause_e cause, - srsran::unique_byte_buffer_t pdu, - bool has_tmsi, - uint32_t s_tmsi = 0); - bool send_ulnastransport(srsran::unique_byte_buffer_t pdu); - bool was_uectxtrelease_requested() const { return release_requested; } - void ue_ctxt_setup_complete(); + // TS 38.413 - Section 8.6.2 - Downlink NAS Transport + bool handle_dl_nas_transport(const asn1::ngap_nr::dl_nas_transport_s& msg); + // TS 38.413 - Section 9.2.6.2 - NG Setup Response + bool handle_ng_setup_response(const asn1::ngap_nr::ng_setup_resp_s& msg); + // TS 38.413 - Section 9.2.6.3 - NG Setup Failure + bool handle_ng_setup_failure(const asn1::ngap_nr::ng_setup_fail_s& msg); + // TS 38.413 - Section 9.2.2.5 - UE Context Release Command + bool handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cmd_s& msg); + // TS 38.413 - Section 9.2.2.1 - Initial Context Setup Request + bool handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg); + // TS 38.413 - Section 9.2.1.1 - PDU Session Resource Setup Request + bool handle_pdu_session_resource_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg); - ue_ctxt_t ctxt = {}; - uint16_t stream_id = 1; - - private: - // args - ngap* ngap_ptr; - - // state - bool release_requested = false; - }; class user_list { public: diff --git a/srsenb/hdr/stack/ngap/ngap_interfaces.h b/srsenb/hdr/stack/ngap/ngap_interfaces.h new file mode 100644 index 000000000..4740a8c2c --- /dev/null +++ b/srsenb/hdr/stack/ngap/ngap_interfaces.h @@ -0,0 +1,24 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSENB_NGAP_INTERFACES_H +#define SRSENB_NGAP_INTERFACES_H + +namespace srsenb { +class ngap_interface_ngap_proc +{ +public: + virtual bool send_initial_ctxt_setup_response() = 0; +}; +} // namespace srsenb + +#endif \ No newline at end of file diff --git a/srsenb/hdr/stack/ngap/ngap_ue.h b/srsenb/hdr/stack/ngap/ngap_ue.h new file mode 100644 index 000000000..99f203628 --- /dev/null +++ b/srsenb/hdr/stack/ngap/ngap_ue.h @@ -0,0 +1,66 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ +#ifndef SRSENB_NGAP_UE_H +#define SRSENB_NGAP_UE_H + +#include "ngap.h" +#include "ngap_ue_proc.h" +#include "ngap_ue_utils.h" +#include "srsran/asn1/asn1_utils.h" +#include "srsran/asn1/ngap.h" +namespace srsenb { + +class ngap::ue : public ngap_interface_ngap_proc +{ +public: + explicit ue(ngap* ngap_ptr_, rrc_interface_ngap_nr* rrc_ptr_, srslog::basic_logger& logger_); + virtual ~ue(); + // TS 38.413 - Section 9.2.5.1 - Initial UE Message + bool send_initial_ue_message(asn1::ngap_nr::rrcestablishment_cause_e cause, + srsran::unique_byte_buffer_t pdu, + bool has_tmsi, + uint32_t s_tmsi = 0); + // TS 38.413 - Section 9.2.5.3 - Uplink NAS Transport + bool send_ul_nas_transport(srsran::unique_byte_buffer_t pdu); + // TS 38.413 - Section 9.2.2.2 - Initial Context Setup Response + bool send_initial_ctxt_setup_response(); + // TS 38.413 - Section 9.2.2.3 - Initial Context Setup Failure + bool send_initial_ctxt_setup_failure(asn1::ngap_nr::cause_c cause); + // TS 38.413 - Section 9.2.2.1 - Initial Context Setup Request + bool handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg); + // TS 38.413 - Section 9.2.2.5 - UE Context Release Command + bool handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cmd_s& msg); + + bool was_uectxtrelease_requested() const { return release_requested; } + void ue_ctxt_setup_complete(); + void notify_rrc_reconf_complete(const bool reconf_complete_outcome); + + srsran::proc_t initial_context_setup_proc; + srsran::proc_t ue_context_release_proc; + + ngap_ue_ctxt_t ctxt = {}; + uint16_t stream_id = 1; + +private: + // args + ngap* ngap_ptr; + rrc_interface_ngap_nr* rrc_ptr; + + // state + bool release_requested = false; + + // logger + srslog::basic_logger& logger; +}; + +} // namespace srsenb +#endif \ No newline at end of file diff --git a/srsenb/hdr/stack/ngap/ngap_ue_proc.h b/srsenb/hdr/stack/ngap/ngap_ue_proc.h new file mode 100644 index 000000000..9464fcd8e --- /dev/null +++ b/srsenb/hdr/stack/ngap/ngap_ue_proc.h @@ -0,0 +1,84 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSENB_NGAP_UE_PROC_H +#define SRSENB_NGAP_UE_PROC_H + +#include "ngap_interfaces.h" +#include "ngap_ue_utils.h" + +#include "srsran/asn1/asn1_utils.h" +#include "srsran/asn1/ngap.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/common/stack_procedure.h" +#include "srsran/interfaces/gnb_rrc_nr_interfaces.h" + +#include +#include + +namespace srsenb { + +// TS 38.413 - Section 8.3 - UE Context Management Procedures + +// TS 38.413 - Section 8.3.1 - Initial Context Setup +class ngap_ue_initial_context_setup_proc +{ +public: + explicit ngap_ue_initial_context_setup_proc(ngap_interface_ngap_proc* parent_, + rrc_interface_ngap_nr* rrc_, + ngap_ue_ctxt_t* ue_ctxt); + srsran::proc_outcome_t init(const asn1::ngap_nr::init_context_setup_request_s& msg); + srsran::proc_outcome_t react(const bool security_mode_command_outcome); + srsran::proc_outcome_t step(); + static const char* name() { return "Initial Context Setup"; } + +private: + ngap_ue_ctxt_t* ue_ctxt; + ngap_interface_ngap_proc* parent = nullptr; + rrc_interface_ngap_nr* rrc = nullptr; + srslog::basic_logger& logger; +}; + +// TS 38.413 - Section 8.3.2 - UE Context Release Request (NG-RAN node initiated) +class ngap_ue_ue_context_release_proc +{ +public: + explicit ngap_ue_ue_context_release_proc(ngap_interface_ngap_proc* parent_, + rrc_interface_ngap_nr* rrc_, + ngap_ue_ctxt_t* ue_ctxt); + srsran::proc_outcome_t init(const asn1::ngap_nr::ue_context_release_cmd_s& msg); + srsran::proc_outcome_t step(); + static const char* name() { return "UE Context Release"; } + +private: + ngap_ue_ctxt_t* ue_ctxt; + ngap_interface_ngap_proc* parent = nullptr; + rrc_interface_ngap_nr* rrc = nullptr; + srslog::basic_logger& logger; +}; + +// TS 38.413 - Section 8.3.4 - UE Context Modification +class ngap_ue_ue_context_modification_proc +{ +public: + explicit ngap_ue_ue_context_modification_proc(ngap_interface_ngap_proc* parent_); + srsran::proc_outcome_t init(); + srsran::proc_outcome_t step(); + static const char* name() { return "UE Context Modification"; } + +private: + ngap_interface_ngap_proc* parent; +}; + +} // namespace srsenb + +#endif \ No newline at end of file diff --git a/srsenb/hdr/stack/ngap/ngap_ue_utils.h b/srsenb/hdr/stack/ngap/ngap_ue_utils.h new file mode 100644 index 000000000..f0067ef50 --- /dev/null +++ b/srsenb/hdr/stack/ngap/ngap_ue_utils.h @@ -0,0 +1,38 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ +#ifndef SRSENB_NGAP_UE_UTILS_H +#define SRSENB_NGAP_UE_UTILS_H + +#include "srsenb/hdr/common/common_enb.h" +#include "srsran/adt/optional.h" +#include "srsran/common/common.h" +#include "srsran/phy/common/phy_common.h" + +namespace srsenb { + +struct ngap_ue_ctxt_t { + static const uint32_t invalid_gnb_id = std::numeric_limits::max(); + + uint16_t rnti = SRSRAN_INVALID_RNTI; + uint32_t ran_ue_ngap_id = invalid_gnb_id; + srsran::optional amf_ue_ngap_id; + uint32_t gnb_cc_idx = 0; + struct timeval init_timestamp = {}; + + // AMF identifier + uint16_t amf_set_id; + uint8_t amf_pointer; + uint8_t amf_region_id; +}; + +} // namespace srsenb +#endif \ No newline at end of file diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 676074dc7..535b8eadc 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -82,6 +82,13 @@ public: int sgnb_addition_request(uint16_t rnti); int sgnb_reconfiguration_complete(uint16_t rnti, asn1::dyn_octstring reconfig_response); + // Interfaces for NGAP + int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key); + int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates); + int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps); + int start_security_mode_procedure(uint16_t rnti); + void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu); + class ue { public: diff --git a/srsenb/src/stack/ngap/CMakeLists.txt b/srsenb/src/stack/ngap/CMakeLists.txt index fd4c1f8bd..099260995 100644 --- a/srsenb/src/stack/ngap/CMakeLists.txt +++ b/srsenb/src/stack/ngap/CMakeLists.txt @@ -6,5 +6,5 @@ # the distribution. # -set(SOURCES ngap.cc) +set(SOURCES ngap.cc ngap_ue.cc ngap_ue_proc.cc) add_library(srsgnb_ngap STATIC ${SOURCES}) diff --git a/srsenb/src/stack/ngap/ngap.cc b/srsenb/src/stack/ngap/ngap.cc index 1410e2cf0..0f99b1973 100644 --- a/srsenb/src/stack/ngap/ngap.cc +++ b/srsenb/src/stack/ngap/ngap.cc @@ -11,6 +11,7 @@ */ #include "srsenb/hdr/stack/ngap/ngap.h" +#include "srsenb/hdr/stack/ngap/ngap_ue.h" #include "srsran/common/int_helpers.h" using srsran::s1ap_mccmnc_to_plmn; @@ -102,6 +103,8 @@ ngap::ngap(srsran::task_sched_handle task_sched_, amf_task_queue = task_sched.make_task_queue(); } +ngap::~ngap() {} + int ngap::init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_) { rrc = rrc_; @@ -204,7 +207,7 @@ void ngap::initial_ue(uint16_t rnti, asn1::ngap_nr::rrcestablishment_cause_e cause, srsran::unique_byte_buffer_t pdu) { - std::unique_ptr ue_ptr{new ue{this}}; + std::unique_ptr ue_ptr{new ue{this, rrc, logger}}; ue_ptr->ctxt.rnti = rnti; ue_ptr->ctxt.gnb_cc_idx = gnb_cc_idx; ue* u = users.add_user(std::move(ue_ptr)); @@ -212,7 +215,7 @@ void ngap::initial_ue(uint16_t rnti, logger.error("Failed to add rnti=0x%x", rnti); return; } - u->send_initialuemessage(cause, std::move(pdu), false); + u->send_initial_ue_message(cause, std::move(pdu), false); } void ngap::initial_ue(uint16_t rnti, @@ -221,7 +224,7 @@ void ngap::initial_ue(uint16_t rnti, srsran::unique_byte_buffer_t pdu, uint32_t s_tmsi) { - std::unique_ptr ue_ptr{new ue{this}}; + std::unique_ptr ue_ptr{new ue{this, rrc, logger}}; ue_ptr->ctxt.rnti = rnti; ue_ptr->ctxt.gnb_cc_idx = gnb_cc_idx; ue* u = users.add_user(std::move(ue_ptr)); @@ -229,7 +232,7 @@ void ngap::initial_ue(uint16_t rnti, logger.error("Failed to add rnti=0x%x", rnti); return; } - u->send_initialuemessage(cause, std::move(pdu), true, s_tmsi); + u->send_initial_ue_message(cause, std::move(pdu), true, s_tmsi); } void ngap::ue_ctxt_setup_complete(uint16_t rnti) @@ -241,6 +244,27 @@ void ngap::ue_ctxt_setup_complete(uint16_t rnti) u->ue_ctxt_setup_complete(); } +void ngap::ue_notify_rrc_reconf_complete(uint16_t rnti, bool outcome) +{ + ue* u = users.find_ue_rnti(rnti); + if (u == nullptr) { + return; + } + u->notify_rrc_reconf_complete(outcome); +} + +void ngap::write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) +{ + logger.info(pdu->msg, pdu->N_bytes, "Received RRC SDU"); + + ue* u = users.find_ue_rnti(rnti); + if (u == nullptr) { + logger.info("The rnti=0x%x does not exist", rnti); + return; + } + u->send_ul_nas_transport(std::move(pdu)); +} + /********************************************************* * ngap::user_list class *********************************************************/ @@ -368,11 +392,11 @@ bool ngap::handle_ngap_rx_pdu(srsran::byte_buffer_t* pdu) switch (rx_pdu.type().value) { case ngap_pdu_c::types_opts::init_msg: - return handle_initiatingmessage(rx_pdu.init_msg()); + return handle_initiating_message(rx_pdu.init_msg()); case ngap_pdu_c::types_opts::successful_outcome: - return handle_successfuloutcome(rx_pdu.successful_outcome()); + return handle_successful_outcome(rx_pdu.successful_outcome()); case ngap_pdu_c::types_opts::unsuccessful_outcome: - return handle_unsuccessfuloutcome(rx_pdu.unsuccessful_outcome()); + return handle_unsuccessful_outcome(rx_pdu.unsuccessful_outcome()); default: logger.error("Unhandled PDU type %d", rx_pdu.type().value); return false; @@ -381,42 +405,44 @@ bool ngap::handle_ngap_rx_pdu(srsran::byte_buffer_t* pdu) return true; } -bool ngap::handle_initiatingmessage(const asn1::ngap_nr::init_msg_s& msg) +bool ngap::handle_initiating_message(const asn1::ngap_nr::init_msg_s& msg) { switch (msg.value.type().value) { case ngap_elem_procs_o::init_msg_c::types_opts::dl_nas_transport: - return handle_dlnastransport(msg.value.dl_nas_transport()); + return handle_dl_nas_transport(msg.value.dl_nas_transport()); case ngap_elem_procs_o::init_msg_c::types_opts::init_context_setup_request: - return handle_initialctxtsetuprequest(msg.value.init_context_setup_request()); + return handle_initial_ctxt_setup_request(msg.value.init_context_setup_request()); + case ngap_elem_procs_o::init_msg_c::types_opts::ue_context_release_cmd: + return handle_ue_ctxt_release_cmd(msg.value.ue_context_release_cmd()); default: logger.error("Unhandled initiating message: %s", msg.value.type().to_string()); } return true; } -bool ngap::handle_successfuloutcome(const successful_outcome_s& msg) +bool ngap::handle_successful_outcome(const successful_outcome_s& msg) { switch (msg.value.type().value) { case ngap_elem_procs_o::successful_outcome_c::types_opts::ng_setup_resp: - return handle_ngsetupresponse(msg.value.ng_setup_resp()); + return handle_ng_setup_response(msg.value.ng_setup_resp()); default: logger.error("Unhandled successful outcome message: %s", msg.value.type().to_string()); } return true; } -bool ngap::handle_unsuccessfuloutcome(const asn1::ngap_nr::unsuccessful_outcome_s& msg) +bool ngap::handle_unsuccessful_outcome(const asn1::ngap_nr::unsuccessful_outcome_s& msg) { switch (msg.value.type().value) { case ngap_elem_procs_o::unsuccessful_outcome_c::types_opts::ng_setup_fail: - return handle_ngsetupfailure(msg.value.ng_setup_fail()); + return handle_ng_setup_failure(msg.value.ng_setup_fail()); default: logger.error("Unhandled unsuccessful outcome message: %s", msg.value.type().to_string()); } return true; } -bool ngap::handle_ngsetupresponse(const asn1::ngap_nr::ng_setup_resp_s& msg) +bool ngap::handle_ng_setup_response(const asn1::ngap_nr::ng_setup_resp_s& msg) { ngsetupresponse = msg; amf_connected = true; @@ -427,7 +453,7 @@ bool ngap::handle_ngsetupresponse(const asn1::ngap_nr::ng_setup_resp_s& msg) return true; } -bool ngap::handle_ngsetupfailure(const asn1::ngap_nr::ng_setup_fail_s& msg) +bool ngap::handle_ng_setup_failure(const asn1::ngap_nr::ng_setup_fail_s& msg) { std::string cause = get_cause(msg.protocol_ies.cause.value); logger.error("NG Setup Failure. Cause: %s", cause.c_str()); @@ -435,14 +461,18 @@ bool ngap::handle_ngsetupfailure(const asn1::ngap_nr::ng_setup_fail_s& msg) return true; } -bool ngap::handle_dlnastransport(const asn1::ngap_nr::dl_nas_transport_s& msg) +bool ngap::handle_dl_nas_transport(const asn1::ngap_nr::dl_nas_transport_s& msg) { if (msg.ext) { logger.warning("Not handling NGAP message extension"); } ue* u = handle_ngapmsg_ue_id(msg.protocol_ies.ran_ue_ngap_id.value.value, msg.protocol_ies.amf_ue_ngap_id.value.value); + if (u == nullptr) { + logger.warning("Couldn't find user with ran_ue_ngap_id %d and %d", + msg.protocol_ies.ran_ue_ngap_id.value.value, + msg.protocol_ies.amf_ue_ngap_id.value.value); return false; } @@ -470,49 +500,79 @@ bool ngap::handle_dlnastransport(const asn1::ngap_nr::dl_nas_transport_s& msg) logger.warning("Not handling AllowedNSSAI"); } - // TODO: Pass NAS PDU once RRC interface is ready - /* srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); if (pdu == nullptr) { logger.error("Fatal Error: Couldn't allocate buffer in ngap::run_thread()."); return false; } 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(u->ctxt.rnti, std::move(pdu)); */ + rrc->write_dl_info(u->ctxt.rnti, std::move(pdu)); return true; } -bool ngap::handle_initialctxtsetuprequest(const asn1::ngap_nr::init_context_setup_request_s& msg) +bool ngap::handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg) { ue* u = handle_ngapmsg_ue_id(msg.protocol_ies.ran_ue_ngap_id.value.value, msg.protocol_ies.amf_ue_ngap_id.value.value); if (u == nullptr) { + logger.warning("Can not find UE"); return false; } - u->ctxt.amf_pointer = msg.protocol_ies.guami.value.amf_pointer.to_number(); - u->ctxt.amf_set_id = msg.protocol_ies.guami.value.amf_set_id.to_number(); - u->ctxt.amf_region_id = msg.protocol_ies.guami.value.amf_region_id.to_number(); - - // Setup UE ctxt in RRC once interface is ready - /* if (not rrc->setup_ue_ctxt(u->ctxt.rnti, msg)) { - return false; - } */ - - /* 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::run_thread()."); - return false; - } - 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(u->ctxt.rnti, std::move(pdu)); - } */ + u->handle_initial_ctxt_setup_request(msg); return true; } +bool ngap::handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cmd_s& msg) +{ + // TODO: UE Context Release Command contains a list of ue_ngap_ids + + return true; +} + +bool ngap::handle_pdu_session_resource_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg) +{ + // TODO + logger.warning("Not implemented yet"); + return true; +} + +/******************************************************************************* +/* NGAP message senders +********************************************************************************/ + +bool ngap::send_error_indication(const asn1::ngap_nr::cause_c& cause, + srsran::optional ran_ue_ngap_id, + srsran::optional amf_ue_ngap_id) +{ + if (amf_connected == false) { + logger.warning("AMF not connected."); + return false; + } + + ngap_pdu_c tx_pdu; + tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_ERROR_IND); + auto& container = tx_pdu.init_msg().value.error_ind().protocol_ies; + + uint16_t rnti = SRSRAN_INVALID_RNTI; + container.ran_ue_ngap_id_present = ran_ue_ngap_id.has_value(); + if (ran_ue_ngap_id.has_value()) { + container.ran_ue_ngap_id.value = ran_ue_ngap_id.value(); + ue* user_ptr = users.find_ue_gnbid(ran_ue_ngap_id.value()); + rnti = user_ptr != nullptr ? user_ptr->ctxt.rnti : SRSRAN_INVALID_RNTI; + } + container.amf_ue_ngap_id_present = amf_ue_ngap_id.has_value(); + if (amf_ue_ngap_id.has_value()) { + container.amf_ue_ngap_id.value = amf_ue_ngap_id.value(); + } + + container.cause_present = true; + container.cause.value = cause; + + return sctp_send_ngap_pdu(tx_pdu, rnti, "Error Indication"); +} /******************************************************************************* /* NGAP connection helpers ********************************************************************************/ @@ -596,134 +656,6 @@ bool ngap::setup_ng() return sctp_send_ngap_pdu(pdu, 0, "ngSetupRequest"); } -/******************************************************************************* -/* NGAP message senders -********************************************************************************/ - -bool ngap::ue::send_initialuemessage(asn1::ngap_nr::rrcestablishment_cause_e cause, - srsran::unique_byte_buffer_t pdu, - bool has_tmsi, - uint32_t s_tmsi) -{ - if (not ngap_ptr->amf_connected) { - return false; - } - - ngap_pdu_c tx_pdu; - tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_INIT_UE_MSG); - init_ue_msg_ies_container& container = tx_pdu.init_msg().value.init_ue_msg().protocol_ies; - - // 5G-S-TMSI - if (has_tmsi) { - container.five_g_s_tmsi_present = true; - srsran::uint32_to_uint8(s_tmsi, container.five_g_s_tmsi.value.five_g_tmsi.data()); - container.five_g_s_tmsi.value.amf_set_id.from_number(ctxt.amf_set_id); - container.five_g_s_tmsi.value.amf_pointer.from_number(ctxt.amf_pointer); - } - - // RAN_UE_NGAP_ID - container.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; - - // NAS_PDU - container.nas_pdu.value.resize(pdu->N_bytes); - memcpy(container.nas_pdu.value.data(), pdu->msg, pdu->N_bytes); - - // RRC Establishment Cause - container.rrcestablishment_cause.value = cause; - - // User Location Info - - // userLocationInformationNR - container.user_location_info.value.set_user_location_info_nr(); - container.user_location_info.value.user_location_info_nr().nr_cgi.nrcell_id = ngap_ptr->nr_cgi.nrcell_id; - container.user_location_info.value.user_location_info_nr().nr_cgi.plmn_id = ngap_ptr->nr_cgi.plmn_id; - container.user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; - container.user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; - - return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "InitialUEMessage"); -} - -bool ngap::ue::send_ulnastransport(srsran::unique_byte_buffer_t pdu) -{ - if (not ngap_ptr->amf_connected) { - return false; - } - - ngap_pdu_c tx_pdu; - tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_UL_NAS_TRANSPORT); - asn1::ngap_nr::ul_nas_transport_ies_container& container = tx_pdu.init_msg().value.ul_nas_transport().protocol_ies; - - // AMF UE NGAP ID - container.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); - - // RAN UE NGAP ID - container.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; - - // NAS PDU - container.nas_pdu.value.resize(pdu->N_bytes); - memcpy(container.nas_pdu.value.data(), pdu->msg, pdu->N_bytes); - - // User Location Info - // userLocationInformationNR - container.user_location_info.value.set_user_location_info_nr(); - container.user_location_info.value.user_location_info_nr().nr_cgi.nrcell_id = ngap_ptr->nr_cgi.nrcell_id; - container.user_location_info.value.user_location_info_nr().nr_cgi.plmn_id = ngap_ptr->nr_cgi.plmn_id; - container.user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; - container.user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; - - return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "UplinkNASTransport"); -} - -void ngap::ue::ue_ctxt_setup_complete() -{ - ngap_pdu_c tx_pdu; - // Handle PDU Session List once RRC interface is ready - tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_NR_ID_INIT_CONTEXT_SETUP); - auto& container = tx_pdu.successful_outcome().value.init_context_setup_resp().protocol_ies; -} - -bool ngap::send_error_indication(const asn1::ngap_nr::cause_c& cause, - srsran::optional ran_ue_ngap_id, - srsran::optional amf_ue_ngap_id) -{ - if (not amf_connected) { - return false; - } - - ngap_pdu_c tx_pdu; - tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_ERROR_IND); - auto& container = tx_pdu.init_msg().value.error_ind().protocol_ies; - - uint16_t rnti = SRSRAN_INVALID_RNTI; - container.ran_ue_ngap_id_present = ran_ue_ngap_id.has_value(); - if (ran_ue_ngap_id.has_value()) { - container.ran_ue_ngap_id.value = ran_ue_ngap_id.value(); - ue* user_ptr = users.find_ue_gnbid(ran_ue_ngap_id.value()); - rnti = user_ptr != nullptr ? user_ptr->ctxt.rnti : SRSRAN_INVALID_RNTI; - } - container.amf_ue_ngap_id_present = amf_ue_ngap_id.has_value(); - if (amf_ue_ngap_id.has_value()) { - container.amf_ue_ngap_id.value = amf_ue_ngap_id.value(); - } - - container.cause_present = true; - container.cause.value = cause; - - return sctp_send_ngap_pdu(tx_pdu, rnti, "Error Indication"); -} - -/******************************************************************************* -/* ngap::ue Class -********************************************************************************/ - -ngap::ue::ue(ngap* ngap_ptr_) : ngap_ptr(ngap_ptr_) -{ - ctxt.ran_ue_ngap_id = ngap_ptr->next_gnb_ue_ngap_id++; - gettimeofday(&ctxt.init_timestamp, nullptr); - - stream_id = ngap_ptr->next_ue_stream_id; -} - /******************************************************************************* /* General helpers ********************************************************************************/ diff --git a/srsenb/src/stack/ngap/ngap_ue.cc b/srsenb/src/stack/ngap/ngap_ue.cc new file mode 100644 index 000000000..59b9f4737 --- /dev/null +++ b/srsenb/src/stack/ngap/ngap_ue.cc @@ -0,0 +1,208 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srsenb/hdr/stack/ngap/ngap_ue.h" +#include "srsenb/hdr/stack/ngap/ngap.h" +#include "srsenb/hdr/stack/ngap/ngap_ue_proc.h" +#include "srsran/common/int_helpers.h" + +using namespace asn1::ngap_nr; + +namespace srsenb { + +/******************************************************************************* +/* ngap_ptr::ue Class +********************************************************************************/ + +ngap::ue::ue(ngap* ngap_ptr_, rrc_interface_ngap_nr* rrc_ptr_, srslog::basic_logger& logger_) : + logger(logger_), + ngap_ptr(ngap_ptr_), + rrc_ptr(rrc_ptr_), + initial_context_setup_proc(this, rrc_ptr, &ctxt), + ue_context_release_proc(this, rrc_ptr, &ctxt) +{ + ctxt.ran_ue_ngap_id = ngap_ptr->next_gnb_ue_ngap_id++; + gettimeofday(&ctxt.init_timestamp, nullptr); + stream_id = ngap_ptr->next_ue_stream_id; +} + +ngap::ue::~ue() {} + +/******************************************************************************* +/* NGAP message senders +********************************************************************************/ + +bool ngap::ue::send_initial_ue_message(asn1::ngap_nr::rrcestablishment_cause_e cause, + srsran::unique_byte_buffer_t pdu, + bool has_tmsi, + uint32_t s_tmsi) +{ + if (not ngap_ptr->amf_connected) { + logger.warning("AMF not connected"); + return false; + } + + ngap_pdu_c tx_pdu; + tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_INIT_UE_MSG); + init_ue_msg_ies_container& container = tx_pdu.init_msg().value.init_ue_msg().protocol_ies; + + // 5G-S-TMSI + if (has_tmsi) { + container.five_g_s_tmsi_present = true; + srsran::uint32_to_uint8(s_tmsi, container.five_g_s_tmsi.value.five_g_tmsi.data()); + container.five_g_s_tmsi.value.amf_set_id.from_number(ctxt.amf_set_id); + container.five_g_s_tmsi.value.amf_pointer.from_number(ctxt.amf_pointer); + } + + // RAN_UE_NGAP_ID + container.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + + // NAS_PDU + container.nas_pdu.value.resize(pdu->N_bytes); + memcpy(container.nas_pdu.value.data(), pdu->msg, pdu->N_bytes); + + // RRC Establishment Cause + container.rrcestablishment_cause.value = cause; + + // User Location Info + + // userLocationInformationNR + container.user_location_info.value.set_user_location_info_nr(); + container.user_location_info.value.user_location_info_nr().nr_cgi.nrcell_id = ngap_ptr->nr_cgi.nrcell_id; + container.user_location_info.value.user_location_info_nr().nr_cgi.plmn_id = ngap_ptr->nr_cgi.plmn_id; + container.user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; + container.user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; + + return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "InitialUEMessage"); +} + +bool ngap::ue::send_ul_nas_transport(srsran::unique_byte_buffer_t pdu) +{ + if (not ngap_ptr->amf_connected) { + logger.warning("AMF not connected"); + return false; + } + + ngap_pdu_c tx_pdu; + tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_UL_NAS_TRANSPORT); + asn1::ngap_nr::ul_nas_transport_ies_container& container = tx_pdu.init_msg().value.ul_nas_transport().protocol_ies; + + // AMF UE NGAP ID + container.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); + + // RAN UE NGAP ID + container.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + + // NAS PDU + container.nas_pdu.value.resize(pdu->N_bytes); + memcpy(container.nas_pdu.value.data(), pdu->msg, pdu->N_bytes); + + // User Location Info + // userLocationInformationNR + container.user_location_info.value.set_user_location_info_nr(); + container.user_location_info.value.user_location_info_nr().nr_cgi.nrcell_id = ngap_ptr->nr_cgi.nrcell_id; + container.user_location_info.value.user_location_info_nr().nr_cgi.plmn_id = ngap_ptr->nr_cgi.plmn_id; + container.user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; + container.user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; + + return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "UplinkNASTransport"); +} + +void ngap::ue::ue_ctxt_setup_complete() +{ + ngap_pdu_c tx_pdu; + // Handle PDU Session List once RRC interface is ready + tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_NR_ID_INIT_CONTEXT_SETUP); + auto& container = tx_pdu.successful_outcome().value.init_context_setup_resp().protocol_ies; +} + +void ngap::ue::notify_rrc_reconf_complete(const bool outcome) +{ + initial_context_setup_proc.trigger(outcome); +} + +bool ngap::ue::send_initial_ctxt_setup_response() +{ + if (not ngap_ptr->amf_connected) { + logger.warning("AMF not connected"); + return false; + } + + ngap_pdu_c tx_pdu; + tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_INIT_CONTEXT_SETUP); + init_context_setup_resp_s& container = tx_pdu.successful_outcome().value.init_context_setup_resp(); + + // AMF UE NGAP ID + container.protocol_ies.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); + + // RAN UE NGAP ID + container.protocol_ies.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + + /* // TODO: PDU Session Resource Setup Response List - Integrate PDU Session and Bearer management into NGAP + container.protocol_ies.pdu_session_res_setup_list_cxt_res_present = true; + + // Case PDU Session Resource Failed to Setup List + container.protocol_ies.pdu_session_res_failed_to_setup_list_cxt_res_present = true; */ + + return true; +} + +bool ngap::ue::send_initial_ctxt_setup_failure(cause_c cause) +{ + if (not ngap_ptr->amf_connected) { + logger.warning("AMF not connected"); + return false; + } + + ngap_pdu_c tx_pdu; + tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_INIT_CONTEXT_SETUP); + init_context_setup_fail_s& container = tx_pdu.unsuccessful_outcome().value.init_context_setup_fail(); + + // AMF UE NGAP ID + container.protocol_ies.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); + + // RAN UE NGAP ID + container.protocol_ies.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + + /* // TODO: PDU Session Resource Setup Response List - Integrate PDU Session and Bearer management into NGAP + container.protocol_ies.pdu_session_res_setup_list_cxt_res_present = true; + + // Case PDU Session Resource Failed to Setup List + container.protocol_ies.pdu_session_res_failed_to_setup_list_cxt_res_present = true; */ + + return true; +} + +/******************************************************************************* +/* NGAP message handler +********************************************************************************/ + +bool ngap::ue::handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg) +{ + if (not initial_context_setup_proc.launch(msg)) { + logger.error("Failed to start Initial Context Setup Procedure"); + return false; + } + return true; +} + +bool ngap::ue::handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cmd_s& msg) +{ + // TODO: Release UE context + if (not ue_context_release_proc.launch(msg)) { + logger.error("Failed to start UE Context Release Procedure"); + return false; + } + return true; +} + +} // namespace srsenb \ No newline at end of file diff --git a/srsenb/src/stack/ngap/ngap_ue_proc.cc b/srsenb/src/stack/ngap/ngap_ue_proc.cc new file mode 100644 index 000000000..8b113b098 --- /dev/null +++ b/srsenb/src/stack/ngap/ngap_ue_proc.cc @@ -0,0 +1,92 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srsenb/hdr/stack/ngap/ngap_ue_proc.h" + +using namespace srsran; + +namespace srsenb { + +ngap_ue_initial_context_setup_proc::ngap_ue_initial_context_setup_proc(ngap_interface_ngap_proc* parent_, + rrc_interface_ngap_nr* rrc_, + ngap_ue_ctxt_t* ue_ctxt_) : + logger(srslog::fetch_basic_logger("NGAP UE")) +{ + parent = parent_; + rrc = rrc_; + ue_ctxt = ue_ctxt_; +}; + +proc_outcome_t ngap_ue_initial_context_setup_proc::init(const asn1::ngap_nr::init_context_setup_request_s& msg) +{ + ue_ctxt->amf_pointer = msg.protocol_ies.guami.value.amf_pointer.to_number(); + ue_ctxt->amf_set_id = msg.protocol_ies.guami.value.amf_set_id.to_number(); + ue_ctxt->amf_region_id = msg.protocol_ies.guami.value.amf_region_id.to_number(); + + if (msg.protocol_ies.ue_aggregate_maximum_bit_rate_present == true) { + rrc->ue_set_bitrates(ue_ctxt->rnti, msg.protocol_ies.ue_aggregate_maximum_bit_rate.value); + } + 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()."); + 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)); + } + return proc_outcome_t::yield; +}; + +proc_outcome_t ngap_ue_initial_context_setup_proc::react(bool security_mode_command_outcome) +{ + if(security_mode_command_outcome == true) { + parent->send_initial_ctxt_setup_response(); + return proc_outcome_t::success; + } + // TODO: error handling if security mode command fails + return proc_outcome_t::error; +} + +proc_outcome_t ngap_ue_initial_context_setup_proc::step() +{ + return proc_outcome_t::yield; +} + +ngap_ue_ue_context_release_proc::ngap_ue_ue_context_release_proc(ngap_interface_ngap_proc* parent_, + rrc_interface_ngap_nr* rrc_, + ngap_ue_ctxt_t* ue_ctxt_) : + logger(srslog::fetch_basic_logger("NGAP UE")) +{ + parent = parent_; + rrc = rrc_; + ue_ctxt = ue_ctxt_; +}; + +proc_outcome_t ngap_ue_ue_context_release_proc::init(const asn1::ngap_nr::ue_context_release_cmd_s& msg) +{ + // ue_ngap_ids_c ue_ngap_ids = msg.protocol_ies.ue_ngap_ids.value; + // cause_c cause = msg.protocol_ies.cause.value; + return proc_outcome_t::success; +} + +proc_outcome_t ngap_ue_ue_context_release_proc::step() +{ + return proc_outcome_t::success; +} + +} // namespace srsenb \ No newline at end of file diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 10b02cd36..8b721b1af 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -366,6 +366,28 @@ void rrc_nr::write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_ void rrc_nr::notify_pdcp_integrity_error(uint16_t rnti, uint32_t lcid) {} +/******************************************************************************* + NGAP interface +*******************************************************************************/ + +int rrc_nr::ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) +{ + return SRSRAN_SUCCESS; +} +int rrc_nr::ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) +{ + return SRSRAN_SUCCESS; +} +int rrc_nr::ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) +{ + return SRSRAN_SUCCESS; +} +int rrc_nr::start_security_mode_procedure(uint16_t rnti) +{ + return SRSRAN_SUCCESS; +} +void rrc_nr::write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {} + /******************************************************************************* Interface for EUTRA RRC *******************************************************************************/ diff --git a/srsenb/test/ngap/ngap_test.cc b/srsenb/test/ngap/ngap_test.cc index 24a556b31..834990974 100644 --- a/srsenb/test/ngap/ngap_test.cc +++ b/srsenb/test/ngap/ngap_test.cc @@ -62,6 +62,24 @@ struct amf_dummy { srsran::unique_byte_buffer_t last_sdu; }; +class rrc_nr_dummy : public rrc_interface_ngap_nr +{ +public: + int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) + { + return SRSRAN_SUCCESS; + } + int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) + { + return SRSRAN_SUCCESS; + } + int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) + { + return SRSRAN_SUCCESS; + } + int start_security_mode_procedure(uint16_t rnti) { return SRSRAN_SUCCESS; } + void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {} +}; struct dummy_socket_manager : public srsran::socket_manager_itf { dummy_socket_manager() : srsran::socket_manager_itf(srslog::fetch_basic_logger("TEST")) {} @@ -143,7 +161,8 @@ int main(int argc, char** argv) args.gtp_bind_addr = "127.0.0.100"; args.amf_addr = "127.0.0.1"; args.gnb_name = "srsgnb01"; - rrc_interface_ngap_nr rrc; + + rrc_nr_dummy rrc; ngap_obj.init(args, &rrc); // Start the log backend.