From 144a8af2e4540298cefd1879f2c92493ad3a1053 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 21:03:22 +0100 Subject: [PATCH] e2ap: add e2sm base class, clean e2ap::generate_setup_request func, fill e2ap_kpm desc properly --- srsgnb/hdr/stack/ric/e2sm.h | 55 ++++++++++++++ srsgnb/hdr/stack/ric/e2sm_kpm.h | 26 +++---- srsgnb/src/stack/ric/e2ap.cc | 41 +++++------ srsgnb/src/stack/ric/e2sm_kpm.cc | 120 +++++++++++++++++-------------- 4 files changed, 152 insertions(+), 90 deletions(-) create mode 100644 srsgnb/hdr/stack/ric/e2sm.h diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h new file mode 100644 index 000000000..6a9826a5c --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -0,0 +1,55 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2022 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 "srsran/common/byte_buffer.h" +#include "srsran/srsran.h" + +#ifndef SRSRAN_E2SM_H +#define SRSRAN_E2SM_H + +enum e2sm_type_t { E2SM_KPM, UNKNOWN }; + +struct RANfunction_description; + +class e2sm +{ +public: + e2sm(); + e2sm(std::string short_name, std::string oid, std::string func_description, uint32_t revision) : + _short_name(short_name), _oid(oid), _func_description(func_description), _revision(revision){}; + virtual ~e2sm() = default; + + std::string get_short_name() { return _short_name; }; + std::string get_oid() { return _oid; }; + std::string get_func_description() { return _func_description; }; + uint32_t get_revision() { return _revision; }; + + virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf) = 0; + +private: + const std::string _short_name; + const std::string _oid; + const std::string _func_description; + const uint32_t _revision; +}; + +struct RANfunction_description { + bool accepted = false; + int function_instance = 0; + e2sm_type_t sm_type; + e2sm* sm_ptr; + std::string function_shortname; + std::string function_e2_sm_oid; + std::string function_desc; +}; + +#endif // SRSRAN_E2SM_H diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index adec8fc9a..acb6cee57 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -10,6 +10,7 @@ * * */ +#include "e2sm.h" #include "srsran/asn1/e2sm.h" #include "srsran/asn1/e2sm_kpm_v2.h" #include "srsran/srsran.h" @@ -17,13 +18,6 @@ #ifndef RIC_E2SM_KPM_H #define RIC_E2SM_KPM_H -struct RANfunction_description { - bool accepted = false; - std::string function_desc; - std::string function_shortname; - std::string function_e2_sm_oid; - int function_instance; - struct RIC_indication_header { uint32_t collet_start_time; std::string file_formatversion; @@ -39,15 +33,21 @@ struct RIC_indication_message { uint64_t granul_period = 0; }; -class e2sm_kpm +class e2sm_kpm : public e2sm { public: + static const std::string short_name; + static const std::string oid; + static const std::string func_description; + static const uint32_t revision; + e2sm_kpm(srslog::basic_logger& logger_); - bool - generate_ran_function_description(int function_id, RANfunction_description desc, srsran::unique_byte_buffer_t& buf); - int process_ric_action_definition(); - bool generate_indication_header(RIC_indication_header hdr, srsran::unique_byte_buffer_t& buf); - bool generate_indication_message(RIC_indication_message msg, srsran::unique_byte_buffer_t& buf); + ~e2sm_kpm() = default; + + virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf); + int process_ric_action_definition(); + bool generate_indication_header(RIC_indication_header hdr, srsran::unique_byte_buffer_t& buf); + bool generate_indication_message(RIC_indication_message msg, srsran::unique_byte_buffer_t& buf); private: srslog::basic_logger& logger; diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index a5a19a307..de41fa3fc 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -13,51 +13,44 @@ e2_ap_pdu_c e2ap::generate_setup_request() init_msg_s& initmsg = pdu.set_init_msg(); initmsg.load_info_obj(ASN1_E2AP_ID_E2SETUP); - e2setup_request_s& setup = initmsg.value.e2setup_request(); - + e2setup_request_s& setup = initmsg.value.e2setup_request(); setup->transaction_id.crit = asn1::crit_opts::reject; setup->transaction_id.value.value = setup_procedure_transaction_id; setup->global_e2node_id.crit = asn1::crit_opts::reject; - auto& gnb_ = setup->global_e2node_id.value.set_gnb(); + auto& gnb_ = setup->global_e2node_id.value.set_gnb(); gnb_.global_g_nb_id.plmn_id.from_number(plmn_id); gnb_.global_g_nb_id.gnb_id.gnb_id().from_number(gnb_id, 28); // TODO: to keep flexric happy, provide them feedback + // add all supported e2SM functions setup->ra_nfunctions_added.crit = asn1::crit_opts::reject; - auto& list = setup->ra_nfunctions_added.value; + auto& ra_nfunc_list = setup->ra_nfunctions_added.value; + ra_nfunc_list.resize(1); - setup->ra_nfunctions_added.id = ASN1_E2AP_ID_RA_NFUNCTIONS_ADDED; - asn1::protocol_ie_single_container_s item; - item.load_info_obj(ASN1_E2AP_ID_RA_NFUNCTION_ITEM); - item.value().ra_nfunction_item().ran_function_id = 147; - item.value().ra_nfunction_item().ran_function_revision = 0; + // E2SM-KPM + uint32_t local_ran_function_id = 147; + ra_nfunction_item_s& ran_func = ra_nfunc_list[0].value().ra_nfunction_item(); + ran_func.ran_function_id = local_ran_function_id; + ran_func.ran_function_revision = e2sm_.get_revision(); + ran_func.ran_function_oid.from_string(e2sm_.get_oid().c_str()); - // pack E2SM-KPM-PDU into ran function definition // add function to map RANfunction_description add_func; - add_func.function_desc = "KPM monitor"; - add_func.function_shortname = "ORAN-E2SM-KPM"; - add_func.function_e2_sm_oid = "1.3.6.1.4.1.53148.1.2.2.2"; - add_func.function_instance = 0; - ran_functions[item.value().ra_nfunction_item().ran_function_id] = add_func; + add_func.function_instance = 0; + add_func.sm_type = e2sm_type_t::E2SM_KPM; + add_func.sm_ptr = &e2sm_; + ran_functions[local_ran_function_id] = add_func; - auto& ran_func_def = item.value().ra_nfunction_item().ran_function_definition; + auto& ran_func_def = ran_func.ran_function_definition; srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); - e2sm_.generate_ran_function_description(item.value().ra_nfunction_item().ran_function_id, add_func, buf); + e2sm_.generate_ran_function_description(add_func, buf); ran_func_def.resize(buf->N_bytes); buf->msg[1] = 0x30; // TODO: needed to keep wireshak happy, need better fix std::copy(buf->msg, buf->msg + buf->N_bytes, ran_func_def.data()); - std::string oid_str = "ORAN-E2SM-KPM"; - item.value().ra_nfunction_item().ran_function_oid.resize(oid_str.size()); - item.value().ra_nfunction_item().ran_function_oid.from_string(oid_str); - - setup->ra_nfunctions_added.value.push_back(item); - setup->e2node_component_cfg_addition.crit = asn1::crit_opts::reject; auto& list1 = setup->e2node_component_cfg_addition.value; list1.resize(1); - list1[0].load_info_obj(ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_ADDITION_ITEM); e2node_component_cfg_addition_item_s& item1 = list1[0].value().e2node_component_cfg_addition_item(); item1.e2node_component_interface_type = e2node_component_interface_type_opts::ng; item1.e2node_component_id.set_e2node_component_interface_type_ng().amf_name.from_string("nginterf"); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index e885a97c5..d82d3acfb 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -1,63 +1,77 @@ #include "srsgnb/hdr/stack/ric/e2sm_kpm.h" -e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : logger(logger_) {} +const std::string e2sm_kpm::short_name = "ORAN-E2SM-KPM"; +const std::string e2sm_kpm::oid = "1.3.6.1.4.1.53148.1.2.2.2"; +const std::string e2sm_kpm::func_description = "KPM Monitor"; +const uint32_t e2sm_kpm::revision = 0; -bool e2sm_kpm::generate_ran_function_description(int function_id, - RANfunction_description desc, - srsran::unique_byte_buffer_t& buf) +e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_description, revision), logger(logger_) +{ +} + +bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf) { using namespace asn1::e2sm_kpm; + desc.function_shortname = short_name; + desc.function_e2_sm_oid = oid; + desc.function_desc = func_description; + e2_sm_kpm_ra_nfunction_description_s e2sm_kpm_ra_nfunction_description; - e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_instance_present = false; - // e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_instance = desc.function_instance; - e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_short_name.from_string(desc.function_shortname); - e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_e2_sm_oid.from_string(desc.function_e2_sm_oid); - e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_description.from_string(desc.function_desc); - - /* - e2sm_kpm_ra_nfunction_description.e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list.resize(1); - auto& ric_event_trigger_style_list_item = - e2sm_kpm_ra_nfunction_description.e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list[0]; - ric_event_trigger_style_list_item.ric_event_trigger_format_type = 5; - ric_event_trigger_style_list_item.ric_event_trigger_style_type = 1; - ric_event_trigger_style_list_item.ric_event_trigger_style_name.from_string("Periodic report"); - auto& list = e2sm_kpm_ra_nfunction_description.e2_sm_kpm_ra_nfunction_item.ric_report_style_list; - list.resize(6); - for (int i = 0; i < (int)list.size(); i++) { - auto& ric_report_style_list_item = - e2sm_kpm_ra_nfunction_description.e2_sm_kpm_ra_nfunction_item.ric_report_style_list[i]; - ric_report_style_list_item.ric_ind_hdr_format_type = 1; - ric_report_style_list_item.ric_ind_msg_format_type = 1; - ric_report_style_list_item.ric_report_style_type = i + 1; - switch (i) { - case 0: - ric_report_style_list_item.ric_report_style_name.from_string( - "O-DU Measurement Container for the 5GC connected deployment"); - break; - case 1: - ric_report_style_list_item.ric_report_style_name.from_string( - "O-DU Measurement Container for the EPC connected deployment"); - break; - case 2: - ric_report_style_list_item.ric_report_style_name.from_string( - "O-CU-CP Measurement Container for the 5GC connected deployment"); - break; - case 3: - ric_report_style_list_item.ric_report_style_name.from_string( - "O-CU-CP Measurement Container for the EPC connected deployment"); - break; - case 4: - ric_report_style_list_item.ric_report_style_name.from_string( - "O-CU-UP Measurement Container for the 5GC connected deployment"); - break; - case 5: - ric_report_style_list_item.ric_report_style_name.from_string( - "O-CU-UP Measurement Container for the EPC connected deployment"); - break; - }; - ric_report_style_list_item.ric_report_style_name.from_string("Periodic report"); + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_short_name.from_string(short_name.c_str()); + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_e2_sm_oid.from_string(oid.c_str()); + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_description.from_string(func_description.c_str()); + if (desc.function_instance) { + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_instance_present = true; + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_instance = desc.function_instance; } - */ + + // O-RAN.WG3.E2SM-KPM-R003-v03.00, 7.3.1 Event Trigger Style Types + auto& event_trigger_style_list = e2sm_kpm_ra_nfunction_description.ric_event_trigger_style_list; + event_trigger_style_list.resize(1); + event_trigger_style_list[0].ric_event_trigger_style_type = 1; + event_trigger_style_list[0].ric_event_trigger_style_name.from_string("Periodic report"); + event_trigger_style_list[0].ric_event_trigger_format_type = 1; // uses RIC Event Trigger Definition Format 1 + + // O-RAN.WG3.E2SM-KPM-R003-v03.00, 7.4.1 REPORT Service Style Type + auto& report_style_list = e2sm_kpm_ra_nfunction_description.ric_report_style_list; + report_style_list.resize(5); + + report_style_list[0].ric_report_style_type = 1; + report_style_list[0].ric_report_style_name.from_string("E2 Node Measurement"); + report_style_list[0].ric_action_format_type = 1; + report_style_list[0].ric_ind_hdr_format_type = 1; + report_style_list[0].ric_ind_msg_format_type = 1; + // A measurement ID can be used for subscription instead of a measurement type if an identifier of a certain + // measurement type was exposed by an E2 Node via the RAN Function Definition IE. + // measurement name to ID mapping (local to the E2 node), here only an example: + report_style_list[0].meas_info_action_list.resize(1); + report_style_list[0].meas_info_action_list[0].meas_name.from_string("RRU.PrbTotDl"); + report_style_list[0].meas_info_action_list[0].meas_id = 123; + + report_style_list[1].ric_report_style_type = 2; + report_style_list[1].ric_report_style_name.from_string("E2 Node Measurement for a single UE"); + report_style_list[1].ric_action_format_type = 2; // includes UE ID + report_style_list[1].ric_ind_hdr_format_type = 1; + report_style_list[1].ric_ind_msg_format_type = 1; + + report_style_list[2].ric_report_style_type = 3; + report_style_list[2].ric_report_style_name.from_string("Condition-based, UE-level E2 Node Measurement"); + report_style_list[2].ric_action_format_type = 3; + report_style_list[2].ric_ind_hdr_format_type = 1; + report_style_list[2].ric_ind_msg_format_type = 2; + + report_style_list[3].ric_report_style_type = 4; + report_style_list[3].ric_report_style_name.from_string("Common Condition-based, UE-level Measurement"); + report_style_list[3].ric_action_format_type = 4; + report_style_list[3].ric_ind_hdr_format_type = 1; + report_style_list[3].ric_ind_msg_format_type = 3; + + report_style_list[4].ric_report_style_type = 5; + report_style_list[4].ric_report_style_name.from_string("E2 Node Measurement for multiple UEs"); + report_style_list[4].ric_action_format_type = 5; + report_style_list[4].ric_ind_hdr_format_type = 1; + report_style_list[4].ric_ind_msg_format_type = 3; + logger.info("Generating RAN function description"); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); if (e2sm_kpm_ra_nfunction_description.pack(bref) != asn1::SRSASN_SUCCESS) {