From 524008345473def08b2e42848c7a0002af73612c Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 5 Apr 2023 13:15:37 +0200 Subject: [PATCH 001/167] eMBMS: adding mutex to mbsfn configuration in the eNodeB --- srsenb/hdr/phy/phy_common.h | 1 + srsenb/src/phy/phy_common.cc | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/srsenb/hdr/phy/phy_common.h b/srsenb/hdr/phy/phy_common.h index 3d16c4371..0cb27581c 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -301,6 +301,7 @@ private: bool have_mtch_stop = false; std::mutex mtch_mutex; + std::mutex mbsfn_mutex; std::condition_variable mtch_cvar; srsran::phy_cfg_mbsfn_t mbsfn = {}; bool sib13_configured = false; diff --git a/srsenb/src/phy/phy_common.cc b/srsenb/src/phy/phy_common.cc index f5dc8131d..d3bac4986 100644 --- a/srsenb/src/phy/phy_common.cc +++ b/srsenb/src/phy/phy_common.cc @@ -60,9 +60,12 @@ bool phy_common::init(const phy_cell_cfg_list_t& cell_list_, if (!cell_list_lte.empty()) { ue_db.init(stack, params, cell_list_lte); } - if (mcch_configured) { - build_mch_table(); - build_mcch_table(); + { + std::lock_guard lock(mbsfn_mutex); + if (mcch_configured) { + build_mch_table(); + build_mcch_table(); + } } reset(); @@ -168,6 +171,7 @@ void phy_common::set_mch_period_stop(uint32_t stop) void phy_common::configure_mbsfn(srsran::phy_cfg_mbsfn_t* cfg) { + std::lock_guard lock(mbsfn_mutex); mbsfn = *cfg; sib13_configured = true; mcch_configured = true; From 07d1f14fab51fb211e82d6457202ced3f865862a Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 5 Apr 2023 13:17:33 +0200 Subject: [PATCH 002/167] eMBMS: pushing bsr update to task queue to avoid potential deadlock --- srsenb/src/stack/mac/mac.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 17e036880..9b22381f7 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -130,17 +130,20 @@ void mac::start_pcap_net(srsran::mac_pcap_net* pcap_net_) int mac::rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) { - srsran::rwlock_read_guard lock(rwlock); int ret = -1; if (check_ue_active(rnti)) { if (rnti != SRSRAN_MRNTI) { + srsran::rwlock_write_guard lock(rwlock); ret = scheduler.dl_rlc_buffer_state(rnti, lc_id, tx_queue, retx_queue); } else { - for (uint32_t i = 0; i < mch.num_mtch_sched; i++) { - if (lc_id == mch.mtch_sched[i].lcid) { - mch.mtch_sched[i].lcid_buffer_size = tx_queue; + task_sched.defer_callback(0, [this, tx_queue, lc_id]() { + srsran::rwlock_write_guard lock(rwlock); + for (uint32_t i = 0; i < mch.num_mtch_sched; i++) { + if (lc_id == mch.mtch_sched[i].lcid) { + mch.mtch_sched[i].lcid_buffer_size = tx_queue; + } } - } + }); ret = 0; } } From f9686e5fce1c44aedbfb9bde2675a62cca2ba723 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 5 Apr 2023 14:51:53 +0200 Subject: [PATCH 003/167] eMBMS: moving RRC add_user call for MRNTI to avoiding potential deadlock --- srsenb/src/stack/mac/mac.cc | 1 - srsenb/src/stack/rrc/rrc.cc | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 9b22381f7..c11aa7bc2 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -1056,7 +1056,6 @@ void mac::write_mcch(const srsran::sib2_mbms_t* sib2_, if (!ret) { logger.info("Failed to allocate rnti=0x%x.for eMBMS", SRSRAN_MRNTI); } - rrc_h->add_user(SRSRAN_MRNTI, {}); } // Internal helper function, caller must hold UE DB rwlock diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index fa20eab80..93fb90161 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -951,6 +951,7 @@ void rrc::configure_mbsfn_sibs() task_sched.defer_task([this, sibs2, sibs13, mcch_t]() mutable { phy->configure_mbsfn(&sibs2, &sibs13, mcch_t); mac->write_mcch(&sibs2, &sibs13, &mcch_t, mcch_payload_buffer, current_mcch_length); + add_user(SRSRAN_MRNTI, {}); }); } From 6f95418689b158807035d411bc87d47c4749758b Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 5 Apr 2023 14:54:18 +0200 Subject: [PATCH 004/167] eMBMS: adding mch mutex to avoid race conditions in SIB13 R/W --- srsue/hdr/phy/phy_common.h | 1 + srsue/src/phy/phy_common.cc | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index 6de05adec..a23547a02 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -336,6 +336,7 @@ private: bool have_mtch_stop = false; std::mutex mtch_mutex; + std::mutex mch_mutex; std::condition_variable mtch_cvar; std::atomic is_pending_tx_end{false}; diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 0ca17c9ec..58ad6a5ca 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -944,6 +944,7 @@ void phy_common::reset() void phy_common::build_mch_table() { // First reset tables + std::lock_guard lock(mch_mutex); bzero(&mch_table[0], sizeof(uint8_t) * 40); // 40 element table represents 4 frames (40 subframes) @@ -966,6 +967,7 @@ void phy_common::build_mch_table() void phy_common::build_mcch_table() { + std::lock_guard lock(mch_mutex); // First reset tables bzero(&mcch_table[0], sizeof(uint8_t) * 10); generate_mcch_table(&mcch_table[0], (uint32_t)mbsfn_config.mbsfn_area_info.mcch_cfg.sf_alloc_info); @@ -1023,7 +1025,7 @@ bool phy_common::is_mch_subframe(srsran_mbsfn_cfg_t* cfg, uint32_t phy_tti) cfg->mbsfn_mcs = 2; cfg->enable = false; cfg->is_mcch = false; - + std::lock_guard lock(mch_mutex); // Check for MCCH if (is_mcch_subframe(cfg, phy_tti)) { cfg->is_mcch = true; From cdd084adee31f8918ed447ecb58876c173801d57 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 12 Apr 2023 21:50:35 +0200 Subject: [PATCH 005/167] eMBMS,rlc: fixing deadlock by switching from write lock to read lock --- srsenb/src/stack/mac/mac.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index c11aa7bc2..1be0ab51f 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -133,11 +133,11 @@ int mac::rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint int ret = -1; if (check_ue_active(rnti)) { if (rnti != SRSRAN_MRNTI) { - srsran::rwlock_write_guard lock(rwlock); + srsran::rwlock_read_guard lock(rwlock); ret = scheduler.dl_rlc_buffer_state(rnti, lc_id, tx_queue, retx_queue); } else { task_sched.defer_callback(0, [this, tx_queue, lc_id]() { - srsran::rwlock_write_guard lock(rwlock); + srsran::rwlock_read_guard lock(rwlock); for (uint32_t i = 0; i < mch.num_mtch_sched; i++) { if (lc_id == mch.mtch_sched[i].lcid) { mch.mtch_sched[i].lcid_buffer_size = tx_queue; From 554c6c62f50f7de08e12a1c559bffae4d441580f Mon Sep 17 00:00:00 2001 From: yagoda Date: Mon, 14 Nov 2022 12:07:03 +0100 Subject: [PATCH 006/167] e2ap, asn1: adding initial support for e2ap ORAN interfacec --- lib/include/srsran/asn1/e2ap.h | 4486 ++++++ lib/include/srsran/asn1/e2sm.h | 1344 ++ lib/src/asn1/CMakeLists.txt | 6 +- lib/src/asn1/e2ap.cpp | 16048 +++++++++++++++++++++ lib/src/asn1/e2sm.cpp | 3065 ++++ srsenb/hdr/enb.h | 2 + srsenb/src/CMakeLists.txt | 4 +- srsenb/src/enb.cc | 11 +- srsgnb/hdr/stack/ric/e2ap.h | 36 + srsgnb/hdr/stack/ric/ric_client.h | 42 + srsgnb/src/stack/CMakeLists.txt | 1 + srsgnb/src/stack/ric/CMakeLists.txt | 5 + srsgnb/src/stack/ric/e2ap.cc | 53 + srsgnb/src/stack/ric/ric_client.cc | 105 + srsgnb/src/stack/ric/test/CMakeLists.txt | 12 + srsgnb/src/stack/ric/test/e2ap_test.cc | 106 + 16 files changed, 25322 insertions(+), 4 deletions(-) create mode 100644 lib/include/srsran/asn1/e2ap.h create mode 100644 lib/include/srsran/asn1/e2sm.h create mode 100644 lib/src/asn1/e2ap.cpp create mode 100644 lib/src/asn1/e2sm.cpp create mode 100644 srsgnb/hdr/stack/ric/e2ap.h create mode 100644 srsgnb/hdr/stack/ric/ric_client.h create mode 100644 srsgnb/src/stack/ric/CMakeLists.txt create mode 100644 srsgnb/src/stack/ric/e2ap.cc create mode 100644 srsgnb/src/stack/ric/ric_client.cc create mode 100644 srsgnb/src/stack/ric/test/CMakeLists.txt create mode 100644 srsgnb/src/stack/ric/test/e2ap_test.cc diff --git a/lib/include/srsran/asn1/e2ap.h b/lib/include/srsran/asn1/e2ap.h new file mode 100644 index 000000000..650a0bc01 --- /dev/null +++ b/lib/include/srsran/asn1/e2ap.h @@ -0,0 +1,4486 @@ +/** + * + * \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. + * + */ + +/******************************************************************************* + * + * 3GPP TS ASN1 E2AP v15.3.0 (2019-03) + * + ******************************************************************************/ + +#ifndef SRSASN1_E2AP_H +#define SRSASN1_E2AP_H + +#include "asn1_utils.h" +#include +#include + +namespace asn1 { +namespace e2ap { + +/******************************************************************************* + * Constant Definitions + ******************************************************************************/ + +#define ASN1_E2AP_ID_E2SETUP 1 +#define ASN1_E2AP_ID_ERROR_IND 2 +#define ASN1_E2AP_ID_RESET 3 +#define ASN1_E2AP_ID_RI_CCTRL 4 +#define ASN1_E2AP_ID_RI_CIND 5 +#define ASN1_E2AP_ID_RICSERVICE_QUERY 6 +#define ASN1_E2AP_ID_RICSERVICE_UPD 7 +#define ASN1_E2AP_ID_RICSUBSCRIPTION 8 +#define ASN1_E2AP_ID_RICSUBSCRIPTION_DELETE 9 +#define ASN1_E2AP_ID_E2NODE_CFG_UPD 10 +#define ASN1_E2AP_ID_E2CONN_UPD 11 +#define ASN1_E2AP_ID_RICSUBSCRIPTION_DELETE_REQUIRED 12 +#define ASN1_E2AP_ID_E2REMOVAL 13 +#define ASN1_E2AP_MAX_PROTOCOL_IES 65535 +#define ASN1_E2AP_MAXNOOF_ERRORS 256 +#define ASN1_E2AP_MAXOF_E2NODE_COMPONENTS 1024 +#define ASN1_E2AP_MAXOF_RA_NFUNCTION_ID 256 +#define ASN1_E2AP_MAXOF_RI_CACTION_ID 16 +#define ASN1_E2AP_MAXOF_TNLA 32 +#define ASN1_E2AP_MAXOF_RI_CREQUEST_ID 1024 +#define ASN1_E2AP_ID_CAUSE 1 +#define ASN1_E2AP_ID_CRIT_DIAGNOSTICS 2 +#define ASN1_E2AP_ID_GLOBAL_E2NODE_ID 3 +#define ASN1_E2AP_ID_GLOBAL_RIC_ID 4 +#define ASN1_E2AP_ID_RA_NFUNCTION_ID 5 +#define ASN1_E2AP_ID_RA_NFUNCTION_ID_ITEM 6 +#define ASN1_E2AP_ID_RA_NFUNCTION_IECAUSE_ITEM 7 +#define ASN1_E2AP_ID_RA_NFUNCTION_ITEM 8 +#define ASN1_E2AP_ID_RA_NFUNCTIONS_ACCEPTED 9 +#define ASN1_E2AP_ID_RA_NFUNCTIONS_ADDED 10 +#define ASN1_E2AP_ID_RA_NFUNCTIONS_DELETED 11 +#define ASN1_E2AP_ID_RA_NFUNCTIONS_MODIFIED 12 +#define ASN1_E2AP_ID_RA_NFUNCTIONS_REJECTED 13 +#define ASN1_E2AP_ID_RI_CACTION_ADMITTED_ITEM 14 +#define ASN1_E2AP_ID_RI_CACTION_ID 15 +#define ASN1_E2AP_ID_RI_CACTION_NOT_ADMITTED_ITEM 16 +#define ASN1_E2AP_ID_RI_CACTIONS_ADMITTED 17 +#define ASN1_E2AP_ID_RI_CACTIONS_NOT_ADMITTED 18 +#define ASN1_E2AP_ID_RI_CACTION_TO_BE_SETUP_ITEM 19 +#define ASN1_E2AP_ID_RI_CCALL_PROCESS_ID 20 +#define ASN1_E2AP_ID_RI_CCTRL_ACK_REQUEST 21 +#define ASN1_E2AP_ID_RI_CCTRL_HDR 22 +#define ASN1_E2AP_ID_RI_CCTRL_MSG 23 +#define ASN1_E2AP_ID_RI_CCTRL_STATUS 24 +#define ASN1_E2AP_ID_RI_CIND_HDR 25 +#define ASN1_E2AP_ID_RI_CIND_MSG 26 +#define ASN1_E2AP_ID_RI_CIND_SN 27 +#define ASN1_E2AP_ID_RI_CIND_TYPE 28 +#define ASN1_E2AP_ID_RI_CREQUEST_ID 29 +#define ASN1_E2AP_ID_RICSUBSCRIPTION_DETAILS 30 +#define ASN1_E2AP_ID_TIME_TO_WAIT 31 +#define ASN1_E2AP_ID_RI_CCTRL_OUTCOME 32 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_UPD 33 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_UPD_ITEM 34 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_UPD_ACK 35 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_UPD_ACK_ITEM 36 +#define ASN1_E2AP_ID_E2CONN_SETUP 39 +#define ASN1_E2AP_ID_E2CONN_SETUP_FAILED 40 +#define ASN1_E2AP_ID_E2CONN_SETUP_FAILED_ITEM 41 +#define ASN1_E2AP_ID_E2CONN_FAILED_ITEM 42 +#define ASN1_E2AP_ID_E2CONN_UPD_ITEM 43 +#define ASN1_E2AP_ID_E2CONN_UPD_ADD 44 +#define ASN1_E2AP_ID_E2CONN_UPD_MODIFY 45 +#define ASN1_E2AP_ID_E2CONN_UPD_REM 46 +#define ASN1_E2AP_ID_E2CONN_UPD_REM_ITEM 47 +#define ASN1_E2AP_ID_TN_LINFO 48 +#define ASN1_E2AP_ID_TRANSACTION_ID 49 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_ADDITION 50 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_ADDITION_ITEM 51 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_ADDITION_ACK 52 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_ADDITION_ACK_ITEM 53 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_REMOVAL 54 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_REMOVAL_ITEM 55 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_REMOVAL_ACK 56 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_REMOVAL_ACK_ITEM 57 +#define ASN1_E2AP_ID_E2NODE_TN_LASSOC_REMOVAL 58 +#define ASN1_E2AP_ID_E2NODE_TN_LASSOC_REMOVAL_ITEM 59 +#define ASN1_E2AP_ID_RICSUBSCRIPTION_TO_BE_REMD 60 +#define ASN1_E2AP_ID_RICSUBSCRIPTION_WITH_CAUSE_ITEM 61 + +/******************************************************************************* + * Struct Definitions + ******************************************************************************/ + +// CauseE2node ::= ENUMERATED +struct cause_e2node_opts { + enum options { e2node_component_unknown, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated cause_e2node_e; + +// CauseMisc ::= ENUMERATED +struct cause_misc_opts { + enum options { ctrl_processing_overload, hardware_fail, om_intervention, unspecified, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated cause_misc_e; + +// CauseProtocol ::= ENUMERATED +struct cause_protocol_opts { + enum options { + transfer_syntax_error, + abstract_syntax_error_reject, + abstract_syntax_error_ignore_and_notify, + msg_not_compatible_with_receiver_state, + semantic_error, + abstract_syntax_error_falsely_constructed_msg, + unspecified, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated cause_protocol_e; + +// CauseRICrequest ::= ENUMERATED +struct cause_ri_crequest_opts { + enum options { + ran_function_id_invalid, + action_not_supported, + excessive_actions, + duplicate_action, + duplicate_event_trigger, + function_res_limit, + request_id_unknown, + inconsistent_action_subsequent_action_seq, + ctrl_msg_invalid, + ric_call_process_id_invalid, + ctrl_timer_expired, + ctrl_failed_to_execute, + sys_not_ready, + unspecified, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated cause_ri_crequest_e; + +// CauseRICservice ::= ENUMERATED +struct cause_ricservice_opts { + enum options { ran_function_not_supported, excessive_functions, ric_res_limit, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated cause_ricservice_e; + +// CauseTransport ::= ENUMERATED +struct cause_transport_opts { + enum options { unspecified, transport_res_unavailable, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated cause_transport_e; + +// Cause ::= CHOICE +struct cause_c { + struct types_opts { + enum options { ric_request, ric_service, e2_node, transport, protocol, misc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + cause_c() = default; + cause_c(const cause_c& other); + cause_c& operator=(const cause_c& other); + ~cause_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + cause_ri_crequest_e& ric_request() + { + assert_choice_type(types::ric_request, type_, "Cause"); + return c.get(); + } + cause_ricservice_e& ric_service() + { + assert_choice_type(types::ric_service, type_, "Cause"); + return c.get(); + } + cause_e2node_e& e2_node() + { + assert_choice_type(types::e2_node, type_, "Cause"); + return c.get(); + } + cause_transport_e& transport() + { + assert_choice_type(types::transport, type_, "Cause"); + return c.get(); + } + cause_protocol_e& protocol() + { + assert_choice_type(types::protocol, type_, "Cause"); + return c.get(); + } + cause_misc_e& misc() + { + assert_choice_type(types::misc, type_, "Cause"); + return c.get(); + } + const cause_ri_crequest_e& ric_request() const + { + assert_choice_type(types::ric_request, type_, "Cause"); + return c.get(); + } + const cause_ricservice_e& ric_service() const + { + assert_choice_type(types::ric_service, type_, "Cause"); + return c.get(); + } + const cause_e2node_e& e2_node() const + { + assert_choice_type(types::e2_node, type_, "Cause"); + return c.get(); + } + const cause_transport_e& transport() const + { + assert_choice_type(types::transport, type_, "Cause"); + return c.get(); + } + const cause_protocol_e& protocol() const + { + assert_choice_type(types::protocol, type_, "Cause"); + return c.get(); + } + const cause_misc_e& misc() const + { + assert_choice_type(types::misc, type_, "Cause"); + return c.get(); + } + cause_ri_crequest_e& set_ric_request(); + cause_ricservice_e& set_ric_service(); + cause_e2node_e& set_e2_node(); + cause_transport_e& set_transport(); + cause_protocol_e& set_protocol(); + cause_misc_e& set_misc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// TypeOfError ::= ENUMERATED +struct type_of_error_opts { + enum options { not_understood, missing, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated type_of_error_e; + +// CriticalityDiagnostics-IE-Item ::= SEQUENCE +struct crit_diagnostics_ie_item_s { + bool ext = false; + crit_e iecrit; + uint32_t ie_id = 0; + type_of_error_e type_of_error; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..256)) OF CriticalityDiagnostics-IE-Item +using crit_diagnostics_ie_list_l = dyn_array; + +// RICrequestID ::= SEQUENCE +struct ri_crequest_id_s { + bool ext = false; + uint32_t ric_requestor_id = 0; + uint32_t ric_instance_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TriggeringMessage ::= ENUMERATED +struct trigger_msg_opts { + enum options { init_msg, successful_outcome, unsuccessfull_outcome, nulltype } value; + + const char* to_string() const; +}; +typedef enumerated trigger_msg_e; + +// CriticalityDiagnostics ::= SEQUENCE +struct crit_diagnostics_s { + bool ext = false; + bool proc_code_present = false; + bool trigger_msg_present = false; + bool proc_crit_present = false; + bool ric_requestor_id_present = false; + uint16_t proc_code = 0; + trigger_msg_e trigger_msg; + crit_e proc_crit; + ri_crequest_id_s ric_requestor_id; + crit_diagnostics_ie_list_l ies_crit_diagnostics; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ENB-ID-Choice ::= CHOICE +struct enb_id_choice_c { + struct types_opts { + enum options { enb_id_macro, enb_id_shortmacro, enb_id_longmacro, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_choice_c() = default; + enb_id_choice_c(const enb_id_choice_c& other); + enb_id_choice_c& operator=(const enb_id_choice_c& other); + ~enb_id_choice_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& enb_id_macro() + { + assert_choice_type(types::enb_id_macro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<18, false, true>& enb_id_shortmacro() + { + assert_choice_type(types::enb_id_shortmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<21, false, true>& enb_id_longmacro() + { + assert_choice_type(types::enb_id_longmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& enb_id_macro() const + { + assert_choice_type(types::enb_id_macro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& enb_id_shortmacro() const + { + assert_choice_type(types::enb_id_shortmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& enb_id_longmacro() const + { + assert_choice_type(types::enb_id_longmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_enb_id_macro(); + fixed_bitstring<18, false, true>& set_enb_id_shortmacro(); + fixed_bitstring<21, false, true>& set_enb_id_longmacro(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// GNB-ID-Choice ::= CHOICE +struct gnb_id_choice_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// ENB-ID ::= CHOICE +struct enb_id_c { + struct types_opts { + enum options { macro_enb_id, home_enb_id, /*...*/ short_macro_enb_id, long_macro_enb_id, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_c() = default; + enb_id_c(const enb_id_c& other); + enb_id_c& operator=(const enb_id_c& other); + ~enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_enb_id() + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<28, false, true>& home_enb_id() + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_enb_id() + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_enb_id() + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_enb_id() const + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<28, false, true>& home_enb_id() const + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_enb_id() const + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_enb_id() const + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_enb_id(); + fixed_bitstring<28, false, true>& set_home_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// ENGNB-ID ::= CHOICE +struct engnb_id_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalgNB-ID ::= SEQUENCE +struct globalg_nb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + gnb_id_choice_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalngeNB-ID ::= SEQUENCE +struct globalngenb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_choice_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalENB-ID ::= SEQUENCE +struct global_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalNG-RANNode-ID ::= CHOICE +struct global_ng_ran_node_id_c { + struct types_opts { + enum options { gnb, ng_enb, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_ng_ran_node_id_c() = default; + global_ng_ran_node_id_c(const global_ng_ran_node_id_c& other); + global_ng_ran_node_id_c& operator=(const global_ng_ran_node_id_c& other); + ~global_ng_ran_node_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + globalg_nb_id_s& gnb() + { + assert_choice_type(types::gnb, type_, "GlobalNG-RANNode-ID"); + return c.get(); + } + globalngenb_id_s& ng_enb() + { + assert_choice_type(types::ng_enb, type_, "GlobalNG-RANNode-ID"); + return c.get(); + } + const globalg_nb_id_s& gnb() const + { + assert_choice_type(types::gnb, type_, "GlobalNG-RANNode-ID"); + return c.get(); + } + const globalngenb_id_s& ng_enb() const + { + assert_choice_type(types::ng_enb, type_, "GlobalNG-RANNode-ID"); + return c.get(); + } + globalg_nb_id_s& set_gnb(); + globalngenb_id_s& set_ng_enb(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// GlobalenGNB-ID ::= SEQUENCE +struct globalen_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + engnb_id_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubsequentActionType ::= ENUMERATED +struct ricsubsequent_action_type_opts { + enum options { continuee, wait, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated ricsubsequent_action_type_e; + +// RICtimeToWait ::= ENUMERATED +struct ri_ctime_to_wait_opts { + enum options { + w1ms, + w2ms, + w5ms, + w10ms, + w20ms, + w30ms, + w40ms, + w50ms, + w100ms, + w200ms, + w500ms, + w1s, + w2s, + w5s, + w10s, + w20s, + w60s, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated ri_ctime_to_wait_e; + +// E2nodeComponentInterfaceE1 ::= SEQUENCE +struct e2node_component_interface_e1_s { + bool ext = false; + uint64_t gnb_cu_cp_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceF1 ::= SEQUENCE +struct e2node_component_interface_f1_s { + bool ext = false; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceNG ::= SEQUENCE +struct e2node_component_interface_ng_s { + bool ext = false; + printable_string<1, 150, true, true> amf_name; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceS1 ::= SEQUENCE +struct e2node_component_interface_s1_s { + bool ext = false; + printable_string<1, 150, true, true> mme_name; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceW1 ::= SEQUENCE +struct e2node_component_interface_w1_s { + bool ext = false; + uint64_t ng_enb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceX2 ::= SEQUENCE +struct e2node_component_interface_x2_s { + bool ext = false; + bool global_enb_id_present = false; + bool global_en_g_nb_id_present = false; + global_enb_id_s global_enb_id; + globalen_gnb_id_s global_en_g_nb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceXn ::= SEQUENCE +struct e2node_component_interface_xn_s { + bool ext = false; + global_ng_ran_node_id_c global_ng_ran_node_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICactionType ::= ENUMERATED +struct ri_caction_type_opts { + enum options { report, insert, policy, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated ri_caction_type_e; + +// RICsubsequentAction ::= SEQUENCE +struct ricsubsequent_action_s { + bool ext = false; + ricsubsequent_action_type_e ric_subsequent_action_type; + ri_ctime_to_wait_e ric_time_to_wait; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfiguration ::= SEQUENCE +struct e2node_component_cfg_s { + bool ext = false; + unbounded_octstring e2node_component_request_part; + unbounded_octstring e2node_component_resp_part; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigurationAck ::= SEQUENCE +struct e2node_component_cfg_ack_s { + struct upd_outcome_opts { + enum options { success, fail, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated upd_outcome_e_; + + // member variables + bool ext = false; + bool fail_cause_present = false; + upd_outcome_e_ upd_outcome; + cause_c fail_cause; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentID ::= CHOICE +struct e2node_component_id_c { + struct types_opts { + enum options { + e2node_component_interface_type_ng, + e2node_component_interface_type_xn, + e2node_component_interface_type_e1, + e2node_component_interface_type_f1, + e2node_component_interface_type_w1, + e2node_component_interface_type_s1, + e2node_component_interface_type_x2, + // ... + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + e2node_component_id_c() = default; + e2node_component_id_c(const e2node_component_id_c& other); + e2node_component_id_c& operator=(const e2node_component_id_c& other); + ~e2node_component_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_interface_ng_s& e2node_component_interface_type_ng() + { + assert_choice_type(types::e2node_component_interface_type_ng, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_xn_s& e2node_component_interface_type_xn() + { + assert_choice_type(types::e2node_component_interface_type_xn, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_e1_s& e2node_component_interface_type_e1() + { + assert_choice_type(types::e2node_component_interface_type_e1, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_f1_s& e2node_component_interface_type_f1() + { + assert_choice_type(types::e2node_component_interface_type_f1, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_w1_s& e2node_component_interface_type_w1() + { + assert_choice_type(types::e2node_component_interface_type_w1, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_s1_s& e2node_component_interface_type_s1() + { + assert_choice_type(types::e2node_component_interface_type_s1, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_x2_s& e2node_component_interface_type_x2() + { + assert_choice_type(types::e2node_component_interface_type_x2, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_ng_s& e2node_component_interface_type_ng() const + { + assert_choice_type(types::e2node_component_interface_type_ng, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_xn_s& e2node_component_interface_type_xn() const + { + assert_choice_type(types::e2node_component_interface_type_xn, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_e1_s& e2node_component_interface_type_e1() const + { + assert_choice_type(types::e2node_component_interface_type_e1, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_f1_s& e2node_component_interface_type_f1() const + { + assert_choice_type(types::e2node_component_interface_type_f1, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_w1_s& e2node_component_interface_type_w1() const + { + assert_choice_type(types::e2node_component_interface_type_w1, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_s1_s& e2node_component_interface_type_s1() const + { + assert_choice_type(types::e2node_component_interface_type_s1, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_x2_s& e2node_component_interface_type_x2() const + { + assert_choice_type(types::e2node_component_interface_type_x2, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_ng_s& set_e2node_component_interface_type_ng(); + e2node_component_interface_xn_s& set_e2node_component_interface_type_xn(); + e2node_component_interface_e1_s& set_e2node_component_interface_type_e1(); + e2node_component_interface_f1_s& set_e2node_component_interface_type_f1(); + e2node_component_interface_w1_s& set_e2node_component_interface_type_w1(); + e2node_component_interface_s1_s& set_e2node_component_interface_type_s1(); + e2node_component_interface_x2_s& set_e2node_component_interface_type_x2(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// E2nodeComponentInterfaceType ::= ENUMERATED +struct e2node_component_interface_type_opts { + enum options { ng, xn, e1, f1, w1, s1, x2, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated e2node_component_interface_type_e; + +// RICaction-ToBeSetup-Item ::= SEQUENCE +struct ri_caction_to_be_setup_item_s { + bool ext = false; + bool ric_subsequent_action_present = false; + uint16_t ric_action_id = 0; + ri_caction_type_e ric_action_type; + unbounded_octstring ric_action_definition; + ricsubsequent_action_s ric_subsequent_action; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TNLinformation ::= SEQUENCE +struct tn_linfo_s { + bool ext = false; + bool tnl_port_present = false; + bounded_bitstring<1, 160, true, true> tnl_address; + fixed_bitstring<16, false, true> tnl_port; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TNLusage ::= ENUMERATED +struct tn_lusage_opts { + enum options { ric_service, support_function, both, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated tn_lusage_e; + +// E2connectionSetupFailed-Item ::= SEQUENCE +struct e2conn_setup_failed_item_s { + bool ext = false; + tn_linfo_s tnl_info; + cause_c cause; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionUpdate-Item ::= SEQUENCE +struct e2conn_upd_item_s { + bool ext = false; + tn_linfo_s tnl_info; + tn_lusage_e tnl_usage; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionUpdateRemove-Item ::= SEQUENCE +struct e2conn_upd_rem_item_s { + bool ext = false; + tn_linfo_s tnl_info; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigAddition-Item ::= SEQUENCE +struct e2node_component_cfg_addition_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + e2node_component_cfg_s e2node_component_cfg; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigAdditionAck-Item ::= SEQUENCE +struct e2node_component_cfg_addition_ack_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + e2node_component_cfg_ack_s e2node_component_cfg_ack; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigRemoval-Item ::= SEQUENCE +struct e2node_component_cfg_removal_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigRemovalAck-Item ::= SEQUENCE +struct e2node_component_cfg_removal_ack_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + e2node_component_cfg_ack_s e2node_component_cfg_ack; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigUpdate-Item ::= SEQUENCE +struct e2node_component_cfg_upd_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + e2node_component_cfg_s e2node_component_cfg; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigUpdateAck-Item ::= SEQUENCE +struct e2node_component_cfg_upd_ack_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + e2node_component_cfg_ack_s e2node_component_cfg_ack; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeTNLassociationRemoval-Item ::= SEQUENCE +struct e2node_tn_lassoc_removal_item_s { + bool ext = false; + tn_linfo_s tnl_info; + tn_linfo_s tnl_info_ric; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RANfunction-Item ::= SEQUENCE +struct ra_nfunction_item_s { + bool ext = false; + uint16_t ran_function_id = 0; + unbounded_octstring ran_function_definition; + uint16_t ran_function_revision = 0; + printable_string<1, 1000, true, true> ran_function_oid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RANfunctionID-Item ::= SEQUENCE +struct ra_nfunction_id_item_s { + bool ext = false; + uint16_t ran_function_id = 0; + uint16_t ran_function_revision = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RANfunctionIDcause-Item ::= SEQUENCE +struct ra_nfunction_idcause_item_s { + bool ext = false; + uint16_t ran_function_id = 0; + cause_c cause; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICaction-Admitted-Item ::= SEQUENCE +struct ri_caction_admitted_item_s { + bool ext = false; + uint16_t ric_action_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICaction-NotAdmitted-Item ::= SEQUENCE +struct ri_caction_not_admitted_item_s { + bool ext = false; + uint16_t ric_action_id = 0; + cause_c cause; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICaction-ToBeSetup-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_caction_to_be_setup_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_caction_to_be_setup_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ri_caction_to_be_setup_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_caction_to_be_setup_item_s& ri_caction_to_be_setup_item() { return c; } + const ri_caction_to_be_setup_item_s& ri_caction_to_be_setup_item() const { return c; } + + private: + ri_caction_to_be_setup_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscription-withCause-Item ::= SEQUENCE +struct ricsubscription_with_cause_item_s { + bool ext = false; + ri_crequest_id_s ric_request_id; + uint16_t ran_function_id = 0; + cause_c cause; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionSetupFailed-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_setup_failed_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2conn_setup_failed_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2conn_setup_failed_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2conn_setup_failed_item_s& e2conn_setup_failed_item() { return c; } + const e2conn_setup_failed_item_s& e2conn_setup_failed_item() const { return c; } + + private: + e2conn_setup_failed_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionUpdate-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_upd_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2conn_upd_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2conn_upd_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2conn_upd_item_s& e2conn_upd_item() { return c; } + const e2conn_upd_item_s& e2conn_upd_item() const { return c; } + + private: + e2conn_upd_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionUpdateRemove-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_upd_rem_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2conn_upd_rem_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2conn_upd_rem_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2conn_upd_rem_item_s& e2conn_upd_rem_item() { return c; } + const e2conn_upd_rem_item_s& e2conn_upd_rem_item() const { return c; } + + private: + e2conn_upd_rem_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigAddition-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_addition_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_addition_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_addition_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_addition_item_s& e2node_component_cfg_addition_item() { return c; } + const e2node_component_cfg_addition_item_s& e2node_component_cfg_addition_item() const { return c; } + + private: + e2node_component_cfg_addition_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigAdditionAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_addition_ack_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_addition_ack_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_addition_ack_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_addition_ack_item_s& e2node_component_cfg_addition_ack_item() { return c; } + const e2node_component_cfg_addition_ack_item_s& e2node_component_cfg_addition_ack_item() const { return c; } + + private: + e2node_component_cfg_addition_ack_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigRemoval-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_removal_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_removal_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_removal_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_removal_item_s& e2node_component_cfg_removal_item() { return c; } + const e2node_component_cfg_removal_item_s& e2node_component_cfg_removal_item() const { return c; } + + private: + e2node_component_cfg_removal_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigRemovalAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_removal_ack_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_removal_ack_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_removal_ack_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_removal_ack_item_s& e2node_component_cfg_removal_ack_item() { return c; } + const e2node_component_cfg_removal_ack_item_s& e2node_component_cfg_removal_ack_item() const { return c; } + + private: + e2node_component_cfg_removal_ack_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigUpdate-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_upd_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_upd_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_upd_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_upd_item_s& e2node_component_cfg_upd_item() { return c; } + const e2node_component_cfg_upd_item_s& e2node_component_cfg_upd_item() const { return c; } + + private: + e2node_component_cfg_upd_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigUpdateAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_upd_ack_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_upd_ack_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_upd_ack_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_upd_ack_item_s& e2node_component_cfg_upd_ack_item() { return c; } + const e2node_component_cfg_upd_ack_item_s& e2node_component_cfg_upd_ack_item() const { return c; } + + private: + e2node_component_cfg_upd_ack_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeTNLassociationRemoval-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_tn_lassoc_removal_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_tn_lassoc_removal_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_tn_lassoc_removal_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_tn_lassoc_removal_item_s& e2node_tn_lassoc_removal_item() { return c; } + const e2node_tn_lassoc_removal_item_s& e2node_tn_lassoc_removal_item() const { return c; } + + private: + e2node_tn_lassoc_removal_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// GlobalE2node-eNB-ID ::= SEQUENCE +struct global_e2node_enb_id_s { + bool ext = false; + global_enb_id_s global_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalE2node-en-gNB-ID ::= SEQUENCE +struct global_e2node_en_g_nb_id_s { + bool ext = false; + bool en_g_nb_cu_up_id_present = false; + bool en_g_nb_du_id_present = false; + globalen_gnb_id_s global_en_g_nb_id; + uint64_t en_g_nb_cu_up_id = 0; + uint64_t en_g_nb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalE2node-gNB-ID ::= SEQUENCE +struct global_e2node_g_nb_id_s { + bool ext = false; + bool global_en_g_nb_id_present = false; + bool gnb_cu_up_id_present = false; + bool gnb_du_id_present = false; + globalg_nb_id_s global_g_nb_id; + globalen_gnb_id_s global_en_g_nb_id; + uint64_t gnb_cu_up_id = 0; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalE2node-ng-eNB-ID ::= SEQUENCE +struct global_e2node_ng_enb_id_s { + bool ext = false; + bool global_enb_id_present = false; + bool ng_enb_du_id_present = false; + globalngenb_id_s global_ng_enb_id; + global_enb_id_s global_enb_id; + uint64_t ng_enb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RANfunction-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ra_nfunction_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ra_nfunction_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ra_nfunction_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ra_nfunction_item_s& ra_nfunction_item() { return c; } + const ra_nfunction_item_s& ra_nfunction_item() const { return c; } + + private: + ra_nfunction_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RANfunctionID-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ra_nfunction_id_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ra_nfunction_id_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ra_nfunction_id_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ra_nfunction_id_item_s& ra_nfunction_id_item() { return c; } + const ra_nfunction_id_item_s& ra_nfunction_id_item() const { return c; } + + private: + ra_nfunction_id_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RANfunctionIDcause-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ra_nfunction_idcause_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ra_nfunction_iecause_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ra_nfunction_iecause_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ra_nfunction_idcause_item_s& ra_nfunction_iecause_item() { return c; } + const ra_nfunction_idcause_item_s& ra_nfunction_iecause_item() const { return c; } + + private: + ra_nfunction_idcause_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICaction-Admitted-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_caction_admitted_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_caction_admitted_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ri_caction_admitted_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_caction_admitted_item_s& ri_caction_admitted_item() { return c; } + const ri_caction_admitted_item_s& ri_caction_admitted_item() const { return c; } + + private: + ri_caction_admitted_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICaction-NotAdmitted-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_caction_not_admitted_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_caction_not_admitted_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ri_caction_not_admitted_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_caction_not_admitted_item_s& ri_caction_not_admitted_item() { return c; } + const ri_caction_not_admitted_item_s& ri_caction_not_admitted_item() const { return c; } + + private: + ri_caction_not_admitted_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICactions-ToBeSetup-List ::= SEQUENCE (SIZE (1..16)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ri_cactions_to_be_setup_list_l = + bounded_array, 16>; + +// RICsubscription-withCause-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_with_cause_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ricsubscription_with_cause_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ricsubscription_with_cause_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ricsubscription_with_cause_item_s& ricsubscription_with_cause_item() { return c; } + const ricsubscription_with_cause_item_s& ricsubscription_with_cause_item() const { return c; } + + private: + ricsubscription_with_cause_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionSetupFailed-List ::= SEQUENCE (SIZE (1..32)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2conn_setup_failed_list_l = bounded_array, 32>; + +// E2connectionUpdate-List ::= SEQUENCE (SIZE (1..32)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using e2conn_upd_list_l = bounded_array, 32>; + +// E2connectionUpdateRemove-List ::= SEQUENCE (SIZE (1..32)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2conn_upd_rem_list_l = bounded_array, 32>; + +// E2nodeComponentConfigAddition-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_addition_list_l = + dyn_array >; + +// E2nodeComponentConfigAdditionAck-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_addition_ack_list_l = + dyn_array >; + +// E2nodeComponentConfigRemoval-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_removal_list_l = + dyn_array >; + +// E2nodeComponentConfigRemovalAck-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_removal_ack_list_l = + dyn_array >; + +// E2nodeComponentConfigUpdate-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_upd_list_l = dyn_array >; + +// E2nodeComponentConfigUpdateAck-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_upd_ack_list_l = + dyn_array >; + +// E2nodeTNLassociationRemoval-List ::= SEQUENCE (SIZE (1..32)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_tn_lassoc_removal_list_l = + bounded_array, 32>; + +// GlobalE2node-ID ::= CHOICE +struct global_e2node_id_c { + struct types_opts { + enum options { gnb, en_g_nb, ng_enb, enb, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_e2node_id_c() = default; + global_e2node_id_c(const global_e2node_id_c& other); + global_e2node_id_c& operator=(const global_e2node_id_c& other); + ~global_e2node_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_e2node_g_nb_id_s& gnb() + { + assert_choice_type(types::gnb, type_, "GlobalE2node-ID"); + return c.get(); + } + global_e2node_en_g_nb_id_s& en_g_nb() + { + assert_choice_type(types::en_g_nb, type_, "GlobalE2node-ID"); + return c.get(); + } + global_e2node_ng_enb_id_s& ng_enb() + { + assert_choice_type(types::ng_enb, type_, "GlobalE2node-ID"); + return c.get(); + } + global_e2node_enb_id_s& enb() + { + assert_choice_type(types::enb, type_, "GlobalE2node-ID"); + return c.get(); + } + const global_e2node_g_nb_id_s& gnb() const + { + assert_choice_type(types::gnb, type_, "GlobalE2node-ID"); + return c.get(); + } + const global_e2node_en_g_nb_id_s& en_g_nb() const + { + assert_choice_type(types::en_g_nb, type_, "GlobalE2node-ID"); + return c.get(); + } + const global_e2node_ng_enb_id_s& ng_enb() const + { + assert_choice_type(types::ng_enb, type_, "GlobalE2node-ID"); + return c.get(); + } + const global_e2node_enb_id_s& enb() const + { + assert_choice_type(types::enb, type_, "GlobalE2node-ID"); + return c.get(); + } + global_e2node_g_nb_id_s& set_gnb(); + global_e2node_en_g_nb_id_s& set_en_g_nb(); + global_e2node_ng_enb_id_s& set_ng_enb(); + global_e2node_enb_id_s& set_enb(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// GlobalRIC-ID ::= SEQUENCE +struct global_ric_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<20, false, true> ric_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RANfunctions-List ::= SEQUENCE (SIZE (1..256)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ra_nfunctions_list_l = dyn_array >; + +// RANfunctionsID-List ::= SEQUENCE (SIZE (1..256)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ra_nfunctions_id_list_l = dyn_array >; + +// RANfunctionsIDcause-List ::= SEQUENCE (SIZE (1..256)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ra_nfunctions_idcause_list_l = dyn_array >; + +// RICaction-Admitted-List ::= SEQUENCE (SIZE (1..16)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ri_caction_admitted_list_l = bounded_array, 16>; + +// RICaction-NotAdmitted-List ::= SEQUENCE (SIZE (0..16)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ri_caction_not_admitted_list_l = + bounded_array, 16>; + +// RICcontrolAckRequest ::= ENUMERATED +struct ri_cctrl_ack_request_opts { + enum options { no_ack, ack, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated ri_cctrl_ack_request_e; + +// RICindicationType ::= ENUMERATED +struct ri_cind_type_opts { + enum options { report, insert, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated ri_cind_type_e; + +// RICsubscription-List-withCause ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using ricsubscription_list_with_cause_l = + dyn_array >; + +// RICsubscriptionDetails ::= SEQUENCE +struct ricsubscription_details_s { + bool ext = false; + unbounded_octstring ric_event_trigger_definition; + ri_cactions_to_be_setup_list_l ric_action_to_be_setup_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TimeToWait ::= ENUMERATED +struct time_to_wait_opts { + enum options { v1s, v2s, v5s, v10s, v20s, v60s, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated time_to_wait_e; + +// E2RemovalFailureIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2_removal_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2RemovalRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2_removal_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::transaction_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id() { return c; } + const uint16_t& transaction_id() const { return c; } + + private: + uint16_t c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2RemovalResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2_removal_resp_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_upd_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, e2conn_upd_add, e2conn_upd_rem, e2conn_upd_modify, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + e2conn_upd_list_l& e2conn_upd_add(); + e2conn_upd_rem_list_l& e2conn_upd_rem(); + e2conn_upd_list_l& e2conn_upd_modify(); + const uint16_t& transaction_id() const; + const e2conn_upd_list_l& e2conn_upd_add() const; + const e2conn_upd_rem_list_l& e2conn_upd_rem() const; + const e2conn_upd_list_l& e2conn_upd_modify() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionUpdateAck-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_upd_ack_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, e2conn_setup, e2conn_setup_failed, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + e2conn_upd_list_l& e2conn_setup(); + e2conn_setup_failed_list_l& e2conn_setup_failed(); + const uint16_t& transaction_id() const; + const e2conn_upd_list_l& e2conn_setup() const; + const e2conn_setup_failed_list_l& e2conn_setup_failed() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_upd_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, time_to_wait, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + time_to_wait_e& time_to_wait(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + const time_to_wait_e& time_to_wait() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeConfigurationUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_cfg_upd_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + transaction_id, + global_e2node_id, + e2node_component_cfg_addition, + e2node_component_cfg_upd, + e2node_component_cfg_removal, + e2node_tn_lassoc_removal, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + global_e2node_id_c& global_e2node_id(); + e2node_component_cfg_addition_list_l& e2node_component_cfg_addition(); + e2node_component_cfg_upd_list_l& e2node_component_cfg_upd(); + e2node_component_cfg_removal_list_l& e2node_component_cfg_removal(); + e2node_tn_lassoc_removal_list_l& e2node_tn_lassoc_removal(); + const uint16_t& transaction_id() const; + const global_e2node_id_c& global_e2node_id() const; + const e2node_component_cfg_addition_list_l& e2node_component_cfg_addition() const; + const e2node_component_cfg_upd_list_l& e2node_component_cfg_upd() const; + const e2node_component_cfg_removal_list_l& e2node_component_cfg_removal() const; + const e2node_tn_lassoc_removal_list_l& e2node_tn_lassoc_removal() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeConfigurationUpdateAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_cfg_upd_ack_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + transaction_id, + e2node_component_cfg_addition_ack, + e2node_component_cfg_upd_ack, + e2node_component_cfg_removal_ack, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + e2node_component_cfg_addition_ack_list_l& e2node_component_cfg_addition_ack(); + e2node_component_cfg_upd_ack_list_l& e2node_component_cfg_upd_ack(); + e2node_component_cfg_removal_ack_list_l& e2node_component_cfg_removal_ack(); + const uint16_t& transaction_id() const; + const e2node_component_cfg_addition_ack_list_l& e2node_component_cfg_addition_ack() const; + const e2node_component_cfg_upd_ack_list_l& e2node_component_cfg_upd_ack() const; + const e2node_component_cfg_removal_ack_list_l& e2node_component_cfg_removal_ack() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeConfigurationUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_cfg_upd_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, time_to_wait, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + time_to_wait_e& time_to_wait(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + const time_to_wait_e& time_to_wait() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2setupFailureIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2setup_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, time_to_wait, crit_diagnostics, tn_linfo, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + time_to_wait_e& time_to_wait(); + crit_diagnostics_s& crit_diagnostics(); + tn_linfo_s& tn_linfo(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + const time_to_wait_e& time_to_wait() const; + const crit_diagnostics_s& crit_diagnostics() const; + const tn_linfo_s& tn_linfo() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2setupRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2setup_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + transaction_id, + global_e2node_id, + ra_nfunctions_added, + e2node_component_cfg_addition, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + global_e2node_id_c& global_e2node_id(); + ra_nfunctions_list_l& ra_nfunctions_added(); + e2node_component_cfg_addition_list_l& e2node_component_cfg_addition(); + const uint16_t& transaction_id() const; + const global_e2node_id_c& global_e2node_id() const; + const ra_nfunctions_list_l& ra_nfunctions_added() const; + const e2node_component_cfg_addition_list_l& e2node_component_cfg_addition() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2setupResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2setup_resp_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + transaction_id, + global_ric_id, + ra_nfunctions_accepted, + ra_nfunctions_rejected, + e2node_component_cfg_addition_ack, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + global_ric_id_s& global_ric_id(); + ra_nfunctions_id_list_l& ra_nfunctions_accepted(); + ra_nfunctions_idcause_list_l& ra_nfunctions_rejected(); + e2node_component_cfg_addition_ack_list_l& e2node_component_cfg_addition_ack(); + const uint16_t& transaction_id() const; + const global_ric_id_s& global_ric_id() const; + const ra_nfunctions_id_list_l& ra_nfunctions_accepted() const; + const ra_nfunctions_idcause_list_l& ra_nfunctions_rejected() const; + const e2node_component_cfg_addition_ack_list_l& e2node_component_cfg_addition_ack() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// ErrorIndication-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct error_ind_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, ri_crequest_id, ra_nfunction_id, cause, crit_diagnostics, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + cause_c& cause(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const cause_c& cause() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICcontrolAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_cctrl_ack_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, ri_ccall_process_id, ri_cctrl_outcome, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + unbounded_octstring& ri_ccall_process_id(); + unbounded_octstring& ri_cctrl_outcome(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const unbounded_octstring& ri_ccall_process_id() const; + const unbounded_octstring& ri_cctrl_outcome() const; + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICcontrolFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_cctrl_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, ri_ccall_process_id, cause, ri_cctrl_outcome, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + unbounded_octstring& ri_ccall_process_id(); + cause_c& cause(); + unbounded_octstring& ri_cctrl_outcome(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const unbounded_octstring& ri_ccall_process_id() const; + const cause_c& cause() const; + const unbounded_octstring& ri_cctrl_outcome() const; + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICcontrolRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_cctrl_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + ri_crequest_id, + ra_nfunction_id, + ri_ccall_process_id, + ri_cctrl_hdr, + ri_cctrl_msg, + ri_cctrl_ack_request, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + unbounded_octstring& ri_ccall_process_id(); + unbounded_octstring& ri_cctrl_hdr(); + unbounded_octstring& ri_cctrl_msg(); + ri_cctrl_ack_request_e& ri_cctrl_ack_request(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const unbounded_octstring& ri_ccall_process_id() const; + const unbounded_octstring& ri_cctrl_hdr() const; + const unbounded_octstring& ri_cctrl_msg() const; + const ri_cctrl_ack_request_e& ri_cctrl_ack_request() const; + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICindication-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_cind_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + ri_crequest_id, + ra_nfunction_id, + ri_caction_id, + ri_cind_sn, + ri_cind_type, + ri_cind_hdr, + ri_cind_msg, + ri_ccall_process_id, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + uint16_t& ri_caction_id(); + uint32_t& ri_cind_sn(); + ri_cind_type_e& ri_cind_type(); + unbounded_octstring& ri_cind_hdr(); + unbounded_octstring& ri_cind_msg(); + unbounded_octstring& ri_ccall_process_id(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const uint16_t& ri_caction_id() const; + const uint32_t& ri_cind_sn() const; + const ri_cind_type_e& ri_cind_type() const; + const unbounded_octstring& ri_cind_hdr() const; + const unbounded_octstring& ri_cind_msg() const; + const unbounded_octstring& ri_ccall_process_id() const; + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICserviceQuery-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricservice_query_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, ra_nfunctions_accepted, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + ra_nfunctions_id_list_l& ra_nfunctions_accepted(); + const uint16_t& transaction_id() const; + const ra_nfunctions_id_list_l& ra_nfunctions_accepted() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICserviceUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricservice_upd_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + transaction_id, + ra_nfunctions_added, + ra_nfunctions_modified, + ra_nfunctions_deleted, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + ra_nfunctions_list_l& ra_nfunctions_added(); + ra_nfunctions_list_l& ra_nfunctions_modified(); + ra_nfunctions_id_list_l& ra_nfunctions_deleted(); + const uint16_t& transaction_id() const; + const ra_nfunctions_list_l& ra_nfunctions_added() const; + const ra_nfunctions_list_l& ra_nfunctions_modified() const; + const ra_nfunctions_id_list_l& ra_nfunctions_deleted() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICserviceUpdateAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricservice_upd_ack_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, ra_nfunctions_accepted, ra_nfunctions_rejected, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + ra_nfunctions_id_list_l& ra_nfunctions_accepted(); + ra_nfunctions_idcause_list_l& ra_nfunctions_rejected(); + const uint16_t& transaction_id() const; + const ra_nfunctions_id_list_l& ra_nfunctions_accepted() const; + const ra_nfunctions_idcause_list_l& ra_nfunctions_rejected() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICserviceUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricservice_upd_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, time_to_wait, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + time_to_wait_e& time_to_wait(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + const time_to_wait_e& time_to_wait() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionDeleteFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_delete_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, cause, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + cause_c& cause(); + crit_diagnostics_s& crit_diagnostics(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const cause_c& cause() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionDeleteRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_delete_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionDeleteRequired-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_delete_required_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ricsubscription_to_be_remd, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ricsubscription_to_be_remd; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ricsubscription_list_with_cause_l& ricsubscription_to_be_remd() { return c; } + const ricsubscription_list_with_cause_l& ricsubscription_to_be_remd() const { return c; } + + private: + ricsubscription_list_with_cause_l c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionDeleteResponse-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_delete_resp_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, cause, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + cause_c& cause(); + crit_diagnostics_s& crit_diagnostics(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const cause_c& cause() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, ricsubscription_details, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + ricsubscription_details_s& ricsubscription_details(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const ricsubscription_details_s& ricsubscription_details() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionResponse-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_resp_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, ri_cactions_admitted, ri_cactions_not_admitted, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + ri_caction_admitted_list_l& ri_cactions_admitted(); + ri_caction_not_admitted_list_l& ri_cactions_not_admitted(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const ri_caction_admitted_list_l& ri_cactions_admitted() const; + const ri_caction_not_admitted_list_l& ri_cactions_not_admitted() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// ResetRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct reset_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// ResetResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct reset_resp_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +struct e2_removal_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s cause; + ie_field_s crit_diagnostics; + + // sequence methods + e2_removal_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2RemovalFailure ::= SEQUENCE +using e2_removal_fail_s = elementary_procedure_option; + +// E2RemovalRequest ::= SEQUENCE +using e2_removal_request_s = elementary_procedure_option >; + +struct e2_removal_resp_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s crit_diagnostics; + + // sequence methods + e2_removal_resp_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2RemovalResponse ::= SEQUENCE +using e2_removal_resp_s = elementary_procedure_option; + +struct e2conn_upd_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool e2conn_upd_add_present = false; + bool e2conn_upd_rem_present = false; + bool e2conn_upd_modify_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 32, true> > e2conn_upd_add; + ie_field_s, 1, 32, true> > e2conn_upd_rem; + ie_field_s, 1, 32, true> > e2conn_upd_modify; + + // sequence methods + e2conn_upd_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionUpdate ::= SEQUENCE +using e2conn_upd_s = elementary_procedure_option; + +struct e2conn_upd_ack_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool e2conn_setup_present = false; + bool e2conn_setup_failed_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 32, true> > e2conn_setup; + ie_field_s, 1, 32, true> > + e2conn_setup_failed; + + // sequence methods + e2conn_upd_ack_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionUpdateAcknowledge ::= SEQUENCE +using e2conn_upd_ack_s = elementary_procedure_option; + +struct e2conn_upd_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool cause_present = false; + bool time_to_wait_present = false; + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s cause; + ie_field_s time_to_wait; + ie_field_s crit_diagnostics; + + // sequence methods + e2conn_upd_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionUpdateFailure ::= SEQUENCE +using e2conn_upd_fail_s = elementary_procedure_option; + +struct e2node_cfg_upd_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool global_e2node_id_present = false; + bool e2node_component_cfg_addition_present = false; + bool e2node_component_cfg_upd_present = false; + bool e2node_component_cfg_removal_present = false; + bool e2node_tn_lassoc_removal_present = false; + ie_field_s > transaction_id; + ie_field_s global_e2node_id; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_addition; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_upd; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_removal; + ie_field_s, 1, 32, true> > + e2node_tn_lassoc_removal; + + // sequence methods + e2node_cfg_upd_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeConfigurationUpdate ::= SEQUENCE +using e2node_cfg_upd_s = elementary_procedure_option; + +struct e2node_cfg_upd_ack_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool e2node_component_cfg_addition_ack_present = false; + bool e2node_component_cfg_upd_ack_present = false; + bool e2node_component_cfg_removal_ack_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_addition_ack; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_upd_ack; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_removal_ack; + + // sequence methods + e2node_cfg_upd_ack_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeConfigurationUpdateAcknowledge ::= SEQUENCE +using e2node_cfg_upd_ack_s = elementary_procedure_option; + +struct e2node_cfg_upd_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool time_to_wait_present = false; + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s cause; + ie_field_s time_to_wait; + ie_field_s crit_diagnostics; + + // sequence methods + e2node_cfg_upd_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeConfigurationUpdateFailure ::= SEQUENCE +using e2node_cfg_upd_fail_s = elementary_procedure_option; + +struct e2setup_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool time_to_wait_present = false; + bool crit_diagnostics_present = false; + bool tn_linfo_present = false; + ie_field_s > transaction_id; + ie_field_s cause; + ie_field_s time_to_wait; + ie_field_s crit_diagnostics; + ie_field_s tn_linfo; + + // sequence methods + e2setup_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2setupFailure ::= SEQUENCE +using e2setup_fail_s = elementary_procedure_option; + +struct e2setup_request_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + ie_field_s > transaction_id; + ie_field_s global_e2node_id; + ie_field_s, 1, 256, true> > ra_nfunctions_added; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_addition; + + // sequence methods + e2setup_request_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2setupRequest ::= SEQUENCE +using e2setup_request_s = elementary_procedure_option; + +struct e2setup_resp_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ra_nfunctions_accepted_present = false; + bool ra_nfunctions_rejected_present = false; + ie_field_s > transaction_id; + ie_field_s global_ric_id; + ie_field_s, 1, 256, true> > + ra_nfunctions_accepted; + ie_field_s, 1, 256, true> > + ra_nfunctions_rejected; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_addition_ack; + + // sequence methods + e2setup_resp_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2setupResponse ::= SEQUENCE +using e2setup_resp_s = elementary_procedure_option; + +struct error_ind_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool transaction_id_present = false; + bool ri_crequest_id_present = false; + bool ra_nfunction_id_present = false; + bool cause_present = false; + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s cause; + ie_field_s crit_diagnostics; + + // sequence methods + error_ind_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ErrorIndication ::= SEQUENCE +using error_ind_s = elementary_procedure_option; + +struct ri_cctrl_ack_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ri_ccall_process_id_present = false; + bool ri_cctrl_outcome_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s > ri_ccall_process_id; + ie_field_s > ri_cctrl_outcome; + + // sequence methods + ri_cctrl_ack_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICcontrolAcknowledge ::= SEQUENCE +using ri_cctrl_ack_s = elementary_procedure_option; + +struct ri_cctrl_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ri_ccall_process_id_present = false; + bool ri_cctrl_outcome_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s > ri_ccall_process_id; + ie_field_s cause; + ie_field_s > ri_cctrl_outcome; + + // sequence methods + ri_cctrl_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICcontrolFailure ::= SEQUENCE +using ri_cctrl_fail_s = elementary_procedure_option; + +struct ri_cctrl_request_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ri_ccall_process_id_present = false; + bool ri_cctrl_ack_request_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s > ri_ccall_process_id; + ie_field_s > ri_cctrl_hdr; + ie_field_s > ri_cctrl_msg; + ie_field_s ri_cctrl_ack_request; + + // sequence methods + ri_cctrl_request_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICcontrolRequest ::= SEQUENCE +using ri_cctrl_request_s = elementary_procedure_option; + +struct ri_cind_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ri_cind_sn_present = false; + bool ri_ccall_process_id_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s > ri_caction_id; + ie_field_s > ri_cind_sn; + ie_field_s ri_cind_type; + ie_field_s > ri_cind_hdr; + ie_field_s > ri_cind_msg; + ie_field_s > ri_ccall_process_id; + + // sequence methods + ri_cind_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICindication ::= SEQUENCE +using ri_cind_s = elementary_procedure_option; + +struct ricservice_query_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ra_nfunctions_accepted_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 256, true> > + ra_nfunctions_accepted; + + // sequence methods + ricservice_query_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICserviceQuery ::= SEQUENCE +using ricservice_query_s = elementary_procedure_option; + +struct ricservice_upd_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ra_nfunctions_added_present = false; + bool ra_nfunctions_modified_present = false; + bool ra_nfunctions_deleted_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 256, true> > ra_nfunctions_added; + ie_field_s, 1, 256, true> > ra_nfunctions_modified; + ie_field_s, 1, 256, true> > + ra_nfunctions_deleted; + + // sequence methods + ricservice_upd_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICserviceUpdate ::= SEQUENCE +using ricservice_upd_s = elementary_procedure_option; + +struct ricservice_upd_ack_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ra_nfunctions_accepted_present = false; + bool ra_nfunctions_rejected_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 256, true> > + ra_nfunctions_accepted; + ie_field_s, 1, 256, true> > + ra_nfunctions_rejected; + + // sequence methods + ricservice_upd_ack_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICserviceUpdateAcknowledge ::= SEQUENCE +using ricservice_upd_ack_s = elementary_procedure_option; + +struct ricservice_upd_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool time_to_wait_present = false; + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s cause; + ie_field_s time_to_wait; + ie_field_s crit_diagnostics; + + // sequence methods + ricservice_upd_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICserviceUpdateFailure ::= SEQUENCE +using ricservice_upd_fail_s = elementary_procedure_option; + +struct ricsubscription_delete_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool crit_diagnostics_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s cause; + ie_field_s crit_diagnostics; + + // sequence methods + ricsubscription_delete_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionDeleteFailure ::= SEQUENCE +using ricsubscription_delete_fail_s = elementary_procedure_option; + +struct ricsubscription_delete_request_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + + // sequence methods + ricsubscription_delete_request_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionDeleteRequest ::= SEQUENCE +using ricsubscription_delete_request_s = elementary_procedure_option; + +// RICsubscriptionDeleteRequired ::= SEQUENCE +using ricsubscription_delete_required_s = + elementary_procedure_option >; + +struct ricsubscription_delete_resp_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + + // sequence methods + ricsubscription_delete_resp_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionDeleteResponse ::= SEQUENCE +using ricsubscription_delete_resp_s = elementary_procedure_option; + +struct ricsubscription_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool crit_diagnostics_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s cause; + ie_field_s crit_diagnostics; + + // sequence methods + ricsubscription_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionFailure ::= SEQUENCE +using ricsubscription_fail_s = elementary_procedure_option; + +struct ricsubscription_request_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s ricsubscription_details; + + // sequence methods + ricsubscription_request_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionRequest ::= SEQUENCE +using ricsubscription_request_s = elementary_procedure_option; + +struct ricsubscription_resp_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ri_cactions_not_admitted_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s, 1, 16, true> > + ri_cactions_admitted; + ie_field_s, 0, 16, true> > + ri_cactions_not_admitted; + + // sequence methods + ricsubscription_resp_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionResponse ::= SEQUENCE +using ricsubscription_resp_s = elementary_procedure_option; + +struct reset_request_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + ie_field_s > transaction_id; + ie_field_s cause; + + // sequence methods + reset_request_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ResetRequest ::= SEQUENCE +using reset_request_s = elementary_procedure_option; + +struct reset_resp_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s crit_diagnostics; + + // sequence methods + reset_resp_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ResetResponse ::= SEQUENCE +using reset_resp_s = elementary_procedure_option; + +// E2AP-ELEMENTARY-PROCEDURES ::= OBJECT SET OF E2AP-ELEMENTARY-PROCEDURE +struct e2_ap_elem_procs_o { + // InitiatingMessage ::= OPEN TYPE + struct init_msg_c { + struct types_opts { + enum options { + ricsubscription_request, + ricsubscription_delete_request, + ricservice_upd, + ri_cctrl_request, + e2setup_request, + e2node_cfg_upd, + e2conn_upd, + reset_request, + e2_removal_request, + ri_cind, + ricservice_query, + error_ind, + ricsubscription_delete_required, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + init_msg_c() = default; + init_msg_c(const init_msg_c& other); + init_msg_c& operator=(const init_msg_c& other); + ~init_msg_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ricsubscription_request_s& ricsubscription_request(); + ricsubscription_delete_request_s& ricsubscription_delete_request(); + ricservice_upd_s& ricservice_upd(); + ri_cctrl_request_s& ri_cctrl_request(); + e2setup_request_s& e2setup_request(); + e2node_cfg_upd_s& e2node_cfg_upd(); + e2conn_upd_s& e2conn_upd(); + reset_request_s& reset_request(); + e2_removal_request_s& e2_removal_request(); + ri_cind_s& ri_cind(); + ricservice_query_s& ricservice_query(); + error_ind_s& error_ind(); + ricsubscription_delete_required_s& ricsubscription_delete_required(); + const ricsubscription_request_s& ricsubscription_request() const; + const ricsubscription_delete_request_s& ricsubscription_delete_request() const; + const ricservice_upd_s& ricservice_upd() const; + const ri_cctrl_request_s& ri_cctrl_request() const; + const e2setup_request_s& e2setup_request() const; + const e2node_cfg_upd_s& e2node_cfg_upd() const; + const e2conn_upd_s& e2conn_upd() const; + const reset_request_s& reset_request() const; + const e2_removal_request_s& e2_removal_request() const; + const ri_cind_s& ri_cind() const; + const ricservice_query_s& ricservice_query() const; + const error_ind_s& error_ind() const; + const ricsubscription_delete_required_s& ricsubscription_delete_required() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + // SuccessfulOutcome ::= OPEN TYPE + struct successful_outcome_c { + struct types_opts { + enum options { + ricsubscription_resp, + ricsubscription_delete_resp, + ricservice_upd_ack, + ri_cctrl_ack, + e2setup_resp, + e2node_cfg_upd_ack, + e2conn_upd_ack, + reset_resp, + e2_removal_resp, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + successful_outcome_c() = default; + successful_outcome_c(const successful_outcome_c& other); + successful_outcome_c& operator=(const successful_outcome_c& other); + ~successful_outcome_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ricsubscription_resp_s& ricsubscription_resp(); + ricsubscription_delete_resp_s& ricsubscription_delete_resp(); + ricservice_upd_ack_s& ricservice_upd_ack(); + ri_cctrl_ack_s& ri_cctrl_ack(); + e2setup_resp_s& e2setup_resp(); + e2node_cfg_upd_ack_s& e2node_cfg_upd_ack(); + e2conn_upd_ack_s& e2conn_upd_ack(); + reset_resp_s& reset_resp(); + e2_removal_resp_s& e2_removal_resp(); + const ricsubscription_resp_s& ricsubscription_resp() const; + const ricsubscription_delete_resp_s& ricsubscription_delete_resp() const; + const ricservice_upd_ack_s& ricservice_upd_ack() const; + const ri_cctrl_ack_s& ri_cctrl_ack() const; + const e2setup_resp_s& e2setup_resp() const; + const e2node_cfg_upd_ack_s& e2node_cfg_upd_ack() const; + const e2conn_upd_ack_s& e2conn_upd_ack() const; + const reset_resp_s& reset_resp() const; + const e2_removal_resp_s& e2_removal_resp() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + // UnsuccessfulOutcome ::= OPEN TYPE + struct unsuccessful_outcome_c { + struct types_opts { + enum options { + ricsubscription_fail, + ricsubscription_delete_fail, + ricservice_upd_fail, + ri_cctrl_fail, + e2setup_fail, + e2node_cfg_upd_fail, + e2conn_upd_fail, + e2_removal_fail, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + unsuccessful_outcome_c() = default; + unsuccessful_outcome_c(const unsuccessful_outcome_c& other); + unsuccessful_outcome_c& operator=(const unsuccessful_outcome_c& other); + ~unsuccessful_outcome_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ricsubscription_fail_s& ricsubscription_fail(); + ricsubscription_delete_fail_s& ricsubscription_delete_fail(); + ricservice_upd_fail_s& ricservice_upd_fail(); + ri_cctrl_fail_s& ri_cctrl_fail(); + e2setup_fail_s& e2setup_fail(); + e2node_cfg_upd_fail_s& e2node_cfg_upd_fail(); + e2conn_upd_fail_s& e2conn_upd_fail(); + e2_removal_fail_s& e2_removal_fail(); + const ricsubscription_fail_s& ricsubscription_fail() const; + const ricsubscription_delete_fail_s& ricsubscription_delete_fail() const; + const ricservice_upd_fail_s& ricservice_upd_fail() const; + const ri_cctrl_fail_s& ri_cctrl_fail() const; + const e2setup_fail_s& e2setup_fail() const; + const e2node_cfg_upd_fail_s& e2node_cfg_upd_fail() const; + const e2conn_upd_fail_s& e2conn_upd_fail() const; + const e2_removal_fail_s& e2_removal_fail() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + + // members lookup methods + static uint16_t idx_to_proc_code(uint32_t idx); + static bool is_proc_code_valid(const uint16_t& proc_code); + static init_msg_c get_init_msg(const uint16_t& proc_code); + static successful_outcome_c get_successful_outcome(const uint16_t& proc_code); + static unsuccessful_outcome_c get_unsuccessful_outcome(const uint16_t& proc_code); + static crit_e get_crit(const uint16_t& proc_code); +}; + +// InitiatingMessage ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +struct init_msg_s { + uint16_t proc_code = 0; + crit_e crit; + e2_ap_elem_procs_o::init_msg_c value; + + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool load_info_obj(const uint16_t& proc_code_); +}; + +// SuccessfulOutcome ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +struct successful_outcome_s { + uint16_t proc_code = 0; + crit_e crit; + e2_ap_elem_procs_o::successful_outcome_c value; + + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool load_info_obj(const uint16_t& proc_code_); +}; + +// UnsuccessfulOutcome ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +struct unsuccessful_outcome_s { + uint16_t proc_code = 0; + crit_e crit; + e2_ap_elem_procs_o::unsuccessful_outcome_c value; + + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool load_info_obj(const uint16_t& proc_code_); +}; + +// E2AP-PDU ::= CHOICE +struct e2_ap_pdu_c { + struct types_opts { + enum options { init_msg, successful_outcome, unsuccessful_outcome, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + e2_ap_pdu_c() = default; + e2_ap_pdu_c(const e2_ap_pdu_c& other); + e2_ap_pdu_c& operator=(const e2_ap_pdu_c& other); + ~e2_ap_pdu_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + init_msg_s& init_msg() + { + assert_choice_type(types::init_msg, type_, "E2AP-PDU"); + return c.get(); + } + successful_outcome_s& successful_outcome() + { + assert_choice_type(types::successful_outcome, type_, "E2AP-PDU"); + return c.get(); + } + unsuccessful_outcome_s& unsuccessful_outcome() + { + assert_choice_type(types::unsuccessful_outcome, type_, "E2AP-PDU"); + return c.get(); + } + const init_msg_s& init_msg() const + { + assert_choice_type(types::init_msg, type_, "E2AP-PDU"); + return c.get(); + } + const successful_outcome_s& successful_outcome() const + { + assert_choice_type(types::successful_outcome, type_, "E2AP-PDU"); + return c.get(); + } + const unsuccessful_outcome_s& unsuccessful_outcome() const + { + assert_choice_type(types::unsuccessful_outcome, type_, "E2AP-PDU"); + return c.get(); + } + init_msg_s& set_init_msg(); + successful_outcome_s& set_successful_outcome(); + unsuccessful_outcome_s& set_unsuccessful_outcome(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// ProtocolIE-FieldPair{E2AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE{{E2AP-PROTOCOL-IES-PAIR}} +template +struct protocol_ie_field_pair_s { + uint32_t id = 0; + crit_e first_crit; + typename ies_set_paramT_::first_value_c first_value; + crit_e second_crit; + typename ies_set_paramT_::second_value_c second_value; + + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool load_info_obj(const uint32_t& id_); +}; + +// ProtocolIE-ContainerPair{E2AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE (SIZE (0..65535)) OF ProtocolIE-FieldPair +template +using protocol_ie_container_pair_l = dyn_seq_of, 0, 65535, true>; + +} // namespace e2ap +} // namespace asn1 + +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; + +#endif // SRSASN1_E2AP_H diff --git a/lib/include/srsran/asn1/e2sm.h b/lib/include/srsran/asn1/e2sm.h new file mode 100644 index 000000000..21fd75453 --- /dev/null +++ b/lib/include/srsran/asn1/e2sm.h @@ -0,0 +1,1344 @@ +/** + * + * \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. + * + */ + +/******************************************************************************* + * + * 3GPP TS ASN1 E2SM v15.3.0 (2019-03) + * + ******************************************************************************/ + +#ifndef SRSASN1_E2SM_H +#define SRSASN1_E2SM_H + +#include "asn1_utils.h" +#include +#include + +namespace asn1 { +namespace e2sm { + +/******************************************************************************* + * Constant Definitions + ******************************************************************************/ + +#define ASN1_E2SM_MAX_E1_APID 65535 +#define ASN1_E2SM_MAX_F1_APID 4 +#define ASN1_E2SM_MAX_EARFCN 65535 +#define ASN1_E2SM_MAX_NRARFCN 3279165 +#define ASN1_E2SM_MAXNOOF_NR_CELL_BANDS 32 + +/******************************************************************************* + * Struct Definitions + ******************************************************************************/ + +// EUTRA-CGI ::= SEQUENCE +struct eutra_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<28, false, true> eutra_cell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-CGI ::= SEQUENCE +struct nr_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<36, false, true> nrcell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CGI ::= CHOICE +struct cgi_c { + struct types_opts { + enum options { nr_cgi, eutra_cgi, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + cgi_c() = default; + cgi_c(const cgi_c& other); + cgi_c& operator=(const cgi_c& other); + ~cgi_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_cgi_s& nr_cgi() + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + eutra_cgi_s& eutra_cgi() + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + const nr_cgi_s& nr_cgi() const + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + const eutra_cgi_s& eutra_cgi() const + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + nr_cgi_s& set_nr_cgi(); + eutra_cgi_s& set_eutra_cgi(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// GUAMI ::= SEQUENCE +struct guami_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<8, false, true> amf_region_id; + fixed_bitstring<10, false, true> amf_set_id; + fixed_bitstring<6, false, true> amf_pointer; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GUMMEI ::= SEQUENCE +struct gummei_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_octstring<2, true> mme_group_id; + fixed_octstring<1, true> mme_code; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CoreCPID ::= CHOICE +struct core_cpid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + core_cpid_c() = default; + core_cpid_c(const core_cpid_c& other); + core_cpid_c& operator=(const core_cpid_c& other); + ~core_cpid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + guami_s& five_gc() + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + gummei_s& epc() + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + const guami_s& five_gc() const + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + const gummei_s& epc() const + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + guami_s& set_five_gc(); + gummei_s& set_epc(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// ENB-ID ::= CHOICE +struct enb_id_c { + struct types_opts { + enum options { macro_enb_id, home_enb_id, /*...*/ short_macro_enb_id, long_macro_enb_id, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_c() = default; + enb_id_c(const enb_id_c& other); + enb_id_c& operator=(const enb_id_c& other); + ~enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_enb_id() + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<28, false, true>& home_enb_id() + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_enb_id() + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_enb_id() + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_enb_id() const + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<28, false, true>& home_enb_id() const + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_enb_id() const + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_enb_id() const + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_enb_id(); + fixed_bitstring<28, false, true>& set_home_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// GlobalENB-ID ::= SEQUENCE +struct global_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GNB-ID ::= CHOICE +struct gnb_id_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalGNB-ID ::= SEQUENCE +struct global_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + gnb_id_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NgENB-ID ::= CHOICE +struct ng_enb_id_c { + struct types_opts { + enum options { macro_ng_enb_id, short_macro_ng_enb_id, long_macro_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ng_enb_id_c() = default; + ng_enb_id_c(const ng_enb_id_c& other); + ng_enb_id_c& operator=(const ng_enb_id_c& other); + ~ng_enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_ng_enb_id() + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_ng_enb_id() + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_ng_enb_id() + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_ng_enb_id() const + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_ng_enb_id() const + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_ng_enb_id() const + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_ng_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_ng_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_ng_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// GlobalNgENB-ID ::= SEQUENCE +struct global_ng_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + ng_enb_id_c ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalRANNodeID ::= CHOICE +struct global_ran_node_id_c { + struct types_opts { + enum options { global_gnb_id, global_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_ran_node_id_c() = default; + global_ran_node_id_c(const global_ran_node_id_c& other); + global_ran_node_id_c& operator=(const global_ran_node_id_c& other); + ~global_ran_node_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_gnb_id_s& global_gnb_id() + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_ng_enb_id_s& global_ng_enb_id() + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_gnb_id_s& global_gnb_id() const + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_ng_enb_id_s& global_ng_enb_id() const + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_gnb_id_s& set_global_gnb_id(); + global_ng_enb_id_s& set_global_ng_enb_id(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// EN-GNB-ID ::= CHOICE +struct en_gnb_id_c { + struct types_opts { + enum options { en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::en_g_nb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& en_g_nb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& en_g_nb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalenGNB-ID ::= SEQUENCE +struct globalen_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + en_gnb_id_c en_g_nb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GroupID ::= CHOICE +struct group_id_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + group_id_c() = default; + group_id_c(const group_id_c& other); + group_id_c& operator=(const group_id_c& other); + ~group_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// InterfaceID-E1 ::= SEQUENCE +struct interface_id_e1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_cu_up_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-F1 ::= SEQUENCE +struct interface_id_f1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-NG ::= SEQUENCE +struct interface_id_ng_s { + bool ext = false; + guami_s guami; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-S1 ::= SEQUENCE +struct interface_id_s1_s { + bool ext = false; + gummei_s gummei; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-W1 ::= SEQUENCE +struct interface_id_w1_s { + bool ext = false; + global_ng_enb_id_s global_ng_enb_id; + uint64_t ng_enb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-X2 ::= SEQUENCE +struct interface_id_x2_s { + struct node_type_c_ { + struct types_opts { + enum options { global_enb_id, global_en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + node_type_c_() = default; + node_type_c_(const node_type_c_& other); + node_type_c_& operator=(const node_type_c_& other); + ~node_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_enb_id_s& global_enb_id() + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + globalen_gnb_id_s& global_en_g_nb_id() + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + const global_enb_id_s& global_enb_id() const + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + const globalen_gnb_id_s& global_en_g_nb_id() const + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + global_enb_id_s& set_global_enb_id(); + globalen_gnb_id_s& set_global_en_g_nb_id(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + node_type_c_ node_type; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-Xn ::= SEQUENCE +struct interface_id_xn_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceIdentifier ::= CHOICE +struct interface_id_c { + struct types_opts { + enum options { ng, xn, f1, e1, s1, x2, w1, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + interface_id_c() = default; + interface_id_c(const interface_id_c& other); + interface_id_c& operator=(const interface_id_c& other); + ~interface_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + interface_id_ng_s& ng() + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_xn_s& xn() + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_f1_s& f1() + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_e1_s& e1() + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_s1_s& s1() + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_x2_s& x2() + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_w1_s& w1() + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_ng_s& ng() const + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_xn_s& xn() const + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_f1_s& f1() const + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_e1_s& e1() const + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_s1_s& s1() const + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_x2_s& x2() const + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_w1_s& w1() const + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_ng_s& set_ng(); + interface_id_xn_s& set_xn(); + interface_id_f1_s& set_f1(); + interface_id_e1_s& set_e1(); + interface_id_s1_s& set_s1(); + interface_id_x2_s& set_x2(); + interface_id_w1_s& set_w1(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// FreqBandNrItem ::= SEQUENCE +struct freq_band_nr_item_s { + bool ext = false; + uint16_t freq_band_ind_nr = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-ARFCN ::= SEQUENCE +struct nr_arfcn_s { + using freq_band_list_nr_l_ = dyn_array; + + // member variables + bool ext = false; + uint32_t nrarfcn = 0; + freq_band_list_nr_l_ freq_band_list_nr; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// QoSID ::= CHOICE +struct qo_sid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + qo_sid_c() = default; + qo_sid_c(const qo_sid_c& other); + qo_sid_c& operator=(const qo_sid_c& other); + ~qo_sid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// RRCclass-LTE ::= ENUMERATED +struct rr_cclass_lte_opts { + enum options { + bcch_bch, + bcch_bch_mbms, + bcch_dl_sch, + bcch_dl_sch_br, + bcch_dl_sch_mbms, + mcch, + pcch, + dl_ccch, + dl_dcch, + ul_ccch, + ul_dcch, + sc_mcch, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated rr_cclass_lte_e; + +// RRCclass-NR ::= ENUMERATED +struct rr_cclass_nr_opts { + enum options { bcch_bch, bcch_dl_sch, dl_ccch, dl_dcch, pcch, ul_ccch, ul_ccch1, ul_dcch, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated rr_cclass_nr_e; + +// RRC-MessageID ::= SEQUENCE +struct rrc_msg_id_s { + struct rrc_type_c_ { + struct types_opts { + enum options { lte, nr, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + rrc_type_c_() = default; + rrc_type_c_(const rrc_type_c_& other); + rrc_type_c_& operator=(const rrc_type_c_& other); + ~rrc_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + rr_cclass_lte_e& lte() + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + rr_cclass_nr_e& nr() + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + const rr_cclass_lte_e& lte() const + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + const rr_cclass_nr_e& nr() const + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + rr_cclass_lte_e& set_lte(); + rr_cclass_nr_e& set_nr(); + + private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + rrc_type_c_ rrc_type; + int64_t msg_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// S-NSSAI ::= SEQUENCE +struct s_nssai_s { + bool ext = false; + bool sd_present = false; + fixed_octstring<1, true> sst; + fixed_octstring<3, true> sd; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ServingCell-ARFCN ::= CHOICE +struct serving_cell_arfcn_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_arfcn_c() = default; + serving_cell_arfcn_c(const serving_cell_arfcn_c& other); + serving_cell_arfcn_c& operator=(const serving_cell_arfcn_c& other); + ~serving_cell_arfcn_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_arfcn_s& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + uint32_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + const nr_arfcn_s& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + const uint32_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + nr_arfcn_s& set_nr(); + uint32_t& set_eutra(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// ServingCell-PCI ::= CHOICE +struct serving_cell_pci_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_pci_c() = default; + serving_cell_pci_c(const serving_cell_pci_c& other); + serving_cell_pci_c& operator=(const serving_cell_pci_c& other); + ~serving_cell_pci_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& set_nr(); + uint16_t& set_eutra(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_e1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_f1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-E1AP-ID-List ::= SEQUENCE (SIZE (1..65535)) OF UEID-GNB-CU-CP-E1AP-ID-Item +using ueid_gnb_cu_cp_e1_ap_id_list_l = dyn_array; + +// UEID-GNB-CU-F1AP-ID-List ::= SEQUENCE (SIZE (1..4)) OF UEID-GNB-CU-CP-F1AP-ID-Item +using ueid_gnb_cu_f1_ap_id_list_l = dyn_array; + +// UEID-EN-GNB ::= SEQUENCE +struct ueid_en_gnb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool gnb_cu_ue_f1_ap_id_present = false; + bool ran_ueid_present = false; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + uint64_t gnb_cu_ue_f1_ap_id = 0; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-ENB ::= SEQUENCE +struct ueid_enb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_present = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool global_enb_id_present = false; + uint64_t mme_ue_s1ap_id = 0; + gummei_s gummei; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB ::= SEQUENCE +struct ueid_gnb_s { + bool ext = false; + bool ran_ueid_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_gnb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + ueid_gnb_cu_f1_ap_id_list_l gnb_cu_ue_f1_ap_id_list; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_gnb_id_s global_gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-UP ::= SEQUENCE +struct ueid_gnb_cu_up_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-DU ::= SEQUENCE +struct ueid_gnb_du_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB ::= SEQUENCE +struct ueid_ng_enb_s { + bool ext = false; + bool ng_enb_cu_ue_w1_ap_id_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_ng_enb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_ng_enb_id_s global_ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB-DU ::= SEQUENCE +struct ueid_ng_enb_du_s { + bool ext = false; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID ::= CHOICE +struct ueid_c { + struct types_opts { + enum options { + gnb_ueid, + gnb_du_ueid, + gnb_cu_up_ueid, + ng_enb_ueid, + ng_enb_du_ueid, + en_g_nb_ueid, + enb_ueid, + // ... + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ueid_c() = default; + ueid_c(const ueid_c& other); + ueid_c& operator=(const ueid_c& other); + ~ueid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ueid_gnb_s& gnb_ueid() + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_du_s& gnb_du_ueid() + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_cu_up_s& gnb_cu_up_ueid() + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_s& ng_enb_ueid() + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_du_s& ng_enb_du_ueid() + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_en_gnb_s& en_g_nb_ueid() + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + ueid_enb_s& enb_ueid() + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_s& gnb_ueid() const + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_du_s& gnb_du_ueid() const + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_cu_up_s& gnb_cu_up_ueid() const + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_s& ng_enb_ueid() const + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_du_s& ng_enb_du_ueid() const + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_en_gnb_s& en_g_nb_ueid() const + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_enb_s& enb_ueid() const + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_s& set_gnb_ueid(); + ueid_gnb_du_s& set_gnb_du_ueid(); + ueid_gnb_cu_up_s& set_gnb_cu_up_ueid(); + ueid_ng_enb_s& set_ng_enb_ueid(); + ueid_ng_enb_du_s& set_ng_enb_du_ueid(); + ueid_en_gnb_s& set_en_g_nb_ueid(); + ueid_enb_s& set_enb_ueid(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +} // namespace e2sm +} // namespace asn1 + +#endif // SRSASN1_E2SM_H diff --git a/lib/src/asn1/CMakeLists.txt b/lib/src/asn1/CMakeLists.txt index a95fe2b44..94fb79bf0 100644 --- a/lib/src/asn1/CMakeLists.txt +++ b/lib/src/asn1/CMakeLists.txt @@ -66,5 +66,9 @@ add_library(nas_5g_msg STATIC nas_5g_msg.cc nas_5g_ies.cc nas_5g_utils.cc) target_compile_options(nas_5g_msg PRIVATE "-Os") target_link_libraries(nas_5g_msg asn1_utils srsran_common) install(TARGETS nas_5g_msg DESTINATION ${LIBRARY_DIR} OPTIONAL) - +## ORAN E2 RIC +add_library(ric_e2 STATIC e2ap.cpp e2sm.cpp) +target_compile_options(ric_e2 PRIVATE "-Os") +target_link_libraries(ric_e2 asn1_utils srsran_common) +install(TARGETS ric_e2 DESTINATION ${LIBRARY_DIR} OPTIONAL) diff --git a/lib/src/asn1/e2ap.cpp b/lib/src/asn1/e2ap.cpp new file mode 100644 index 000000000..f6c492608 --- /dev/null +++ b/lib/src/asn1/e2ap.cpp @@ -0,0 +1,16048 @@ +/** + * + * \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 "srsran/asn1/e2ap.h" +#include + +using namespace asn1; +using namespace asn1::e2ap; + +/******************************************************************************* + * Struct Methods + ******************************************************************************/ + +// CauseE2node ::= ENUMERATED +const char* cause_e2node_opts::to_string() const +{ + static const char* options[] = {"e2node-component-unknown"}; + return convert_enum_idx(options, 1, value, "cause_e2node_e"); +} +uint8_t cause_e2node_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "cause_e2node_e"); +} + +// CauseMisc ::= ENUMERATED +const char* cause_misc_opts::to_string() const +{ + static const char* options[] = {"control-processing-overload", "hardware-failure", "om-intervention", "unspecified"}; + return convert_enum_idx(options, 4, value, "cause_misc_e"); +} + +// CauseProtocol ::= ENUMERATED +const char* cause_protocol_opts::to_string() const +{ + static const char* options[] = {"transfer-syntax-error", + "abstract-syntax-error-reject", + "abstract-syntax-error-ignore-and-notify", + "message-not-compatible-with-receiver-state", + "semantic-error", + "abstract-syntax-error-falsely-constructed-message", + "unspecified"}; + return convert_enum_idx(options, 7, value, "cause_protocol_e"); +} + +// CauseRICrequest ::= ENUMERATED +const char* cause_ri_crequest_opts::to_string() const +{ + static const char* options[] = {"ran-function-id-invalid", + "action-not-supported", + "excessive-actions", + "duplicate-action", + "duplicate-event-trigger", + "function-resource-limit", + "request-id-unknown", + "inconsistent-action-subsequent-action-sequence", + "control-message-invalid", + "ric-call-process-id-invalid", + "control-timer-expired", + "control-failed-to-execute", + "system-not-ready", + "unspecified"}; + return convert_enum_idx(options, 14, value, "cause_ri_crequest_e"); +} + +// CauseRICservice ::= ENUMERATED +const char* cause_ricservice_opts::to_string() const +{ + static const char* options[] = {"ran-function-not-supported", "excessive-functions", "ric-resource-limit"}; + return convert_enum_idx(options, 3, value, "cause_ricservice_e"); +} + +// CauseTransport ::= ENUMERATED +const char* cause_transport_opts::to_string() const +{ + static const char* options[] = {"unspecified", "transport-resource-unavailable"}; + return convert_enum_idx(options, 2, value, "cause_transport_e"); +} + +// Cause ::= CHOICE +void cause_c::destroy_() {} +void cause_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +cause_c::cause_c(const cause_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ric_request: + c.init(other.c.get()); + break; + case types::ric_service: + c.init(other.c.get()); + break; + case types::e2_node: + c.init(other.c.get()); + break; + case types::transport: + c.init(other.c.get()); + break; + case types::protocol: + c.init(other.c.get()); + break; + case types::misc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cause_c"); + } +} +cause_c& cause_c::operator=(const cause_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ric_request: + c.set(other.c.get()); + break; + case types::ric_service: + c.set(other.c.get()); + break; + case types::e2_node: + c.set(other.c.get()); + break; + case types::transport: + c.set(other.c.get()); + break; + case types::protocol: + c.set(other.c.get()); + break; + case types::misc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cause_c"); + } + + return *this; +} +cause_ri_crequest_e& cause_c::set_ric_request() +{ + set(types::ric_request); + return c.get(); +} +cause_ricservice_e& cause_c::set_ric_service() +{ + set(types::ric_service); + return c.get(); +} +cause_e2node_e& cause_c::set_e2_node() +{ + set(types::e2_node); + return c.get(); +} +cause_transport_e& cause_c::set_transport() +{ + set(types::transport); + return c.get(); +} +cause_protocol_e& cause_c::set_protocol() +{ + set(types::protocol); + return c.get(); +} +cause_misc_e& cause_c::set_misc() +{ + set(types::misc); + return c.get(); +} +void cause_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ric_request: + j.write_str("ricRequest", c.get().to_string()); + break; + case types::ric_service: + j.write_str("ricService", c.get().to_string()); + break; + case types::e2_node: + j.write_str("e2Node", "e2node-component-unknown"); + break; + case types::transport: + j.write_str("transport", c.get().to_string()); + break; + case types::protocol: + j.write_str("protocol", c.get().to_string()); + break; + case types::misc: + j.write_str("misc", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "cause_c"); + } + j.end_obj(); +} +SRSASN_CODE cause_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ric_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ric_service: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2_node: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::transport: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::protocol: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::misc: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "cause_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE cause_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ric_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ric_service: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2_node: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::transport: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::protocol: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::misc: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "cause_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* cause_c::types_opts::to_string() const +{ + static const char* options[] = {"ricRequest", "ricService", "e2Node", "transport", "protocol", "misc"}; + return convert_enum_idx(options, 6, value, "cause_c::types"); +} +uint8_t cause_c::types_opts::to_number() const +{ + if (value == e2_node) { + return 2; + } + invalid_enum_number(value, "cause_c::types"); + return 0; +} + +// TypeOfError ::= ENUMERATED +const char* type_of_error_opts::to_string() const +{ + static const char* options[] = {"not-understood", "missing"}; + return convert_enum_idx(options, 2, value, "type_of_error_e"); +} + +// CriticalityDiagnostics-IE-Item ::= SEQUENCE +SRSASN_CODE crit_diagnostics_ie_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(iecrit.pack(bref)); + HANDLE_CODE(pack_integer(bref, ie_id, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(type_of_error.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE crit_diagnostics_ie_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(iecrit.unpack(bref)); + HANDLE_CODE(unpack_integer(ie_id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(type_of_error.unpack(bref)); + + return SRSASN_SUCCESS; +} +void crit_diagnostics_ie_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("iECriticality", iecrit.to_string()); + j.write_int("iE-ID", ie_id); + j.write_str("typeOfError", type_of_error.to_string()); + j.end_obj(); +} + +// RICrequestID ::= SEQUENCE +SRSASN_CODE ri_crequest_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ric_requestor_id, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(pack_integer(bref, ric_instance_id, (uint32_t)0u, (uint32_t)65535u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_crequest_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ric_requestor_id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(unpack_integer(ric_instance_id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + + return SRSASN_SUCCESS; +} +void ri_crequest_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ricRequestorID", ric_requestor_id); + j.write_int("ricInstanceID", ric_instance_id); + j.end_obj(); +} + +// TriggeringMessage ::= ENUMERATED +const char* trigger_msg_opts::to_string() const +{ + static const char* options[] = {"initiating-message", "successful-outcome", "unsuccessfull-outcome"}; + return convert_enum_idx(options, 3, value, "trigger_msg_e"); +} + +// CriticalityDiagnostics ::= SEQUENCE +SRSASN_CODE crit_diagnostics_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(proc_code_present, 1)); + HANDLE_CODE(bref.pack(trigger_msg_present, 1)); + HANDLE_CODE(bref.pack(proc_crit_present, 1)); + HANDLE_CODE(bref.pack(ric_requestor_id_present, 1)); + HANDLE_CODE(bref.pack(ies_crit_diagnostics.size() > 0, 1)); + + if (proc_code_present) { + HANDLE_CODE(pack_integer(bref, proc_code, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (trigger_msg_present) { + HANDLE_CODE(trigger_msg.pack(bref)); + } + if (proc_crit_present) { + HANDLE_CODE(proc_crit.pack(bref)); + } + if (ric_requestor_id_present) { + HANDLE_CODE(ric_requestor_id.pack(bref)); + } + if (ies_crit_diagnostics.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, ies_crit_diagnostics, 1, 256, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE crit_diagnostics_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(proc_code_present, 1)); + HANDLE_CODE(bref.unpack(trigger_msg_present, 1)); + HANDLE_CODE(bref.unpack(proc_crit_present, 1)); + HANDLE_CODE(bref.unpack(ric_requestor_id_present, 1)); + bool ies_crit_diagnostics_present; + HANDLE_CODE(bref.unpack(ies_crit_diagnostics_present, 1)); + + if (proc_code_present) { + HANDLE_CODE(unpack_integer(proc_code, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (trigger_msg_present) { + HANDLE_CODE(trigger_msg.unpack(bref)); + } + if (proc_crit_present) { + HANDLE_CODE(proc_crit.unpack(bref)); + } + if (ric_requestor_id_present) { + HANDLE_CODE(ric_requestor_id.unpack(bref)); + } + if (ies_crit_diagnostics_present) { + HANDLE_CODE(unpack_dyn_seq_of(ies_crit_diagnostics, bref, 1, 256, true)); + } + + return SRSASN_SUCCESS; +} +void crit_diagnostics_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (proc_code_present) { + j.write_int("procedureCode", proc_code); + } + if (trigger_msg_present) { + j.write_str("triggeringMessage", trigger_msg.to_string()); + } + if (proc_crit_present) { + j.write_str("procedureCriticality", proc_crit.to_string()); + } + if (ric_requestor_id_present) { + j.write_fieldname("ricRequestorID"); + ric_requestor_id.to_json(j); + } + if (ies_crit_diagnostics.size() > 0) { + j.start_array("iEsCriticalityDiagnostics"); + for (const auto& e1 : ies_crit_diagnostics) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// ENB-ID-Choice ::= CHOICE +void enb_id_choice_c::destroy_() +{ + switch (type_) { + case types::enb_id_macro: + c.destroy >(); + break; + case types::enb_id_shortmacro: + c.destroy >(); + break; + case types::enb_id_longmacro: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_choice_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::enb_id_macro: + c.init >(); + break; + case types::enb_id_shortmacro: + c.init >(); + break; + case types::enb_id_longmacro: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } +} +enb_id_choice_c::enb_id_choice_c(const enb_id_choice_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::enb_id_macro: + c.init(other.c.get >()); + break; + case types::enb_id_shortmacro: + c.init(other.c.get >()); + break; + case types::enb_id_longmacro: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } +} +enb_id_choice_c& enb_id_choice_c::operator=(const enb_id_choice_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::enb_id_macro: + c.set(other.c.get >()); + break; + case types::enb_id_shortmacro: + c.set(other.c.get >()); + break; + case types::enb_id_longmacro: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_choice_c::set_enb_id_macro() +{ + set(types::enb_id_macro); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_choice_c::set_enb_id_shortmacro() +{ + set(types::enb_id_shortmacro); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_choice_c::set_enb_id_longmacro() +{ + set(types::enb_id_longmacro); + return c.get >(); +} +void enb_id_choice_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::enb_id_macro: + j.write_str("enb-ID-macro", c.get >().to_string()); + break; + case types::enb_id_shortmacro: + j.write_str("enb-ID-shortmacro", c.get >().to_string()); + break; + case types::enb_id_longmacro: + j.write_str("enb-ID-longmacro", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_choice_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::enb_id_macro: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::enb_id_shortmacro: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::enb_id_longmacro: + HANDLE_CODE((c.get >().pack(bref))); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_choice_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::enb_id_macro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::enb_id_shortmacro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::enb_id_longmacro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_choice_c::types_opts::to_string() const +{ + static const char* options[] = {"enb-ID-macro", "enb-ID-shortmacro", "enb-ID-longmacro"}; + return convert_enum_idx(options, 3, value, "enb_id_choice_c::types"); +} + +// GNB-ID-Choice ::= CHOICE +void gnb_id_choice_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gnb-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE gnb_id_choice_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE gnb_id_choice_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "gnb_id_choice_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* gnb_id_choice_c::types_opts::to_string() const +{ + static const char* options[] = {"gnb-ID"}; + return convert_enum_idx(options, 1, value, "gnb_id_choice_c::types"); +} + +// ENB-ID ::= CHOICE +void enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_enb_id: + c.destroy >(); + break; + case types::home_enb_id: + c.destroy >(); + break; + case types::short_macro_enb_id: + c.destroy >(); + break; + case types::long_macro_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_enb_id: + c.init >(); + break; + case types::home_enb_id: + c.init >(); + break; + case types::short_macro_enb_id: + c.init >(); + break; + case types::long_macro_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c::enb_id_c(const enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_enb_id: + c.init(other.c.get >()); + break; + case types::home_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c& enb_id_c::operator=(const enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_enb_id: + c.set(other.c.get >()); + break; + case types::home_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_c::set_macro_enb_id() +{ + set(types::macro_enb_id); + return c.get >(); +} +fixed_bitstring<28, false, true>& enb_id_c::set_home_enb_id() +{ + set(types::home_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_c::set_short_macro_enb_id() +{ + set(types::short_macro_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_c::set_long_macro_enb_id() +{ + set(types::long_macro_enb_id); + return c.get >(); +} +void enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_enb_id: + j.write_str("macro-eNB-ID", c.get >().to_string()); + break; + case types::home_enb_id: + j.write_str("home-eNB-ID", c.get >().to_string()); + break; + case types::short_macro_enb_id: + j.write_str("short-Macro-eNB-ID", c.get >().to_string()); + break; + case types::long_macro_enb_id: + j.write_str("long-Macro-eNB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macro-eNB-ID", "home-eNB-ID", "short-Macro-eNB-ID", "long-Macro-eNB-ID"}; + return convert_enum_idx(options, 4, value, "enb_id_c::types"); +} + +// ENGNB-ID ::= CHOICE +void engnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE engnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE engnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "engnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* engnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB-ID"}; + return convert_enum_idx(options, 1, value, "engnb_id_c::types"); +} + +// GlobalgNB-ID ::= SEQUENCE +SRSASN_CODE globalg_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalg_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalg_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("plmn-id", plmn_id.to_string()); + j.write_fieldname("gnb-id"); + gnb_id.to_json(j); + j.end_obj(); +} + +// GlobalngeNB-ID ::= SEQUENCE +SRSASN_CODE globalngenb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalngenb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalngenb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("plmn-id", plmn_id.to_string()); + j.write_fieldname("enb-id"); + enb_id.to_json(j); + j.end_obj(); +} + +// GlobalENB-ID ::= SEQUENCE +SRSASN_CODE global_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("eNB-ID"); + enb_id.to_json(j); + j.end_obj(); +} + +// GlobalNG-RANNode-ID ::= CHOICE +void global_ng_ran_node_id_c::destroy_() +{ + switch (type_) { + case types::gnb: + c.destroy(); + break; + case types::ng_enb: + c.destroy(); + break; + default: + break; + } +} +void global_ng_ran_node_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb: + c.init(); + break; + case types::ng_enb: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + } +} +global_ng_ran_node_id_c::global_ng_ran_node_id_c(const global_ng_ran_node_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb: + c.init(other.c.get()); + break; + case types::ng_enb: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + } +} +global_ng_ran_node_id_c& global_ng_ran_node_id_c::operator=(const global_ng_ran_node_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb: + c.set(other.c.get()); + break; + case types::ng_enb: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + } + + return *this; +} +globalg_nb_id_s& global_ng_ran_node_id_c::set_gnb() +{ + set(types::gnb); + return c.get(); +} +globalngenb_id_s& global_ng_ran_node_id_c::set_ng_enb() +{ + set(types::ng_enb); + return c.get(); +} +void global_ng_ran_node_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb: + j.write_fieldname("gNB"); + c.get().to_json(j); + break; + case types::ng_enb: + j.write_fieldname("ng-eNB"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_ng_ran_node_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ng_ran_node_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_ng_ran_node_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB", "ng-eNB"}; + return convert_enum_idx(options, 2, value, "global_ng_ran_node_id_c::types"); +} + +// GlobalenGNB-ID ::= SEQUENCE +SRSASN_CODE globalen_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalen_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalen_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("gNB-ID"); + gnb_id.to_json(j); + j.end_obj(); +} + +// RICsubsequentActionType ::= ENUMERATED +const char* ricsubsequent_action_type_opts::to_string() const +{ + static const char* options[] = {"continue", "wait"}; + return convert_enum_idx(options, 2, value, "ricsubsequent_action_type_e"); +} + +// RICtimeToWait ::= ENUMERATED +const char* ri_ctime_to_wait_opts::to_string() const +{ + static const char* options[] = {"w1ms", + "w2ms", + "w5ms", + "w10ms", + "w20ms", + "w30ms", + "w40ms", + "w50ms", + "w100ms", + "w200ms", + "w500ms", + "w1s", + "w2s", + "w5s", + "w10s", + "w20s", + "w60s"}; + return convert_enum_idx(options, 17, value, "ri_ctime_to_wait_e"); +} + +// E2nodeComponentInterfaceE1 ::= SEQUENCE +SRSASN_CODE e2node_component_interface_e1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_e1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_cp_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_e1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-ID", gnb_cu_cp_id); + j.end_obj(); +} + +// E2nodeComponentInterfaceF1 ::= SEQUENCE +SRSASN_CODE e2node_component_interface_f1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_f1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_f1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-DU-ID", gnb_du_id); + j.end_obj(); +} + +// E2nodeComponentInterfaceNG ::= SEQUENCE +SRSASN_CODE e2node_component_interface_ng_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(amf_name.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_ng_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(amf_name.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_ng_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("amf-name", amf_name.to_string()); + j.end_obj(); +} + +// E2nodeComponentInterfaceS1 ::= SEQUENCE +SRSASN_CODE e2node_component_interface_s1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(mme_name.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_s1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(mme_name.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_s1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("mme-name", mme_name.to_string()); + j.end_obj(); +} + +// E2nodeComponentInterfaceW1 ::= SEQUENCE +SRSASN_CODE e2node_component_interface_w1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ng_enb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_w1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ng_enb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_w1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ng-eNB-DU-ID", ng_enb_du_id); + j.end_obj(); +} + +// E2nodeComponentInterfaceX2 ::= SEQUENCE +SRSASN_CODE e2node_component_interface_x2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(global_enb_id_present, 1)); + HANDLE_CODE(bref.pack(global_en_g_nb_id_present, 1)); + + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.pack(bref)); + } + if (global_en_g_nb_id_present) { + HANDLE_CODE(global_en_g_nb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_x2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(global_enb_id_present, 1)); + HANDLE_CODE(bref.unpack(global_en_g_nb_id_present, 1)); + + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.unpack(bref)); + } + if (global_en_g_nb_id_present) { + HANDLE_CODE(global_en_g_nb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void e2node_component_interface_x2_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (global_enb_id_present) { + j.write_fieldname("global-eNB-ID"); + global_enb_id.to_json(j); + } + if (global_en_g_nb_id_present) { + j.write_fieldname("global-en-gNB-ID"); + global_en_g_nb_id.to_json(j); + } + j.end_obj(); +} + +// E2nodeComponentInterfaceXn ::= SEQUENCE +SRSASN_CODE e2node_component_interface_xn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_node_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_xn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_node_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_xn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-Node-ID"); + global_ng_ran_node_id.to_json(j); + j.end_obj(); +} + +// RICactionType ::= ENUMERATED +const char* ri_caction_type_opts::to_string() const +{ + static const char* options[] = {"report", "insert", "policy"}; + return convert_enum_idx(options, 3, value, "ri_caction_type_e"); +} + +// RICsubsequentAction ::= SEQUENCE +SRSASN_CODE ricsubsequent_action_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ric_subsequent_action_type.pack(bref)); + HANDLE_CODE(ric_time_to_wait.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubsequent_action_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ric_subsequent_action_type.unpack(bref)); + HANDLE_CODE(ric_time_to_wait.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ricsubsequent_action_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ricSubsequentActionType", ric_subsequent_action_type.to_string()); + j.write_str("ricTimeToWait", ric_time_to_wait.to_string()); + j.end_obj(); +} + +// E2nodeComponentConfiguration ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_request_part.pack(bref)); + HANDLE_CODE(e2node_component_resp_part.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_request_part.unpack(bref)); + HANDLE_CODE(e2node_component_resp_part.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentRequestPart", e2node_component_request_part.to_string()); + j.write_str("e2nodeComponentResponsePart", e2node_component_resp_part.to_string()); + j.end_obj(); +} + +// E2nodeComponentConfigurationAck ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_ack_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(fail_cause_present, 1)); + + HANDLE_CODE(upd_outcome.pack(bref)); + if (fail_cause_present) { + HANDLE_CODE(fail_cause.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_ack_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(fail_cause_present, 1)); + + HANDLE_CODE(upd_outcome.unpack(bref)); + if (fail_cause_present) { + HANDLE_CODE(fail_cause.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_ack_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("updateOutcome", upd_outcome.to_string()); + if (fail_cause_present) { + j.write_fieldname("failureCause"); + fail_cause.to_json(j); + } + j.end_obj(); +} + +const char* e2node_component_cfg_ack_s::upd_outcome_opts::to_string() const +{ + static const char* options[] = {"success", "failure"}; + return convert_enum_idx(options, 2, value, "e2node_component_cfg_ack_s::upd_outcome_e_"); +} + +// E2nodeComponentID ::= CHOICE +void e2node_component_id_c::destroy_() +{ + switch (type_) { + case types::e2node_component_interface_type_ng: + c.destroy(); + break; + case types::e2node_component_interface_type_xn: + c.destroy(); + break; + case types::e2node_component_interface_type_e1: + c.destroy(); + break; + case types::e2node_component_interface_type_f1: + c.destroy(); + break; + case types::e2node_component_interface_type_w1: + c.destroy(); + break; + case types::e2node_component_interface_type_s1: + c.destroy(); + break; + case types::e2node_component_interface_type_x2: + c.destroy(); + break; + default: + break; + } +} +void e2node_component_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::e2node_component_interface_type_ng: + c.init(); + break; + case types::e2node_component_interface_type_xn: + c.init(); + break; + case types::e2node_component_interface_type_e1: + c.init(); + break; + case types::e2node_component_interface_type_f1: + c.init(); + break; + case types::e2node_component_interface_type_w1: + c.init(); + break; + case types::e2node_component_interface_type_s1: + c.init(); + break; + case types::e2node_component_interface_type_x2: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + } +} +e2node_component_id_c::e2node_component_id_c(const e2node_component_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::e2node_component_interface_type_ng: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_xn: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_e1: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_f1: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_w1: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_s1: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_x2: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + } +} +e2node_component_id_c& e2node_component_id_c::operator=(const e2node_component_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::e2node_component_interface_type_ng: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_xn: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_e1: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_f1: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_w1: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_s1: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_x2: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + } + + return *this; +} +e2node_component_interface_ng_s& e2node_component_id_c::set_e2node_component_interface_type_ng() +{ + set(types::e2node_component_interface_type_ng); + return c.get(); +} +e2node_component_interface_xn_s& e2node_component_id_c::set_e2node_component_interface_type_xn() +{ + set(types::e2node_component_interface_type_xn); + return c.get(); +} +e2node_component_interface_e1_s& e2node_component_id_c::set_e2node_component_interface_type_e1() +{ + set(types::e2node_component_interface_type_e1); + return c.get(); +} +e2node_component_interface_f1_s& e2node_component_id_c::set_e2node_component_interface_type_f1() +{ + set(types::e2node_component_interface_type_f1); + return c.get(); +} +e2node_component_interface_w1_s& e2node_component_id_c::set_e2node_component_interface_type_w1() +{ + set(types::e2node_component_interface_type_w1); + return c.get(); +} +e2node_component_interface_s1_s& e2node_component_id_c::set_e2node_component_interface_type_s1() +{ + set(types::e2node_component_interface_type_s1); + return c.get(); +} +e2node_component_interface_x2_s& e2node_component_id_c::set_e2node_component_interface_type_x2() +{ + set(types::e2node_component_interface_type_x2); + return c.get(); +} +void e2node_component_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::e2node_component_interface_type_ng: + j.write_fieldname("e2nodeComponentInterfaceTypeNG"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_xn: + j.write_fieldname("e2nodeComponentInterfaceTypeXn"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_e1: + j.write_fieldname("e2nodeComponentInterfaceTypeE1"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_f1: + j.write_fieldname("e2nodeComponentInterfaceTypeF1"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_w1: + j.write_fieldname("e2nodeComponentInterfaceTypeW1"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_s1: + j.write_fieldname("e2nodeComponentInterfaceTypeS1"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_x2: + j.write_fieldname("e2nodeComponentInterfaceTypeX2"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + } + j.end_obj(); +} +SRSASN_CODE e2node_component_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::e2node_component_interface_type_ng: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_xn: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_e1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_f1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_w1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_s1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_x2: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::e2node_component_interface_type_ng: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_xn: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_e1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_f1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_w1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_s1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_x2: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2node_component_id_c::types_opts::to_string() const +{ + static const char* options[] = {"e2nodeComponentInterfaceTypeNG", + "e2nodeComponentInterfaceTypeXn", + "e2nodeComponentInterfaceTypeE1", + "e2nodeComponentInterfaceTypeF1", + "e2nodeComponentInterfaceTypeW1", + "e2nodeComponentInterfaceTypeS1", + "e2nodeComponentInterfaceTypeX2"}; + return convert_enum_idx(options, 7, value, "e2node_component_id_c::types"); +} + +// E2nodeComponentInterfaceType ::= ENUMERATED +const char* e2node_component_interface_type_opts::to_string() const +{ + static const char* options[] = {"ng", "xn", "e1", "f1", "w1", "s1", "x2"}; + return convert_enum_idx(options, 7, value, "e2node_component_interface_type_e"); +} + +// RICaction-ToBeSetup-Item ::= SEQUENCE +SRSASN_CODE ri_caction_to_be_setup_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ric_action_definition.size() > 0, 1)); + HANDLE_CODE(bref.pack(ric_subsequent_action_present, 1)); + + HANDLE_CODE(pack_integer(bref, ric_action_id, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(ric_action_type.pack(bref)); + if (ric_action_definition.size() > 0) { + HANDLE_CODE(ric_action_definition.pack(bref)); + } + if (ric_subsequent_action_present) { + HANDLE_CODE(ric_subsequent_action.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_to_be_setup_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool ric_action_definition_present; + HANDLE_CODE(bref.unpack(ric_action_definition_present, 1)); + HANDLE_CODE(bref.unpack(ric_subsequent_action_present, 1)); + + HANDLE_CODE(unpack_integer(ric_action_id, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(ric_action_type.unpack(bref)); + if (ric_action_definition_present) { + HANDLE_CODE(ric_action_definition.unpack(bref)); + } + if (ric_subsequent_action_present) { + HANDLE_CODE(ric_subsequent_action.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ri_caction_to_be_setup_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ricActionID", ric_action_id); + j.write_str("ricActionType", ric_action_type.to_string()); + if (ric_action_definition.size() > 0) { + j.write_str("ricActionDefinition", ric_action_definition.to_string()); + } + if (ric_subsequent_action_present) { + j.write_fieldname("ricSubsequentAction"); + ric_subsequent_action.to_json(j); + } + j.end_obj(); +} + +// TNLinformation ::= SEQUENCE +SRSASN_CODE tn_linfo_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(tnl_port_present, 1)); + + HANDLE_CODE(tnl_address.pack(bref)); + if (tnl_port_present) { + HANDLE_CODE(tnl_port.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE tn_linfo_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(tnl_port_present, 1)); + + HANDLE_CODE(tnl_address.unpack(bref)); + if (tnl_port_present) { + HANDLE_CODE(tnl_port.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void tn_linfo_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("tnlAddress", tnl_address.to_string()); + if (tnl_port_present) { + j.write_str("tnlPort", tnl_port.to_string()); + } + j.end_obj(); +} + +// TNLusage ::= ENUMERATED +const char* tn_lusage_opts::to_string() const +{ + static const char* options[] = {"ric-service", "support-function", "both"}; + return convert_enum_idx(options, 3, value, "tn_lusage_e"); +} + +// E2connectionSetupFailed-Item ::= SEQUENCE +SRSASN_CODE e2conn_setup_failed_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(tnl_info.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_setup_failed_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(tnl_info.unpack(bref)); + HANDLE_CODE(cause.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2conn_setup_failed_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("tnlInformation"); + tnl_info.to_json(j); + j.write_fieldname("cause"); + cause.to_json(j); + j.end_obj(); +} + +// E2connectionUpdate-Item ::= SEQUENCE +SRSASN_CODE e2conn_upd_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(tnl_info.pack(bref)); + HANDLE_CODE(tnl_usage.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(tnl_info.unpack(bref)); + HANDLE_CODE(tnl_usage.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2conn_upd_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("tnlInformation"); + tnl_info.to_json(j); + j.write_str("tnlUsage", tnl_usage.to_string()); + j.end_obj(); +} + +// E2connectionUpdateRemove-Item ::= SEQUENCE +SRSASN_CODE e2conn_upd_rem_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(tnl_info.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_rem_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(tnl_info.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2conn_upd_rem_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("tnlInformation"); + tnl_info.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigAddition-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_addition_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + HANDLE_CODE(e2node_component_cfg.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_addition_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + HANDLE_CODE(e2node_component_cfg.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_addition_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.write_fieldname("e2nodeComponentConfiguration"); + e2node_component_cfg.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigAdditionAck-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_addition_ack_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_addition_ack_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_addition_ack_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.write_fieldname("e2nodeComponentConfigurationAck"); + e2node_component_cfg_ack.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigRemoval-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_removal_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_removal_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_removal_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigRemovalAck-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_removal_ack_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_removal_ack_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_removal_ack_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.write_fieldname("e2nodeComponentConfigurationAck"); + e2node_component_cfg_ack.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigUpdate-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_upd_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + HANDLE_CODE(e2node_component_cfg.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_upd_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + HANDLE_CODE(e2node_component_cfg.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_upd_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.write_fieldname("e2nodeComponentConfiguration"); + e2node_component_cfg.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigUpdateAck-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_upd_ack_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_upd_ack_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_upd_ack_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.write_fieldname("e2nodeComponentConfigurationAck"); + e2node_component_cfg_ack.to_json(j); + j.end_obj(); +} + +// E2nodeTNLassociationRemoval-Item ::= SEQUENCE +SRSASN_CODE e2node_tn_lassoc_removal_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(tnl_info.pack(bref)); + HANDLE_CODE(tnl_info_ric.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_tn_lassoc_removal_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(tnl_info.unpack(bref)); + HANDLE_CODE(tnl_info_ric.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_tn_lassoc_removal_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("tnlInformation"); + tnl_info.to_json(j); + j.write_fieldname("tnlInformationRIC"); + tnl_info_ric.to_json(j); + j.end_obj(); +} + +// RANfunction-Item ::= SEQUENCE +SRSASN_CODE ra_nfunction_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ran_function_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(ran_function_definition.pack(bref)); + HANDLE_CODE(pack_integer(bref, ran_function_revision, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(ran_function_oid.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ran_function_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(ran_function_definition.unpack(bref)); + HANDLE_CODE(unpack_integer(ran_function_revision, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(ran_function_oid.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ra_nfunction_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ranFunctionID", ran_function_id); + j.write_str("ranFunctionDefinition", ran_function_definition.to_string()); + j.write_int("ranFunctionRevision", ran_function_revision); + j.write_str("ranFunctionOID", ran_function_oid.to_string()); + j.end_obj(); +} + +// RANfunctionID-Item ::= SEQUENCE +SRSASN_CODE ra_nfunction_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ran_function_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(pack_integer(bref, ran_function_revision, (uint16_t)0u, (uint16_t)4095u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ran_function_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(unpack_integer(ran_function_revision, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + + return SRSASN_SUCCESS; +} +void ra_nfunction_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ranFunctionID", ran_function_id); + j.write_int("ranFunctionRevision", ran_function_revision); + j.end_obj(); +} + +// RANfunctionIDcause-Item ::= SEQUENCE +SRSASN_CODE ra_nfunction_idcause_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ran_function_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(cause.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_idcause_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ran_function_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(cause.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ra_nfunction_idcause_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ranFunctionID", ran_function_id); + j.write_fieldname("cause"); + cause.to_json(j); + j.end_obj(); +} + +// RICaction-Admitted-Item ::= SEQUENCE +SRSASN_CODE ri_caction_admitted_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ric_action_id, (uint16_t)0u, (uint16_t)255u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_admitted_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ric_action_id, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + + return SRSASN_SUCCESS; +} +void ri_caction_admitted_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ricActionID", ric_action_id); + j.end_obj(); +} + +// RICaction-NotAdmitted-Item ::= SEQUENCE +SRSASN_CODE ri_caction_not_admitted_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ric_action_id, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(cause.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_not_admitted_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ric_action_id, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(cause.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ri_caction_not_admitted_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ricActionID", ric_action_id); + j.write_fieldname("cause"); + cause.to_json(j); + j.end_obj(); +} + +// RICaction-ToBeSetup-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_caction_to_be_setup_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {19}; + return map_enum_number(options, 1, idx, "id"); +} +bool ri_caction_to_be_setup_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 19 == id; +} +crit_e ri_caction_to_be_setup_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 19) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ri_caction_to_be_setup_item_ies_o::value_c ri_caction_to_be_setup_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 19) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_caction_to_be_setup_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 19) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ri_caction_to_be_setup_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RICaction-ToBeSetup-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ri_caction_to_be_setup_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_to_be_setup_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ri_caction_to_be_setup_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICaction-ToBeSetup-Item"}; + return convert_enum_idx(options, 1, value, "ri_caction_to_be_setup_item_ies_o::value_c::types"); +} + +// RICsubscription-withCause-Item ::= SEQUENCE +SRSASN_CODE ricsubscription_with_cause_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ric_request_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, ran_function_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(cause.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_with_cause_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ric_request_id.unpack(bref)); + HANDLE_CODE(unpack_integer(ran_function_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(cause.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ricsubscription_with_cause_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ricRequestID"); + ric_request_id.to_json(j); + j.write_int("ranFunctionID", ran_function_id); + j.write_fieldname("cause"); + cause.to_json(j); + j.end_obj(); +} + +// E2connectionSetupFailed-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_setup_failed_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {41}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2conn_setup_failed_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 41 == id; +} +crit_e e2conn_setup_failed_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 41) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2conn_setup_failed_item_ies_o::value_c e2conn_setup_failed_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 41) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_setup_failed_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 41) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_setup_failed_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2connectionSetupFailed-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2conn_setup_failed_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_setup_failed_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2conn_setup_failed_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2connectionSetupFailed-Item"}; + return convert_enum_idx(options, 1, value, "e2conn_setup_failed_item_ies_o::value_c::types"); +} +uint8_t e2conn_setup_failed_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2conn_setup_failed_item_ies_o::value_c::types"); +} + +// E2connectionUpdate-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_upd_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {43}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2conn_upd_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 43 == id; +} +crit_e e2conn_upd_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 43) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2conn_upd_item_ies_o::value_c e2conn_upd_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 43) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_upd_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 43) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_upd_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2connectionUpdate-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2conn_upd_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2conn_upd_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2connectionUpdate-Item"}; + return convert_enum_idx(options, 1, value, "e2conn_upd_item_ies_o::value_c::types"); +} +uint8_t e2conn_upd_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2conn_upd_item_ies_o::value_c::types"); +} + +// E2connectionUpdateRemove-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_upd_rem_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {47}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2conn_upd_rem_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 47 == id; +} +crit_e e2conn_upd_rem_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 47) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2conn_upd_rem_item_ies_o::value_c e2conn_upd_rem_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 47) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_upd_rem_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 47) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_upd_rem_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2connectionUpdateRemove-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2conn_upd_rem_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_rem_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2conn_upd_rem_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2connectionUpdateRemove-Item"}; + return convert_enum_idx(options, 1, value, "e2conn_upd_rem_item_ies_o::value_c::types"); +} +uint8_t e2conn_upd_rem_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2conn_upd_rem_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigAddition-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_addition_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {51}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_addition_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 51 == id; +} +crit_e e2node_component_cfg_addition_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 51) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_addition_item_ies_o::value_c +e2node_component_cfg_addition_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 51) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_addition_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 51) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_addition_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigAddition-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_addition_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_addition_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_addition_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigAddition-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_addition_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_addition_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_addition_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigAdditionAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_addition_ack_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {53}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_addition_ack_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 53 == id; +} +crit_e e2node_component_cfg_addition_ack_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 53) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_addition_ack_item_ies_o::value_c +e2node_component_cfg_addition_ack_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 53) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_addition_ack_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 53) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_addition_ack_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigAdditionAck-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_addition_ack_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_addition_ack_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_addition_ack_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigAdditionAck-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_addition_ack_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_addition_ack_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_addition_ack_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigRemoval-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_removal_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {55}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_removal_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 55 == id; +} +crit_e e2node_component_cfg_removal_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 55) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_removal_item_ies_o::value_c e2node_component_cfg_removal_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 55) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_removal_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 55) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_removal_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigRemoval-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_removal_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_removal_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_removal_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigRemoval-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_removal_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_removal_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_removal_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigRemovalAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_removal_ack_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {57}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_removal_ack_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 57 == id; +} +crit_e e2node_component_cfg_removal_ack_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 57) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_removal_ack_item_ies_o::value_c +e2node_component_cfg_removal_ack_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 57) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_removal_ack_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 57) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_removal_ack_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigRemovalAck-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_removal_ack_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_removal_ack_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_removal_ack_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigRemovalAck-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_removal_ack_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_removal_ack_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_removal_ack_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigUpdate-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_upd_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {34}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_upd_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 34 == id; +} +crit_e e2node_component_cfg_upd_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 34) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_upd_item_ies_o::value_c e2node_component_cfg_upd_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 34) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_upd_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 34) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_upd_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigUpdate-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_upd_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_upd_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_upd_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigUpdate-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_upd_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_upd_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_upd_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigUpdateAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_upd_ack_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {36}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_upd_ack_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 36 == id; +} +crit_e e2node_component_cfg_upd_ack_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 36) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_upd_ack_item_ies_o::value_c e2node_component_cfg_upd_ack_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 36) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_upd_ack_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 36) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_upd_ack_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigUpdateAck-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_upd_ack_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_upd_ack_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_upd_ack_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigUpdateAck-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_upd_ack_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_upd_ack_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_upd_ack_item_ies_o::value_c::types"); +} + +// E2nodeTNLassociationRemoval-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_tn_lassoc_removal_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {59}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_tn_lassoc_removal_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 59 == id; +} +crit_e e2node_tn_lassoc_removal_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 59) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_tn_lassoc_removal_item_ies_o::value_c e2node_tn_lassoc_removal_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 59) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_tn_lassoc_removal_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 59) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_tn_lassoc_removal_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeTNLassociationRemoval-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_tn_lassoc_removal_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_tn_lassoc_removal_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_tn_lassoc_removal_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeTNLassociationRemoval-Item"}; + return convert_enum_idx(options, 1, value, "e2node_tn_lassoc_removal_item_ies_o::value_c::types"); +} +uint8_t e2node_tn_lassoc_removal_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_tn_lassoc_removal_item_ies_o::value_c::types"); +} + +// GlobalE2node-eNB-ID ::= SEQUENCE +SRSASN_CODE global_e2node_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_e2node_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_e2node_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-eNB-ID"); + global_enb_id.to_json(j); + j.end_obj(); +} + +// GlobalE2node-en-gNB-ID ::= SEQUENCE +SRSASN_CODE global_e2node_en_g_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(en_g_nb_cu_up_id_present, 1)); + HANDLE_CODE(bref.pack(en_g_nb_du_id_present, 1)); + + HANDLE_CODE(global_en_g_nb_id.pack(bref)); + if (en_g_nb_cu_up_id_present) { + HANDLE_CODE(pack_integer(bref, en_g_nb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (en_g_nb_du_id_present) { + HANDLE_CODE(pack_integer(bref, en_g_nb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_e2node_en_g_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(en_g_nb_cu_up_id_present, 1)); + HANDLE_CODE(bref.unpack(en_g_nb_du_id_present, 1)); + + HANDLE_CODE(global_en_g_nb_id.unpack(bref)); + if (en_g_nb_cu_up_id_present) { + HANDLE_CODE(unpack_integer(en_g_nb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (en_g_nb_du_id_present) { + HANDLE_CODE(unpack_integer(en_g_nb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +void global_e2node_en_g_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-en-gNB-ID"); + global_en_g_nb_id.to_json(j); + if (en_g_nb_cu_up_id_present) { + j.write_int("en-gNB-CU-UP-ID", en_g_nb_cu_up_id); + } + if (en_g_nb_du_id_present) { + j.write_int("en-gNB-DU-ID", en_g_nb_du_id); + } + j.end_obj(); +} + +// GlobalE2node-gNB-ID ::= SEQUENCE +SRSASN_CODE global_e2node_g_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(global_en_g_nb_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_up_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_du_id_present, 1)); + + HANDLE_CODE(global_g_nb_id.pack(bref)); + if (global_en_g_nb_id_present) { + HANDLE_CODE(global_en_g_nb_id.pack(bref)); + } + if (gnb_cu_up_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (gnb_du_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_e2node_g_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(global_en_g_nb_id_present, 1)); + HANDLE_CODE(bref.unpack(gnb_cu_up_id_present, 1)); + HANDLE_CODE(bref.unpack(gnb_du_id_present, 1)); + + HANDLE_CODE(global_g_nb_id.unpack(bref)); + if (global_en_g_nb_id_present) { + HANDLE_CODE(global_en_g_nb_id.unpack(bref)); + } + if (gnb_cu_up_id_present) { + HANDLE_CODE(unpack_integer(gnb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (gnb_du_id_present) { + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +void global_e2node_g_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-gNB-ID"); + global_g_nb_id.to_json(j); + if (global_en_g_nb_id_present) { + j.write_fieldname("global-en-gNB-ID"); + global_en_g_nb_id.to_json(j); + } + if (gnb_cu_up_id_present) { + j.write_int("gNB-CU-UP-ID", gnb_cu_up_id); + } + if (gnb_du_id_present) { + j.write_int("gNB-DU-ID", gnb_du_id); + } + j.end_obj(); +} + +// GlobalE2node-ng-eNB-ID ::= SEQUENCE +SRSASN_CODE global_e2node_ng_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(global_enb_id_present, 1)); + HANDLE_CODE(bref.pack(ng_enb_du_id_present, 1)); + + HANDLE_CODE(global_ng_enb_id.pack(bref)); + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.pack(bref)); + } + if (ng_enb_du_id_present) { + HANDLE_CODE(pack_integer(bref, ng_enb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_e2node_ng_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(global_enb_id_present, 1)); + HANDLE_CODE(bref.unpack(ng_enb_du_id_present, 1)); + + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.unpack(bref)); + } + if (ng_enb_du_id_present) { + HANDLE_CODE(unpack_integer(ng_enb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +void global_e2node_ng_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-ng-eNB-ID"); + global_ng_enb_id.to_json(j); + if (global_enb_id_present) { + j.write_fieldname("global-eNB-ID"); + global_enb_id.to_json(j); + } + if (ng_enb_du_id_present) { + j.write_int("ngENB-DU-ID", ng_enb_du_id); + } + j.end_obj(); +} + +// RANfunction-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ra_nfunction_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {8}; + return map_enum_number(options, 1, idx, "id"); +} +bool ra_nfunction_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 8 == id; +} +crit_e ra_nfunction_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 8) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ra_nfunction_item_ies_o::value_c ra_nfunction_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 8) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ra_nfunction_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 8) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ra_nfunction_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RANfunction-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ra_nfunction_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ra_nfunction_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RANfunction-Item"}; + return convert_enum_idx(options, 1, value, "ra_nfunction_item_ies_o::value_c::types"); +} + +// RANfunctionID-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ra_nfunction_id_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {6}; + return map_enum_number(options, 1, idx, "id"); +} +bool ra_nfunction_id_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 6 == id; +} +crit_e ra_nfunction_id_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 6) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ra_nfunction_id_item_ies_o::value_c ra_nfunction_id_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 6) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ra_nfunction_id_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 6) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ra_nfunction_id_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RANfunctionID-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ra_nfunction_id_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_id_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ra_nfunction_id_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RANfunctionID-Item"}; + return convert_enum_idx(options, 1, value, "ra_nfunction_id_item_ies_o::value_c::types"); +} + +// RANfunctionIDcause-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ra_nfunction_idcause_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {7}; + return map_enum_number(options, 1, idx, "id"); +} +bool ra_nfunction_idcause_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 7 == id; +} +crit_e ra_nfunction_idcause_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 7) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ra_nfunction_idcause_item_ies_o::value_c ra_nfunction_idcause_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 7) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ra_nfunction_idcause_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 7) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ra_nfunction_idcause_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RANfunctionIDcause-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ra_nfunction_idcause_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_idcause_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ra_nfunction_idcause_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RANfunctionIDcause-Item"}; + return convert_enum_idx(options, 1, value, "ra_nfunction_idcause_item_ies_o::value_c::types"); +} + +// RICaction-Admitted-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_caction_admitted_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {14}; + return map_enum_number(options, 1, idx, "id"); +} +bool ri_caction_admitted_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 14 == id; +} +crit_e ri_caction_admitted_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 14) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ri_caction_admitted_item_ies_o::value_c ri_caction_admitted_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 14) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_caction_admitted_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 14) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ri_caction_admitted_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RICaction-Admitted-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ri_caction_admitted_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_admitted_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ri_caction_admitted_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICaction-Admitted-Item"}; + return convert_enum_idx(options, 1, value, "ri_caction_admitted_item_ies_o::value_c::types"); +} + +// RICaction-NotAdmitted-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_caction_not_admitted_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {16}; + return map_enum_number(options, 1, idx, "id"); +} +bool ri_caction_not_admitted_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 16 == id; +} +crit_e ri_caction_not_admitted_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 16) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ri_caction_not_admitted_item_ies_o::value_c ri_caction_not_admitted_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 16) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_caction_not_admitted_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 16) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ri_caction_not_admitted_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RICaction-NotAdmitted-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ri_caction_not_admitted_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_not_admitted_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ri_caction_not_admitted_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICaction-NotAdmitted-Item"}; + return convert_enum_idx(options, 1, value, "ri_caction_not_admitted_item_ies_o::value_c::types"); +} + +template struct asn1::protocol_ie_single_container_s; + +// RICsubscription-withCause-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_with_cause_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {61}; + return map_enum_number(options, 1, idx, "id"); +} +bool ricsubscription_with_cause_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 61 == id; +} +crit_e ricsubscription_with_cause_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 61) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ricsubscription_with_cause_item_ies_o::value_c ricsubscription_with_cause_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 61) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_with_cause_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 61) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_with_cause_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RICsubscription-withCause-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ricsubscription_with_cause_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_with_cause_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ricsubscription_with_cause_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICsubscription-withCause-Item"}; + return convert_enum_idx(options, 1, value, "ricsubscription_with_cause_item_ies_o::value_c::types"); +} + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +// GlobalE2node-ID ::= CHOICE +void global_e2node_id_c::destroy_() +{ + switch (type_) { + case types::gnb: + c.destroy(); + break; + case types::en_g_nb: + c.destroy(); + break; + case types::ng_enb: + c.destroy(); + break; + case types::enb: + c.destroy(); + break; + default: + break; + } +} +void global_e2node_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb: + c.init(); + break; + case types::en_g_nb: + c.init(); + break; + case types::ng_enb: + c.init(); + break; + case types::enb: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + } +} +global_e2node_id_c::global_e2node_id_c(const global_e2node_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb: + c.init(other.c.get()); + break; + case types::en_g_nb: + c.init(other.c.get()); + break; + case types::ng_enb: + c.init(other.c.get()); + break; + case types::enb: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + } +} +global_e2node_id_c& global_e2node_id_c::operator=(const global_e2node_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb: + c.set(other.c.get()); + break; + case types::en_g_nb: + c.set(other.c.get()); + break; + case types::ng_enb: + c.set(other.c.get()); + break; + case types::enb: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + } + + return *this; +} +global_e2node_g_nb_id_s& global_e2node_id_c::set_gnb() +{ + set(types::gnb); + return c.get(); +} +global_e2node_en_g_nb_id_s& global_e2node_id_c::set_en_g_nb() +{ + set(types::en_g_nb); + return c.get(); +} +global_e2node_ng_enb_id_s& global_e2node_id_c::set_ng_enb() +{ + set(types::ng_enb); + return c.get(); +} +global_e2node_enb_id_s& global_e2node_id_c::set_enb() +{ + set(types::enb); + return c.get(); +} +void global_e2node_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb: + j.write_fieldname("gNB"); + c.get().to_json(j); + break; + case types::en_g_nb: + j.write_fieldname("en-gNB"); + c.get().to_json(j); + break; + case types::ng_enb: + j.write_fieldname("ng-eNB"); + c.get().to_json(j); + break; + case types::enb: + j.write_fieldname("eNB"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_e2node_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::en_g_nb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::enb: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_e2node_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::en_g_nb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::enb: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_e2node_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB", "en-gNB", "ng-eNB", "eNB"}; + return convert_enum_idx(options, 4, value, "global_e2node_id_c::types"); +} + +// GlobalRIC-ID ::= SEQUENCE +SRSASN_CODE global_ric_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(ric_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ric_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(ric_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_ric_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_str("ric-ID", ric_id.to_string()); + j.end_obj(); +} + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +// RICcontrolAckRequest ::= ENUMERATED +const char* ri_cctrl_ack_request_opts::to_string() const +{ + static const char* options[] = {"noAck", "ack"}; + return convert_enum_idx(options, 2, value, "ri_cctrl_ack_request_e"); +} + +// RICindicationType ::= ENUMERATED +const char* ri_cind_type_opts::to_string() const +{ + static const char* options[] = {"report", "insert"}; + return convert_enum_idx(options, 2, value, "ri_cind_type_e"); +} + +template struct asn1::protocol_ie_single_container_s; + +// RICsubscriptionDetails ::= SEQUENCE +SRSASN_CODE ricsubscription_details_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ric_event_trigger_definition.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, ric_action_to_be_setup_list, 1, 16, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_details_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ric_event_trigger_definition.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(ric_action_to_be_setup_list, bref, 1, 16, true)); + + return SRSASN_SUCCESS; +} +void ricsubscription_details_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ricEventTriggerDefinition", ric_event_trigger_definition.to_string()); + j.start_array("ricAction-ToBeSetup-List"); + for (const auto& e1 : ric_action_to_be_setup_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// TimeToWait ::= ENUMERATED +const char* time_to_wait_opts::to_string() const +{ + static const char* options[] = {"v1s", "v2s", "v5s", "v10s", "v20s", "v60s"}; + return convert_enum_idx(options, 6, value, "time_to_wait_e"); +} +uint8_t time_to_wait_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 5, 10, 20, 60}; + return map_enum_number(options, 6, value, "time_to_wait_e"); +} + +// E2RemovalFailureIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2_removal_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1, 2}; + return map_enum_number(options, 3, idx, "id"); +} +bool e2_removal_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2_removal_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2_removal_fail_ies_o::value_c e2_removal_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2_removal_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2_removal_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void e2_removal_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + } +} +e2_removal_fail_ies_o::value_c::value_c(const e2_removal_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + } +} +e2_removal_fail_ies_o::value_c& e2_removal_fail_ies_o::value_c::operator=(const e2_removal_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2_removal_fail_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& e2_removal_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& e2_removal_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& e2_removal_fail_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& e2_removal_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& e2_removal_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void e2_removal_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_removal_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_removal_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_removal_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "Cause", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 3, value, "e2_removal_fail_ies_o::value_c::types"); +} +uint8_t e2_removal_fail_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2_removal_fail_ies_o::value_c::types"); +} + +// E2RemovalRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2_removal_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2_removal_request_ies_o::is_id_valid(const uint32_t& id) +{ + return 49 == id; +} +crit_e e2_removal_request_ies_o::get_crit(const uint32_t& id) +{ + if (id == 49) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2_removal_request_ies_o::value_c e2_removal_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 49) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2_removal_request_ies_o::get_presence(const uint32_t& id) +{ + if (id == 49) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2_removal_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("INTEGER (0..255,...)", c); + j.end_obj(); +} +SRSASN_CODE e2_removal_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(pack_integer(bref, c, (uint16_t)0u, (uint16_t)255u, true, true)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_removal_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(unpack_integer(c, bref, (uint16_t)0u, (uint16_t)255u, true, true)); + return SRSASN_SUCCESS; +} + +const char* e2_removal_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)"}; + return convert_enum_idx(options, 1, value, "e2_removal_request_ies_o::value_c::types"); +} +uint8_t e2_removal_request_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2_removal_request_ies_o::value_c::types"); +} + +// E2RemovalResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2_removal_resp_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 2}; + return map_enum_number(options, 2, idx, "id"); +} +bool e2_removal_resp_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2_removal_resp_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2_removal_resp_ies_o::value_c e2_removal_resp_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2_removal_resp_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2_removal_resp_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void e2_removal_resp_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + } +} +e2_removal_resp_ies_o::value_c::value_c(const e2_removal_resp_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + } +} +e2_removal_resp_ies_o::value_c& e2_removal_resp_ies_o::value_c::operator=(const e2_removal_resp_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2_removal_resp_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& e2_removal_resp_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& e2_removal_resp_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& e2_removal_resp_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void e2_removal_resp_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_removal_resp_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_removal_resp_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_removal_resp_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 2, value, "e2_removal_resp_ies_o::value_c::types"); +} +uint8_t e2_removal_resp_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2_removal_resp_ies_o::value_c::types"); +} + +// E2connectionUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_upd_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 44, 46, 45}; + return map_enum_number(options, 4, idx, "id"); +} +bool e2conn_upd_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 44, 46, 45}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2conn_upd_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 44: + return crit_e::reject; + case 46: + return crit_e::reject; + case 45: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2conn_upd_ies_o::value_c e2conn_upd_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 44: + ret.set(value_c::types::e2conn_upd_add); + break; + case 46: + ret.set(value_c::types::e2conn_upd_rem); + break; + case 45: + ret.set(value_c::types::e2conn_upd_modify); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_upd_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 44: + return presence_e::optional; + case 46: + return presence_e::optional; + case 45: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_upd_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::e2conn_upd_add: + c.destroy(); + break; + case types::e2conn_upd_rem: + c.destroy(); + break; + case types::e2conn_upd_modify: + c.destroy(); + break; + default: + break; + } +} +void e2conn_upd_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::e2conn_upd_add: + c.init(); + break; + case types::e2conn_upd_rem: + c.init(); + break; + case types::e2conn_upd_modify: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + } +} +e2conn_upd_ies_o::value_c::value_c(const e2conn_upd_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::e2conn_upd_add: + c.init(other.c.get()); + break; + case types::e2conn_upd_rem: + c.init(other.c.get()); + break; + case types::e2conn_upd_modify: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + } +} +e2conn_upd_ies_o::value_c& e2conn_upd_ies_o::value_c::operator=(const e2conn_upd_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::e2conn_upd_add: + c.set(other.c.get()); + break; + case types::e2conn_upd_rem: + c.set(other.c.get()); + break; + case types::e2conn_upd_modify: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2conn_upd_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +e2conn_upd_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_add() +{ + assert_choice_type(types::e2conn_upd_add, type_, "Value"); + return c.get(); +} +e2conn_upd_rem_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_rem() +{ + assert_choice_type(types::e2conn_upd_rem, type_, "Value"); + return c.get(); +} +e2conn_upd_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_modify() +{ + assert_choice_type(types::e2conn_upd_modify, type_, "Value"); + return c.get(); +} +const uint16_t& e2conn_upd_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const e2conn_upd_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_add() const +{ + assert_choice_type(types::e2conn_upd_add, type_, "Value"); + return c.get(); +} +const e2conn_upd_rem_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_rem() const +{ + assert_choice_type(types::e2conn_upd_rem, type_, "Value"); + return c.get(); +} +const e2conn_upd_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_modify() const +{ + assert_choice_type(types::e2conn_upd_modify, type_, "Value"); + return c.get(); +} +void e2conn_upd_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::e2conn_upd_add: + j.start_array("E2connectionUpdate-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2conn_upd_rem: + j.start_array("E2connectionUpdateRemove-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2conn_upd_modify: + j.start_array("E2connectionUpdate-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2conn_upd_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2conn_upd_add: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + case types::e2conn_upd_rem: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + case types::e2conn_upd_modify: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2conn_upd_add: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + case types::e2conn_upd_rem: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + case types::e2conn_upd_modify: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2conn_upd_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "INTEGER (0..255,...)", "E2connectionUpdate-List", "E2connectionUpdateRemove-List", "E2connectionUpdate-List"}; + return convert_enum_idx(options, 4, value, "e2conn_upd_ies_o::value_c::types"); +} + +// E2connectionUpdateAck-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_upd_ack_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 39, 40}; + return map_enum_number(options, 3, idx, "id"); +} +bool e2conn_upd_ack_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 39, 40}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2conn_upd_ack_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 39: + return crit_e::reject; + case 40: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2conn_upd_ack_ies_o::value_c e2conn_upd_ack_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 39: + ret.set(value_c::types::e2conn_setup); + break; + case 40: + ret.set(value_c::types::e2conn_setup_failed); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_upd_ack_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 39: + return presence_e::optional; + case 40: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_upd_ack_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::e2conn_setup: + c.destroy(); + break; + case types::e2conn_setup_failed: + c.destroy(); + break; + default: + break; + } +} +void e2conn_upd_ack_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::e2conn_setup: + c.init(); + break; + case types::e2conn_setup_failed: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + } +} +e2conn_upd_ack_ies_o::value_c::value_c(const e2conn_upd_ack_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::e2conn_setup: + c.init(other.c.get()); + break; + case types::e2conn_setup_failed: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + } +} +e2conn_upd_ack_ies_o::value_c& e2conn_upd_ack_ies_o::value_c::operator=(const e2conn_upd_ack_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::e2conn_setup: + c.set(other.c.get()); + break; + case types::e2conn_setup_failed: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2conn_upd_ack_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +e2conn_upd_list_l& e2conn_upd_ack_ies_o::value_c::e2conn_setup() +{ + assert_choice_type(types::e2conn_setup, type_, "Value"); + return c.get(); +} +e2conn_setup_failed_list_l& e2conn_upd_ack_ies_o::value_c::e2conn_setup_failed() +{ + assert_choice_type(types::e2conn_setup_failed, type_, "Value"); + return c.get(); +} +const uint16_t& e2conn_upd_ack_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const e2conn_upd_list_l& e2conn_upd_ack_ies_o::value_c::e2conn_setup() const +{ + assert_choice_type(types::e2conn_setup, type_, "Value"); + return c.get(); +} +const e2conn_setup_failed_list_l& e2conn_upd_ack_ies_o::value_c::e2conn_setup_failed() const +{ + assert_choice_type(types::e2conn_setup_failed, type_, "Value"); + return c.get(); +} +void e2conn_upd_ack_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::e2conn_setup: + j.start_array("E2connectionUpdate-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2conn_setup_failed: + j.start_array("E2connectionSetupFailed-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2conn_upd_ack_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2conn_setup: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + case types::e2conn_setup_failed: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_ack_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2conn_setup: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + case types::e2conn_setup_failed: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2conn_upd_ack_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "E2connectionUpdate-List", "E2connectionSetupFailed-List"}; + return convert_enum_idx(options, 3, value, "e2conn_upd_ack_ies_o::value_c::types"); +} + +// E2connectionUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_upd_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + return map_enum_number(options, 4, idx, "id"); +} +bool e2conn_upd_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2conn_upd_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::reject; + case 31: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2conn_upd_fail_ies_o::value_c e2conn_upd_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 31: + ret.set(value_c::types::time_to_wait); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_upd_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::optional; + case 31: + return presence_e::optional; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_upd_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void e2conn_upd_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::time_to_wait: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + } +} +e2conn_upd_fail_ies_o::value_c::value_c(const e2conn_upd_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::time_to_wait: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + } +} +e2conn_upd_fail_ies_o::value_c& e2conn_upd_fail_ies_o::value_c::operator=(const e2conn_upd_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::time_to_wait: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2conn_upd_fail_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& e2conn_upd_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +time_to_wait_e& e2conn_upd_fail_ies_o::value_c::time_to_wait() +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& e2conn_upd_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& e2conn_upd_fail_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& e2conn_upd_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const time_to_wait_e& e2conn_upd_fail_ies_o::value_c::time_to_wait() const +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& e2conn_upd_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void e2conn_upd_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::time_to_wait: + j.write_str("TimeToWait", c.get().to_string()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2conn_upd_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2conn_upd_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "Cause", "TimeToWait", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 4, value, "e2conn_upd_fail_ies_o::value_c::types"); +} +uint8_t e2conn_upd_fail_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2conn_upd_fail_ies_o::value_c::types"); +} + +// E2nodeConfigurationUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_cfg_upd_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 3, 50, 33, 54, 58}; + return map_enum_number(options, 6, idx, "id"); +} +bool e2node_cfg_upd_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 3, 50, 33, 54, 58}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2node_cfg_upd_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 3: + return crit_e::reject; + case 50: + return crit_e::reject; + case 33: + return crit_e::reject; + case 54: + return crit_e::reject; + case 58: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2node_cfg_upd_ies_o::value_c e2node_cfg_upd_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 3: + ret.set(value_c::types::global_e2node_id); + break; + case 50: + ret.set(value_c::types::e2node_component_cfg_addition); + break; + case 33: + ret.set(value_c::types::e2node_component_cfg_upd); + break; + case 54: + ret.set(value_c::types::e2node_component_cfg_removal); + break; + case 58: + ret.set(value_c::types::e2node_tn_lassoc_removal); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_cfg_upd_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 3: + return presence_e::optional; + case 50: + return presence_e::optional; + case 33: + return presence_e::optional; + case 54: + return presence_e::optional; + case 58: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2node_cfg_upd_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::global_e2node_id: + c.destroy(); + break; + case types::e2node_component_cfg_addition: + c.destroy(); + break; + case types::e2node_component_cfg_upd: + c.destroy(); + break; + case types::e2node_component_cfg_removal: + c.destroy(); + break; + case types::e2node_tn_lassoc_removal: + c.destroy(); + break; + default: + break; + } +} +void e2node_cfg_upd_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::global_e2node_id: + c.init(); + break; + case types::e2node_component_cfg_addition: + c.init(); + break; + case types::e2node_component_cfg_upd: + c.init(); + break; + case types::e2node_component_cfg_removal: + c.init(); + break; + case types::e2node_tn_lassoc_removal: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + } +} +e2node_cfg_upd_ies_o::value_c::value_c(const e2node_cfg_upd_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::global_e2node_id: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_addition: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_upd: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_removal: + c.init(other.c.get()); + break; + case types::e2node_tn_lassoc_removal: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + } +} +e2node_cfg_upd_ies_o::value_c& e2node_cfg_upd_ies_o::value_c::operator=(const e2node_cfg_upd_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::global_e2node_id: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_addition: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_upd: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_removal: + c.set(other.c.get()); + break; + case types::e2node_tn_lassoc_removal: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2node_cfg_upd_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +global_e2node_id_c& e2node_cfg_upd_ies_o::value_c::global_e2node_id() +{ + assert_choice_type(types::global_e2node_id, type_, "Value"); + return c.get(); +} +e2node_component_cfg_addition_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_addition() +{ + assert_choice_type(types::e2node_component_cfg_addition, type_, "Value"); + return c.get(); +} +e2node_component_cfg_upd_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_upd() +{ + assert_choice_type(types::e2node_component_cfg_upd, type_, "Value"); + return c.get(); +} +e2node_component_cfg_removal_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_removal() +{ + assert_choice_type(types::e2node_component_cfg_removal, type_, "Value"); + return c.get(); +} +e2node_tn_lassoc_removal_list_l& e2node_cfg_upd_ies_o::value_c::e2node_tn_lassoc_removal() +{ + assert_choice_type(types::e2node_tn_lassoc_removal, type_, "Value"); + return c.get(); +} +const uint16_t& e2node_cfg_upd_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const global_e2node_id_c& e2node_cfg_upd_ies_o::value_c::global_e2node_id() const +{ + assert_choice_type(types::global_e2node_id, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_addition_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_addition() const +{ + assert_choice_type(types::e2node_component_cfg_addition, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_upd_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_upd() const +{ + assert_choice_type(types::e2node_component_cfg_upd, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_removal_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_removal() const +{ + assert_choice_type(types::e2node_component_cfg_removal, type_, "Value"); + return c.get(); +} +const e2node_tn_lassoc_removal_list_l& e2node_cfg_upd_ies_o::value_c::e2node_tn_lassoc_removal() const +{ + assert_choice_type(types::e2node_tn_lassoc_removal, type_, "Value"); + return c.get(); +} +void e2node_cfg_upd_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::global_e2node_id: + j.write_fieldname("GlobalE2node-ID"); + c.get().to_json(j); + break; + case types::e2node_component_cfg_addition: + j.start_array("E2nodeComponentConfigAddition-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_upd: + j.start_array("E2nodeComponentConfigUpdate-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_removal: + j.start_array("E2nodeComponentConfigRemoval-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_tn_lassoc_removal: + j.start_array("E2nodeTNLassociationRemoval-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2node_cfg_upd_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_e2node_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_cfg_addition: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + case types::e2node_component_cfg_upd: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + case types::e2node_component_cfg_removal: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + case types::e2node_tn_lassoc_removal: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_e2node_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_cfg_addition: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + case types::e2node_component_cfg_upd: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + case types::e2node_component_cfg_removal: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + case types::e2node_tn_lassoc_removal: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2node_cfg_upd_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", + "GlobalE2node-ID", + "E2nodeComponentConfigAddition-List", + "E2nodeComponentConfigUpdate-List", + "E2nodeComponentConfigRemoval-List", + "E2nodeTNLassociationRemoval-List"}; + return convert_enum_idx(options, 6, value, "e2node_cfg_upd_ies_o::value_c::types"); +} + +// E2nodeConfigurationUpdateAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_cfg_upd_ack_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 52, 35, 56}; + return map_enum_number(options, 4, idx, "id"); +} +bool e2node_cfg_upd_ack_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 52, 35, 56}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2node_cfg_upd_ack_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 52: + return crit_e::reject; + case 35: + return crit_e::reject; + case 56: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2node_cfg_upd_ack_ies_o::value_c e2node_cfg_upd_ack_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 52: + ret.set(value_c::types::e2node_component_cfg_addition_ack); + break; + case 35: + ret.set(value_c::types::e2node_component_cfg_upd_ack); + break; + case 56: + ret.set(value_c::types::e2node_component_cfg_removal_ack); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_cfg_upd_ack_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 52: + return presence_e::optional; + case 35: + return presence_e::optional; + case 56: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2node_cfg_upd_ack_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::e2node_component_cfg_addition_ack: + c.destroy(); + break; + case types::e2node_component_cfg_upd_ack: + c.destroy(); + break; + case types::e2node_component_cfg_removal_ack: + c.destroy(); + break; + default: + break; + } +} +void e2node_cfg_upd_ack_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::e2node_component_cfg_addition_ack: + c.init(); + break; + case types::e2node_component_cfg_upd_ack: + c.init(); + break; + case types::e2node_component_cfg_removal_ack: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + } +} +e2node_cfg_upd_ack_ies_o::value_c::value_c(const e2node_cfg_upd_ack_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_addition_ack: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_upd_ack: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_removal_ack: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + } +} +e2node_cfg_upd_ack_ies_o::value_c& +e2node_cfg_upd_ack_ies_o::value_c::operator=(const e2node_cfg_upd_ack_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_addition_ack: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_upd_ack: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_removal_ack: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2node_cfg_upd_ack_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +e2node_component_cfg_addition_ack_list_l& e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_addition_ack() +{ + assert_choice_type(types::e2node_component_cfg_addition_ack, type_, "Value"); + return c.get(); +} +e2node_component_cfg_upd_ack_list_l& e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_upd_ack() +{ + assert_choice_type(types::e2node_component_cfg_upd_ack, type_, "Value"); + return c.get(); +} +e2node_component_cfg_removal_ack_list_l& e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_removal_ack() +{ + assert_choice_type(types::e2node_component_cfg_removal_ack, type_, "Value"); + return c.get(); +} +const uint16_t& e2node_cfg_upd_ack_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_addition_ack_list_l& +e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_addition_ack() const +{ + assert_choice_type(types::e2node_component_cfg_addition_ack, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_upd_ack_list_l& e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_upd_ack() const +{ + assert_choice_type(types::e2node_component_cfg_upd_ack, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_removal_ack_list_l& +e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_removal_ack() const +{ + assert_choice_type(types::e2node_component_cfg_removal_ack, type_, "Value"); + return c.get(); +} +void e2node_cfg_upd_ack_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::e2node_component_cfg_addition_ack: + j.start_array("E2nodeComponentConfigAdditionAck-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_upd_ack: + j.start_array("E2nodeComponentConfigUpdateAck-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_removal_ack: + j.start_array("E2nodeComponentConfigRemovalAck-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2node_cfg_upd_ack_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2node_component_cfg_addition_ack: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + case types::e2node_component_cfg_upd_ack: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + case types::e2node_component_cfg_removal_ack: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_ack_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2node_component_cfg_addition_ack: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + case types::e2node_component_cfg_upd_ack: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + case types::e2node_component_cfg_removal_ack: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2node_cfg_upd_ack_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", + "E2nodeComponentConfigAdditionAck-List", + "E2nodeComponentConfigUpdateAck-List", + "E2nodeComponentConfigRemovalAck-List"}; + return convert_enum_idx(options, 4, value, "e2node_cfg_upd_ack_ies_o::value_c::types"); +} + +// E2nodeConfigurationUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_cfg_upd_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + return map_enum_number(options, 4, idx, "id"); +} +bool e2node_cfg_upd_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2node_cfg_upd_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 31: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2node_cfg_upd_fail_ies_o::value_c e2node_cfg_upd_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 31: + ret.set(value_c::types::time_to_wait); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_cfg_upd_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 31: + return presence_e::optional; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2node_cfg_upd_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void e2node_cfg_upd_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::time_to_wait: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + } +} +e2node_cfg_upd_fail_ies_o::value_c::value_c(const e2node_cfg_upd_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::time_to_wait: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + } +} +e2node_cfg_upd_fail_ies_o::value_c& +e2node_cfg_upd_fail_ies_o::value_c::operator=(const e2node_cfg_upd_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::time_to_wait: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2node_cfg_upd_fail_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& e2node_cfg_upd_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +time_to_wait_e& e2node_cfg_upd_fail_ies_o::value_c::time_to_wait() +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& e2node_cfg_upd_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& e2node_cfg_upd_fail_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& e2node_cfg_upd_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const time_to_wait_e& e2node_cfg_upd_fail_ies_o::value_c::time_to_wait() const +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& e2node_cfg_upd_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void e2node_cfg_upd_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::time_to_wait: + j.write_str("TimeToWait", c.get().to_string()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2node_cfg_upd_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2node_cfg_upd_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "Cause", "TimeToWait", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 4, value, "e2node_cfg_upd_fail_ies_o::value_c::types"); +} +uint8_t e2node_cfg_upd_fail_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2node_cfg_upd_fail_ies_o::value_c::types"); +} + +// E2setupFailureIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2setup_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1, 31, 2, 48}; + return map_enum_number(options, 5, idx, "id"); +} +bool e2setup_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1, 31, 2, 48}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2setup_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 31: + return crit_e::ignore; + case 2: + return crit_e::ignore; + case 48: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2setup_fail_ies_o::value_c e2setup_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 31: + ret.set(value_c::types::time_to_wait); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + case 48: + ret.set(value_c::types::tn_linfo); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2setup_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 31: + return presence_e::optional; + case 2: + return presence_e::optional; + case 48: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2setup_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + case types::tn_linfo: + c.destroy(); + break; + default: + break; + } +} +void e2setup_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::time_to_wait: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::tn_linfo: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + } +} +e2setup_fail_ies_o::value_c::value_c(const e2setup_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::time_to_wait: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::tn_linfo: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + } +} +e2setup_fail_ies_o::value_c& e2setup_fail_ies_o::value_c::operator=(const e2setup_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::time_to_wait: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::tn_linfo: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2setup_fail_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& e2setup_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +time_to_wait_e& e2setup_fail_ies_o::value_c::time_to_wait() +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& e2setup_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +tn_linfo_s& e2setup_fail_ies_o::value_c::tn_linfo() +{ + assert_choice_type(types::tn_linfo, type_, "Value"); + return c.get(); +} +const uint16_t& e2setup_fail_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& e2setup_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const time_to_wait_e& e2setup_fail_ies_o::value_c::time_to_wait() const +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& e2setup_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const tn_linfo_s& e2setup_fail_ies_o::value_c::tn_linfo() const +{ + assert_choice_type(types::tn_linfo, type_, "Value"); + return c.get(); +} +void e2setup_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::time_to_wait: + j.write_str("TimeToWait", c.get().to_string()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + case types::tn_linfo: + j.write_fieldname("TNLinformation"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2setup_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::tn_linfo: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::tn_linfo: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2setup_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "INTEGER (0..255,...)", "Cause", "TimeToWait", "CriticalityDiagnostics", "TNLinformation"}; + return convert_enum_idx(options, 5, value, "e2setup_fail_ies_o::value_c::types"); +} +uint8_t e2setup_fail_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2setup_fail_ies_o::value_c::types"); +} + +// E2setupRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2setup_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 3, 10, 50}; + return map_enum_number(options, 4, idx, "id"); +} +bool e2setup_request_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 3, 10, 50}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2setup_request_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 3: + return crit_e::reject; + case 10: + return crit_e::reject; + case 50: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2setup_request_ies_o::value_c e2setup_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 3: + ret.set(value_c::types::global_e2node_id); + break; + case 10: + ret.set(value_c::types::ra_nfunctions_added); + break; + case 50: + ret.set(value_c::types::e2node_component_cfg_addition); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2setup_request_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 3: + return presence_e::mandatory; + case 10: + return presence_e::mandatory; + case 50: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2setup_request_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::global_e2node_id: + c.destroy(); + break; + case types::ra_nfunctions_added: + c.destroy(); + break; + case types::e2node_component_cfg_addition: + c.destroy(); + break; + default: + break; + } +} +void e2setup_request_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::global_e2node_id: + c.init(); + break; + case types::ra_nfunctions_added: + c.init(); + break; + case types::e2node_component_cfg_addition: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + } +} +e2setup_request_ies_o::value_c::value_c(const e2setup_request_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::global_e2node_id: + c.init(other.c.get()); + break; + case types::ra_nfunctions_added: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_addition: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + } +} +e2setup_request_ies_o::value_c& e2setup_request_ies_o::value_c::operator=(const e2setup_request_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::global_e2node_id: + c.set(other.c.get()); + break; + case types::ra_nfunctions_added: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_addition: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2setup_request_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +global_e2node_id_c& e2setup_request_ies_o::value_c::global_e2node_id() +{ + assert_choice_type(types::global_e2node_id, type_, "Value"); + return c.get(); +} +ra_nfunctions_list_l& e2setup_request_ies_o::value_c::ra_nfunctions_added() +{ + assert_choice_type(types::ra_nfunctions_added, type_, "Value"); + return c.get(); +} +e2node_component_cfg_addition_list_l& e2setup_request_ies_o::value_c::e2node_component_cfg_addition() +{ + assert_choice_type(types::e2node_component_cfg_addition, type_, "Value"); + return c.get(); +} +const uint16_t& e2setup_request_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const global_e2node_id_c& e2setup_request_ies_o::value_c::global_e2node_id() const +{ + assert_choice_type(types::global_e2node_id, type_, "Value"); + return c.get(); +} +const ra_nfunctions_list_l& e2setup_request_ies_o::value_c::ra_nfunctions_added() const +{ + assert_choice_type(types::ra_nfunctions_added, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_addition_list_l& e2setup_request_ies_o::value_c::e2node_component_cfg_addition() const +{ + assert_choice_type(types::e2node_component_cfg_addition, type_, "Value"); + return c.get(); +} +void e2setup_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::global_e2node_id: + j.write_fieldname("GlobalE2node-ID"); + c.get().to_json(j); + break; + case types::ra_nfunctions_added: + j.start_array("RANfunctions-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_addition: + j.start_array("E2nodeComponentConfigAddition-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2setup_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_e2node_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunctions_added: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::e2node_component_cfg_addition: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_e2node_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunctions_added: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::e2node_component_cfg_addition: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2setup_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "INTEGER (0..255,...)", "GlobalE2node-ID", "RANfunctions-List", "E2nodeComponentConfigAddition-List"}; + return convert_enum_idx(options, 4, value, "e2setup_request_ies_o::value_c::types"); +} + +// E2setupResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2setup_resp_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 4, 9, 13, 52}; + return map_enum_number(options, 5, idx, "id"); +} +bool e2setup_resp_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 4, 9, 13, 52}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2setup_resp_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 4: + return crit_e::reject; + case 9: + return crit_e::reject; + case 13: + return crit_e::reject; + case 52: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2setup_resp_ies_o::value_c e2setup_resp_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 4: + ret.set(value_c::types::global_ric_id); + break; + case 9: + ret.set(value_c::types::ra_nfunctions_accepted); + break; + case 13: + ret.set(value_c::types::ra_nfunctions_rejected); + break; + case 52: + ret.set(value_c::types::e2node_component_cfg_addition_ack); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2setup_resp_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 4: + return presence_e::mandatory; + case 9: + return presence_e::optional; + case 13: + return presence_e::optional; + case 52: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2setup_resp_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::global_ric_id: + c.destroy(); + break; + case types::ra_nfunctions_accepted: + c.destroy(); + break; + case types::ra_nfunctions_rejected: + c.destroy(); + break; + case types::e2node_component_cfg_addition_ack: + c.destroy(); + break; + default: + break; + } +} +void e2setup_resp_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::global_ric_id: + c.init(); + break; + case types::ra_nfunctions_accepted: + c.init(); + break; + case types::ra_nfunctions_rejected: + c.init(); + break; + case types::e2node_component_cfg_addition_ack: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + } +} +e2setup_resp_ies_o::value_c::value_c(const e2setup_resp_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::global_ric_id: + c.init(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.init(other.c.get()); + break; + case types::ra_nfunctions_rejected: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_addition_ack: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + } +} +e2setup_resp_ies_o::value_c& e2setup_resp_ies_o::value_c::operator=(const e2setup_resp_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::global_ric_id: + c.set(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.set(other.c.get()); + break; + case types::ra_nfunctions_rejected: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_addition_ack: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2setup_resp_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +global_ric_id_s& e2setup_resp_ies_o::value_c::global_ric_id() +{ + assert_choice_type(types::global_ric_id, type_, "Value"); + return c.get(); +} +ra_nfunctions_id_list_l& e2setup_resp_ies_o::value_c::ra_nfunctions_accepted() +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +ra_nfunctions_idcause_list_l& e2setup_resp_ies_o::value_c::ra_nfunctions_rejected() +{ + assert_choice_type(types::ra_nfunctions_rejected, type_, "Value"); + return c.get(); +} +e2node_component_cfg_addition_ack_list_l& e2setup_resp_ies_o::value_c::e2node_component_cfg_addition_ack() +{ + assert_choice_type(types::e2node_component_cfg_addition_ack, type_, "Value"); + return c.get(); +} +const uint16_t& e2setup_resp_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const global_ric_id_s& e2setup_resp_ies_o::value_c::global_ric_id() const +{ + assert_choice_type(types::global_ric_id, type_, "Value"); + return c.get(); +} +const ra_nfunctions_id_list_l& e2setup_resp_ies_o::value_c::ra_nfunctions_accepted() const +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +const ra_nfunctions_idcause_list_l& e2setup_resp_ies_o::value_c::ra_nfunctions_rejected() const +{ + assert_choice_type(types::ra_nfunctions_rejected, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_addition_ack_list_l& e2setup_resp_ies_o::value_c::e2node_component_cfg_addition_ack() const +{ + assert_choice_type(types::e2node_component_cfg_addition_ack, type_, "Value"); + return c.get(); +} +void e2setup_resp_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::global_ric_id: + j.write_fieldname("GlobalRIC-ID"); + c.get().to_json(j); + break; + case types::ra_nfunctions_accepted: + j.start_array("RANfunctionsID-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::ra_nfunctions_rejected: + j.start_array("RANfunctionsIDcause-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_addition_ack: + j.start_array("E2nodeComponentConfigAdditionAck-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2setup_resp_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_ric_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::ra_nfunctions_rejected: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::e2node_component_cfg_addition_ack: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_resp_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_ric_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::ra_nfunctions_rejected: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::e2node_component_cfg_addition_ack: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2setup_resp_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", + "GlobalRIC-ID", + "RANfunctionsID-List", + "RANfunctionsIDcause-List", + "E2nodeComponentConfigAdditionAck-List"}; + return convert_enum_idx(options, 5, value, "e2setup_resp_ies_o::value_c::types"); +} +uint8_t e2setup_resp_ies_o::value_c::types_opts::to_number() const +{ + switch (value) { + case transaction_id: + return 0; + case e2node_component_cfg_addition_ack: + return 2; + default: + invalid_enum_number(value, "e2setup_resp_ies_o::value_c::types"); + } + return 0; +} + +// ErrorIndication-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t error_ind_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 29, 5, 1, 2}; + return map_enum_number(options, 5, idx, "id"); +} +bool error_ind_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 29, 5, 1, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e error_ind_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +error_ind_ies_o::value_c error_ind_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e error_ind_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::optional; + case 29: + return presence_e::optional; + case 5: + return presence_e::optional; + case 1: + return presence_e::optional; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void error_ind_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void error_ind_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::cause: + c.init(); + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + } +} +error_ind_ies_o::value_c::value_c(const error_ind_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + } +} +error_ind_ies_o::value_c& error_ind_ies_o::value_c::operator=(const error_ind_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + } + + return *this; +} +uint16_t& error_ind_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +ri_crequest_id_s& error_ind_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& error_ind_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +cause_c& error_ind_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& error_ind_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& error_ind_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& error_ind_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& error_ind_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const cause_c& error_ind_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& error_ind_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void error_ind_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE error_ind_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE error_ind_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* error_ind_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "INTEGER (0..255,...)", "RICrequestID", "INTEGER (0..4095)", "Cause", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 5, value, "error_ind_ies_o::value_c::types"); +} + +// RICcontrolAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_cctrl_ack_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 20, 32}; + return map_enum_number(options, 4, idx, "id"); +} +bool ri_cctrl_ack_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 20, 32}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ri_cctrl_ack_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 20: + return crit_e::reject; + case 32: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ri_cctrl_ack_ies_o::value_c ri_cctrl_ack_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 20: + ret.set(value_c::types::ri_ccall_process_id); + break; + case 32: + ret.set(value_c::types::ri_cctrl_outcome); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_cctrl_ack_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 20: + return presence_e::optional; + case 32: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ri_cctrl_ack_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ri_ccall_process_id: + c.destroy >(); + break; + case types::ri_cctrl_outcome: + c.destroy >(); + break; + default: + break; + } +} +void ri_cctrl_ack_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ri_ccall_process_id: + c.init >(); + break; + case types::ri_cctrl_outcome: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + } +} +ri_cctrl_ack_ies_o::value_c::value_c(const ri_cctrl_ack_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ri_ccall_process_id: + c.init(other.c.get >()); + break; + case types::ri_cctrl_outcome: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + } +} +ri_cctrl_ack_ies_o::value_c& ri_cctrl_ack_ies_o::value_c::operator=(const ri_cctrl_ack_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ri_ccall_process_id: + c.set(other.c.get >()); + break; + case types::ri_cctrl_outcome: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ri_cctrl_ack_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ri_cctrl_ack_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +unbounded_octstring& ri_cctrl_ack_ies_o::value_c::ri_ccall_process_id() +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +unbounded_octstring& ri_cctrl_ack_ies_o::value_c::ri_cctrl_outcome() +{ + assert_choice_type(types::ri_cctrl_outcome, type_, "Value"); + return c.get >(); +} +const ri_crequest_id_s& ri_cctrl_ack_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ri_cctrl_ack_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const unbounded_octstring& ri_cctrl_ack_ies_o::value_c::ri_ccall_process_id() const +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +const unbounded_octstring& ri_cctrl_ack_ies_o::value_c::ri_cctrl_outcome() const +{ + assert_choice_type(types::ri_cctrl_outcome, type_, "Value"); + return c.get >(); +} +void ri_cctrl_ack_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ri_ccall_process_id: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_cctrl_outcome: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ri_cctrl_ack_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_cctrl_outcome: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_ack_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_cctrl_outcome: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ri_cctrl_ack_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)", "OCTET STRING", "OCTET STRING"}; + return convert_enum_idx(options, 4, value, "ri_cctrl_ack_ies_o::value_c::types"); +} +uint8_t ri_cctrl_ack_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ri_cctrl_ack_ies_o::value_c::types"); + return 0; +} + +// RICcontrolFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_cctrl_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 20, 1, 32}; + return map_enum_number(options, 5, idx, "id"); +} +bool ri_cctrl_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 20, 1, 32}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ri_cctrl_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 20: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 32: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ri_cctrl_fail_ies_o::value_c ri_cctrl_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 20: + ret.set(value_c::types::ri_ccall_process_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 32: + ret.set(value_c::types::ri_cctrl_outcome); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_cctrl_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 20: + return presence_e::optional; + case 1: + return presence_e::mandatory; + case 32: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ri_cctrl_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ri_ccall_process_id: + c.destroy >(); + break; + case types::cause: + c.destroy(); + break; + case types::ri_cctrl_outcome: + c.destroy >(); + break; + default: + break; + } +} +void ri_cctrl_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ri_ccall_process_id: + c.init >(); + break; + case types::cause: + c.init(); + break; + case types::ri_cctrl_outcome: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + } +} +ri_cctrl_fail_ies_o::value_c::value_c(const ri_cctrl_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ri_ccall_process_id: + c.init(other.c.get >()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::ri_cctrl_outcome: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + } +} +ri_cctrl_fail_ies_o::value_c& ri_cctrl_fail_ies_o::value_c::operator=(const ri_cctrl_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ri_ccall_process_id: + c.set(other.c.get >()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::ri_cctrl_outcome: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ri_cctrl_fail_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ri_cctrl_fail_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +unbounded_octstring& ri_cctrl_fail_ies_o::value_c::ri_ccall_process_id() +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +cause_c& ri_cctrl_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +unbounded_octstring& ri_cctrl_fail_ies_o::value_c::ri_cctrl_outcome() +{ + assert_choice_type(types::ri_cctrl_outcome, type_, "Value"); + return c.get >(); +} +const ri_crequest_id_s& ri_cctrl_fail_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ri_cctrl_fail_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const unbounded_octstring& ri_cctrl_fail_ies_o::value_c::ri_ccall_process_id() const +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +const cause_c& ri_cctrl_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const unbounded_octstring& ri_cctrl_fail_ies_o::value_c::ri_cctrl_outcome() const +{ + assert_choice_type(types::ri_cctrl_outcome, type_, "Value"); + return c.get >(); +} +void ri_cctrl_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ri_ccall_process_id: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::ri_cctrl_outcome: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ri_cctrl_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cctrl_outcome: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cctrl_outcome: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ri_cctrl_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)", "OCTET STRING", "Cause", "OCTET STRING"}; + return convert_enum_idx(options, 5, value, "ri_cctrl_fail_ies_o::value_c::types"); +} +uint8_t ri_cctrl_fail_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ri_cctrl_fail_ies_o::value_c::types"); + return 0; +} + +// RICcontrolRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_cctrl_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 20, 22, 23, 21}; + return map_enum_number(options, 6, idx, "id"); +} +bool ri_cctrl_request_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 20, 22, 23, 21}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ri_cctrl_request_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 20: + return crit_e::reject; + case 22: + return crit_e::reject; + case 23: + return crit_e::reject; + case 21: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ri_cctrl_request_ies_o::value_c ri_cctrl_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 20: + ret.set(value_c::types::ri_ccall_process_id); + break; + case 22: + ret.set(value_c::types::ri_cctrl_hdr); + break; + case 23: + ret.set(value_c::types::ri_cctrl_msg); + break; + case 21: + ret.set(value_c::types::ri_cctrl_ack_request); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_cctrl_request_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 20: + return presence_e::optional; + case 22: + return presence_e::mandatory; + case 23: + return presence_e::mandatory; + case 21: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ri_cctrl_request_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ri_ccall_process_id: + c.destroy >(); + break; + case types::ri_cctrl_hdr: + c.destroy >(); + break; + case types::ri_cctrl_msg: + c.destroy >(); + break; + default: + break; + } +} +void ri_cctrl_request_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ri_ccall_process_id: + c.init >(); + break; + case types::ri_cctrl_hdr: + c.init >(); + break; + case types::ri_cctrl_msg: + c.init >(); + break; + case types::ri_cctrl_ack_request: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + } +} +ri_cctrl_request_ies_o::value_c::value_c(const ri_cctrl_request_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ri_ccall_process_id: + c.init(other.c.get >()); + break; + case types::ri_cctrl_hdr: + c.init(other.c.get >()); + break; + case types::ri_cctrl_msg: + c.init(other.c.get >()); + break; + case types::ri_cctrl_ack_request: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + } +} +ri_cctrl_request_ies_o::value_c& +ri_cctrl_request_ies_o::value_c::operator=(const ri_cctrl_request_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ri_ccall_process_id: + c.set(other.c.get >()); + break; + case types::ri_cctrl_hdr: + c.set(other.c.get >()); + break; + case types::ri_cctrl_msg: + c.set(other.c.get >()); + break; + case types::ri_cctrl_ack_request: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ri_cctrl_request_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ri_cctrl_request_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_ccall_process_id() +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_cctrl_hdr() +{ + assert_choice_type(types::ri_cctrl_hdr, type_, "Value"); + return c.get >(); +} +unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_cctrl_msg() +{ + assert_choice_type(types::ri_cctrl_msg, type_, "Value"); + return c.get >(); +} +ri_cctrl_ack_request_e& ri_cctrl_request_ies_o::value_c::ri_cctrl_ack_request() +{ + assert_choice_type(types::ri_cctrl_ack_request, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ri_cctrl_request_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ri_cctrl_request_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_ccall_process_id() const +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +const unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_cctrl_hdr() const +{ + assert_choice_type(types::ri_cctrl_hdr, type_, "Value"); + return c.get >(); +} +const unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_cctrl_msg() const +{ + assert_choice_type(types::ri_cctrl_msg, type_, "Value"); + return c.get >(); +} +const ri_cctrl_ack_request_e& ri_cctrl_request_ies_o::value_c::ri_cctrl_ack_request() const +{ + assert_choice_type(types::ri_cctrl_ack_request, type_, "Value"); + return c.get(); +} +void ri_cctrl_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ri_ccall_process_id: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_cctrl_hdr: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_cctrl_msg: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_cctrl_ack_request: + j.write_str("RICcontrolAckRequest", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ri_cctrl_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_cctrl_hdr: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_cctrl_msg: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_cctrl_ack_request: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_cctrl_hdr: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_cctrl_msg: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_cctrl_ack_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ri_cctrl_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "RICrequestID", "INTEGER (0..4095)", "OCTET STRING", "OCTET STRING", "OCTET STRING", "RICcontrolAckRequest"}; + return convert_enum_idx(options, 6, value, "ri_cctrl_request_ies_o::value_c::types"); +} +uint8_t ri_cctrl_request_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ri_cctrl_request_ies_o::value_c::types"); + return 0; +} + +// RICindication-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_cind_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 15, 27, 28, 25, 26, 20}; + return map_enum_number(options, 8, idx, "id"); +} +bool ri_cind_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 15, 27, 28, 25, 26, 20}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ri_cind_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 15: + return crit_e::reject; + case 27: + return crit_e::reject; + case 28: + return crit_e::reject; + case 25: + return crit_e::reject; + case 26: + return crit_e::reject; + case 20: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ri_cind_ies_o::value_c ri_cind_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 15: + ret.set(value_c::types::ri_caction_id); + break; + case 27: + ret.set(value_c::types::ri_cind_sn); + break; + case 28: + ret.set(value_c::types::ri_cind_type); + break; + case 25: + ret.set(value_c::types::ri_cind_hdr); + break; + case 26: + ret.set(value_c::types::ri_cind_msg); + break; + case 20: + ret.set(value_c::types::ri_ccall_process_id); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_cind_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 15: + return presence_e::mandatory; + case 27: + return presence_e::optional; + case 28: + return presence_e::mandatory; + case 25: + return presence_e::mandatory; + case 26: + return presence_e::mandatory; + case 20: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ri_cind_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ri_cind_hdr: + c.destroy >(); + break; + case types::ri_cind_msg: + c.destroy >(); + break; + case types::ri_ccall_process_id: + c.destroy >(); + break; + default: + break; + } +} +void ri_cind_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ri_caction_id: + break; + case types::ri_cind_sn: + break; + case types::ri_cind_type: + break; + case types::ri_cind_hdr: + c.init >(); + break; + case types::ri_cind_msg: + c.init >(); + break; + case types::ri_ccall_process_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + } +} +ri_cind_ies_o::value_c::value_c(const ri_cind_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ri_caction_id: + c.init(other.c.get()); + break; + case types::ri_cind_sn: + c.init(other.c.get()); + break; + case types::ri_cind_type: + c.init(other.c.get()); + break; + case types::ri_cind_hdr: + c.init(other.c.get >()); + break; + case types::ri_cind_msg: + c.init(other.c.get >()); + break; + case types::ri_ccall_process_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + } +} +ri_cind_ies_o::value_c& ri_cind_ies_o::value_c::operator=(const ri_cind_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ri_caction_id: + c.set(other.c.get()); + break; + case types::ri_cind_sn: + c.set(other.c.get()); + break; + case types::ri_cind_type: + c.set(other.c.get()); + break; + case types::ri_cind_hdr: + c.set(other.c.get >()); + break; + case types::ri_cind_msg: + c.set(other.c.get >()); + break; + case types::ri_ccall_process_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ri_cind_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ri_cind_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +uint16_t& ri_cind_ies_o::value_c::ri_caction_id() +{ + assert_choice_type(types::ri_caction_id, type_, "Value"); + return c.get(); +} +uint32_t& ri_cind_ies_o::value_c::ri_cind_sn() +{ + assert_choice_type(types::ri_cind_sn, type_, "Value"); + return c.get(); +} +ri_cind_type_e& ri_cind_ies_o::value_c::ri_cind_type() +{ + assert_choice_type(types::ri_cind_type, type_, "Value"); + return c.get(); +} +unbounded_octstring& ri_cind_ies_o::value_c::ri_cind_hdr() +{ + assert_choice_type(types::ri_cind_hdr, type_, "Value"); + return c.get >(); +} +unbounded_octstring& ri_cind_ies_o::value_c::ri_cind_msg() +{ + assert_choice_type(types::ri_cind_msg, type_, "Value"); + return c.get >(); +} +unbounded_octstring& ri_cind_ies_o::value_c::ri_ccall_process_id() +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +const ri_crequest_id_s& ri_cind_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ri_cind_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const uint16_t& ri_cind_ies_o::value_c::ri_caction_id() const +{ + assert_choice_type(types::ri_caction_id, type_, "Value"); + return c.get(); +} +const uint32_t& ri_cind_ies_o::value_c::ri_cind_sn() const +{ + assert_choice_type(types::ri_cind_sn, type_, "Value"); + return c.get(); +} +const ri_cind_type_e& ri_cind_ies_o::value_c::ri_cind_type() const +{ + assert_choice_type(types::ri_cind_type, type_, "Value"); + return c.get(); +} +const unbounded_octstring& ri_cind_ies_o::value_c::ri_cind_hdr() const +{ + assert_choice_type(types::ri_cind_hdr, type_, "Value"); + return c.get >(); +} +const unbounded_octstring& ri_cind_ies_o::value_c::ri_cind_msg() const +{ + assert_choice_type(types::ri_cind_msg, type_, "Value"); + return c.get >(); +} +const unbounded_octstring& ri_cind_ies_o::value_c::ri_ccall_process_id() const +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +void ri_cind_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ri_caction_id: + j.write_int("INTEGER (0..255)", c.get()); + break; + case types::ri_cind_sn: + j.write_int("INTEGER (0..65535)", c.get()); + break; + case types::ri_cind_type: + j.write_str("RICindicationType", c.get().to_string()); + break; + case types::ri_cind_hdr: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_cind_msg: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_ccall_process_id: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ri_cind_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_caction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + case types::ri_cind_sn: + HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + case types::ri_cind_type: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cind_hdr: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_cind_msg: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cind_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_caction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + case types::ri_cind_sn: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + case types::ri_cind_type: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cind_hdr: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_cind_msg: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ri_cind_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", + "INTEGER (0..4095)", + "INTEGER (0..255)", + "INTEGER (0..65535)", + "RICindicationType", + "OCTET STRING", + "OCTET STRING", + "OCTET STRING"}; + return convert_enum_idx(options, 8, value, "ri_cind_ies_o::value_c::types"); +} + +// RICserviceQuery-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricservice_query_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 9}; + return map_enum_number(options, 2, idx, "id"); +} +bool ricservice_query_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 9}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricservice_query_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 9: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricservice_query_ies_o::value_c ricservice_query_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 9: + ret.set(value_c::types::ra_nfunctions_accepted); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricservice_query_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 9: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricservice_query_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ra_nfunctions_accepted: + c.destroy(); + break; + default: + break; + } +} +void ricservice_query_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::ra_nfunctions_accepted: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + } +} +ricservice_query_ies_o::value_c::value_c(const ricservice_query_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + } +} +ricservice_query_ies_o::value_c& +ricservice_query_ies_o::value_c::operator=(const ricservice_query_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + } + + return *this; +} +uint16_t& ricservice_query_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +ra_nfunctions_id_list_l& ricservice_query_ies_o::value_c::ra_nfunctions_accepted() +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +const uint16_t& ricservice_query_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const ra_nfunctions_id_list_l& ricservice_query_ies_o::value_c::ra_nfunctions_accepted() const +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +void ricservice_query_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::ra_nfunctions_accepted: + j.start_array("RANfunctionsID-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricservice_query_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_query_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricservice_query_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "RANfunctionsID-List"}; + return convert_enum_idx(options, 2, value, "ricservice_query_ies_o::value_c::types"); +} +uint8_t ricservice_query_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "ricservice_query_ies_o::value_c::types"); +} + +// RICserviceUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricservice_upd_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 10, 12, 11}; + return map_enum_number(options, 4, idx, "id"); +} +bool ricservice_upd_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 10, 12, 11}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricservice_upd_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 10: + return crit_e::reject; + case 12: + return crit_e::reject; + case 11: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricservice_upd_ies_o::value_c ricservice_upd_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 10: + ret.set(value_c::types::ra_nfunctions_added); + break; + case 12: + ret.set(value_c::types::ra_nfunctions_modified); + break; + case 11: + ret.set(value_c::types::ra_nfunctions_deleted); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricservice_upd_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 10: + return presence_e::optional; + case 12: + return presence_e::optional; + case 11: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricservice_upd_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ra_nfunctions_added: + c.destroy(); + break; + case types::ra_nfunctions_modified: + c.destroy(); + break; + case types::ra_nfunctions_deleted: + c.destroy(); + break; + default: + break; + } +} +void ricservice_upd_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::ra_nfunctions_added: + c.init(); + break; + case types::ra_nfunctions_modified: + c.init(); + break; + case types::ra_nfunctions_deleted: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + } +} +ricservice_upd_ies_o::value_c::value_c(const ricservice_upd_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::ra_nfunctions_added: + c.init(other.c.get()); + break; + case types::ra_nfunctions_modified: + c.init(other.c.get()); + break; + case types::ra_nfunctions_deleted: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + } +} +ricservice_upd_ies_o::value_c& ricservice_upd_ies_o::value_c::operator=(const ricservice_upd_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::ra_nfunctions_added: + c.set(other.c.get()); + break; + case types::ra_nfunctions_modified: + c.set(other.c.get()); + break; + case types::ra_nfunctions_deleted: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + } + + return *this; +} +uint16_t& ricservice_upd_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +ra_nfunctions_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_added() +{ + assert_choice_type(types::ra_nfunctions_added, type_, "Value"); + return c.get(); +} +ra_nfunctions_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_modified() +{ + assert_choice_type(types::ra_nfunctions_modified, type_, "Value"); + return c.get(); +} +ra_nfunctions_id_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_deleted() +{ + assert_choice_type(types::ra_nfunctions_deleted, type_, "Value"); + return c.get(); +} +const uint16_t& ricservice_upd_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const ra_nfunctions_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_added() const +{ + assert_choice_type(types::ra_nfunctions_added, type_, "Value"); + return c.get(); +} +const ra_nfunctions_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_modified() const +{ + assert_choice_type(types::ra_nfunctions_modified, type_, "Value"); + return c.get(); +} +const ra_nfunctions_id_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_deleted() const +{ + assert_choice_type(types::ra_nfunctions_deleted, type_, "Value"); + return c.get(); +} +void ricservice_upd_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::ra_nfunctions_added: + j.start_array("RANfunctions-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::ra_nfunctions_modified: + j.start_array("RANfunctions-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::ra_nfunctions_deleted: + j.start_array("RANfunctionsID-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricservice_upd_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_added: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::ra_nfunctions_modified: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::ra_nfunctions_deleted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_added: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::ra_nfunctions_modified: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::ra_nfunctions_deleted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricservice_upd_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "INTEGER (0..255,...)", "RANfunctions-List", "RANfunctions-List", "RANfunctionsID-List"}; + return convert_enum_idx(options, 4, value, "ricservice_upd_ies_o::value_c::types"); +} +uint8_t ricservice_upd_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "ricservice_upd_ies_o::value_c::types"); +} + +// RICserviceUpdateAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricservice_upd_ack_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 9, 13}; + return map_enum_number(options, 3, idx, "id"); +} +bool ricservice_upd_ack_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 9, 13}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricservice_upd_ack_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 9: + return crit_e::reject; + case 13: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricservice_upd_ack_ies_o::value_c ricservice_upd_ack_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 9: + ret.set(value_c::types::ra_nfunctions_accepted); + break; + case 13: + ret.set(value_c::types::ra_nfunctions_rejected); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricservice_upd_ack_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 9: + return presence_e::optional; + case 13: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricservice_upd_ack_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ra_nfunctions_accepted: + c.destroy(); + break; + case types::ra_nfunctions_rejected: + c.destroy(); + break; + default: + break; + } +} +void ricservice_upd_ack_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::ra_nfunctions_accepted: + c.init(); + break; + case types::ra_nfunctions_rejected: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + } +} +ricservice_upd_ack_ies_o::value_c::value_c(const ricservice_upd_ack_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.init(other.c.get()); + break; + case types::ra_nfunctions_rejected: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + } +} +ricservice_upd_ack_ies_o::value_c& +ricservice_upd_ack_ies_o::value_c::operator=(const ricservice_upd_ack_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.set(other.c.get()); + break; + case types::ra_nfunctions_rejected: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + } + + return *this; +} +uint16_t& ricservice_upd_ack_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +ra_nfunctions_id_list_l& ricservice_upd_ack_ies_o::value_c::ra_nfunctions_accepted() +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +ra_nfunctions_idcause_list_l& ricservice_upd_ack_ies_o::value_c::ra_nfunctions_rejected() +{ + assert_choice_type(types::ra_nfunctions_rejected, type_, "Value"); + return c.get(); +} +const uint16_t& ricservice_upd_ack_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const ra_nfunctions_id_list_l& ricservice_upd_ack_ies_o::value_c::ra_nfunctions_accepted() const +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +const ra_nfunctions_idcause_list_l& ricservice_upd_ack_ies_o::value_c::ra_nfunctions_rejected() const +{ + assert_choice_type(types::ra_nfunctions_rejected, type_, "Value"); + return c.get(); +} +void ricservice_upd_ack_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::ra_nfunctions_accepted: + j.start_array("RANfunctionsID-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::ra_nfunctions_rejected: + j.start_array("RANfunctionsIDcause-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricservice_upd_ack_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::ra_nfunctions_rejected: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_ack_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::ra_nfunctions_rejected: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricservice_upd_ack_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "RANfunctionsID-List", "RANfunctionsIDcause-List"}; + return convert_enum_idx(options, 3, value, "ricservice_upd_ack_ies_o::value_c::types"); +} +uint8_t ricservice_upd_ack_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "ricservice_upd_ack_ies_o::value_c::types"); +} + +// RICserviceUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricservice_upd_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + return map_enum_number(options, 4, idx, "id"); +} +bool ricservice_upd_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricservice_upd_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::reject; + case 31: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricservice_upd_fail_ies_o::value_c ricservice_upd_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 31: + ret.set(value_c::types::time_to_wait); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricservice_upd_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 31: + return presence_e::optional; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricservice_upd_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void ricservice_upd_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::time_to_wait: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + } +} +ricservice_upd_fail_ies_o::value_c::value_c(const ricservice_upd_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::time_to_wait: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + } +} +ricservice_upd_fail_ies_o::value_c& +ricservice_upd_fail_ies_o::value_c::operator=(const ricservice_upd_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::time_to_wait: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + } + + return *this; +} +uint16_t& ricservice_upd_fail_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& ricservice_upd_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +time_to_wait_e& ricservice_upd_fail_ies_o::value_c::time_to_wait() +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& ricservice_upd_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& ricservice_upd_fail_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& ricservice_upd_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const time_to_wait_e& ricservice_upd_fail_ies_o::value_c::time_to_wait() const +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& ricservice_upd_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void ricservice_upd_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::time_to_wait: + j.write_str("TimeToWait", c.get().to_string()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricservice_upd_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricservice_upd_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "Cause", "TimeToWait", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 4, value, "ricservice_upd_fail_ies_o::value_c::types"); +} +uint8_t ricservice_upd_fail_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "ricservice_upd_fail_ies_o::value_c::types"); +} + +// RICsubscriptionDeleteFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_delete_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 1, 2}; + return map_enum_number(options, 4, idx, "id"); +} +bool ricsubscription_delete_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 1, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_delete_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_delete_fail_ies_o::value_c ricsubscription_delete_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_delete_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_delete_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_delete_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::cause: + c.init(); + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + } +} +ricsubscription_delete_fail_ies_o::value_c::value_c(const ricsubscription_delete_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + } +} +ricsubscription_delete_fail_ies_o::value_c& +ricsubscription_delete_fail_ies_o::value_c::operator=(const ricsubscription_delete_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_delete_fail_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_delete_fail_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +cause_c& ricsubscription_delete_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& ricsubscription_delete_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_delete_fail_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_delete_fail_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const cause_c& ricsubscription_delete_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& ricsubscription_delete_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void ricsubscription_delete_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_delete_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_delete_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)", "Cause", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 4, value, "ricsubscription_delete_fail_ies_o::value_c::types"); +} +uint8_t ricsubscription_delete_fail_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_delete_fail_ies_o::value_c::types"); + return 0; +} + +// RICsubscriptionDeleteRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_delete_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5}; + return map_enum_number(options, 2, idx, "id"); +} +bool ricsubscription_delete_request_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_delete_request_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_delete_request_ies_o::value_c ricsubscription_delete_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_delete_request_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_delete_request_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_delete_request_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + } +} +ricsubscription_delete_request_ies_o::value_c::value_c(const ricsubscription_delete_request_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + } +} +ricsubscription_delete_request_ies_o::value_c& +ricsubscription_delete_request_ies_o::value_c::operator=(const ricsubscription_delete_request_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_delete_request_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_delete_request_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_delete_request_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_delete_request_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +void ricsubscription_delete_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_delete_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_delete_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)"}; + return convert_enum_idx(options, 2, value, "ricsubscription_delete_request_ies_o::value_c::types"); +} +uint8_t ricsubscription_delete_request_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_delete_request_ies_o::value_c::types"); + return 0; +} + +// RICsubscriptionDeleteRequired-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_delete_required_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {60}; + return map_enum_number(options, 1, idx, "id"); +} +bool ricsubscription_delete_required_ies_o::is_id_valid(const uint32_t& id) +{ + return 60 == id; +} +crit_e ricsubscription_delete_required_ies_o::get_crit(const uint32_t& id) +{ + if (id == 60) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ricsubscription_delete_required_ies_o::value_c ricsubscription_delete_required_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 60) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_delete_required_ies_o::get_presence(const uint32_t& id) +{ + if (id == 60) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_delete_required_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("RICsubscription-List-withCause"); + for (const auto& e1 : c) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} +SRSASN_CODE ricsubscription_delete_required_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(pack_dyn_seq_of(bref, c, 1, 1024, true)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_required_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(unpack_dyn_seq_of(c, bref, 1, 1024, true)); + return SRSASN_SUCCESS; +} + +const char* ricsubscription_delete_required_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICsubscription-List-withCause"}; + return convert_enum_idx(options, 1, value, "ricsubscription_delete_required_ies_o::value_c::types"); +} + +// RICsubscriptionDeleteResponse-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_delete_resp_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5}; + return map_enum_number(options, 2, idx, "id"); +} +bool ricsubscription_delete_resp_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_delete_resp_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_delete_resp_ies_o::value_c ricsubscription_delete_resp_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_delete_resp_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_delete_resp_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_delete_resp_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + } +} +ricsubscription_delete_resp_ies_o::value_c::value_c(const ricsubscription_delete_resp_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + } +} +ricsubscription_delete_resp_ies_o::value_c& +ricsubscription_delete_resp_ies_o::value_c::operator=(const ricsubscription_delete_resp_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_delete_resp_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_delete_resp_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_delete_resp_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_delete_resp_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +void ricsubscription_delete_resp_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_delete_resp_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_resp_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_delete_resp_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)"}; + return convert_enum_idx(options, 2, value, "ricsubscription_delete_resp_ies_o::value_c::types"); +} +uint8_t ricsubscription_delete_resp_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_delete_resp_ies_o::value_c::types"); + return 0; +} + +// RICsubscriptionFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 1, 2}; + return map_enum_number(options, 4, idx, "id"); +} +bool ricsubscription_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 1, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 1: + return crit_e::reject; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_fail_ies_o::value_c ricsubscription_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::cause: + c.init(); + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + } +} +ricsubscription_fail_ies_o::value_c::value_c(const ricsubscription_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + } +} +ricsubscription_fail_ies_o::value_c& +ricsubscription_fail_ies_o::value_c::operator=(const ricsubscription_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_fail_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_fail_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +cause_c& ricsubscription_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& ricsubscription_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_fail_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_fail_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const cause_c& ricsubscription_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& ricsubscription_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void ricsubscription_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)", "Cause", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 4, value, "ricsubscription_fail_ies_o::value_c::types"); +} +uint8_t ricsubscription_fail_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_fail_ies_o::value_c::types"); + return 0; +} + +// RICsubscriptionRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 30}; + return map_enum_number(options, 3, idx, "id"); +} +bool ricsubscription_request_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 30}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_request_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 30: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_request_ies_o::value_c ricsubscription_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 30: + ret.set(value_c::types::ricsubscription_details); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_request_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 30: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_request_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ricsubscription_details: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_request_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ricsubscription_details: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + } +} +ricsubscription_request_ies_o::value_c::value_c(const ricsubscription_request_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ricsubscription_details: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + } +} +ricsubscription_request_ies_o::value_c& +ricsubscription_request_ies_o::value_c::operator=(const ricsubscription_request_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ricsubscription_details: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_request_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_request_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +ricsubscription_details_s& ricsubscription_request_ies_o::value_c::ricsubscription_details() +{ + assert_choice_type(types::ricsubscription_details, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_request_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_request_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const ricsubscription_details_s& ricsubscription_request_ies_o::value_c::ricsubscription_details() const +{ + assert_choice_type(types::ricsubscription_details, type_, "Value"); + return c.get(); +} +void ricsubscription_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ricsubscription_details: + j.write_fieldname("RICsubscriptionDetails"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ricsubscription_details: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ricsubscription_details: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)", "RICsubscriptionDetails"}; + return convert_enum_idx(options, 3, value, "ricsubscription_request_ies_o::value_c::types"); +} +uint8_t ricsubscription_request_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_request_ies_o::value_c::types"); + return 0; +} + +// RICsubscriptionResponse-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_resp_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 17, 18}; + return map_enum_number(options, 4, idx, "id"); +} +bool ricsubscription_resp_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 17, 18}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_resp_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 17: + return crit_e::reject; + case 18: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_resp_ies_o::value_c ricsubscription_resp_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 17: + ret.set(value_c::types::ri_cactions_admitted); + break; + case 18: + ret.set(value_c::types::ri_cactions_not_admitted); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_resp_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 17: + return presence_e::mandatory; + case 18: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_resp_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ri_cactions_admitted: + c.destroy(); + break; + case types::ri_cactions_not_admitted: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_resp_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ri_cactions_admitted: + c.init(); + break; + case types::ri_cactions_not_admitted: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + } +} +ricsubscription_resp_ies_o::value_c::value_c(const ricsubscription_resp_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ri_cactions_admitted: + c.init(other.c.get()); + break; + case types::ri_cactions_not_admitted: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + } +} +ricsubscription_resp_ies_o::value_c& +ricsubscription_resp_ies_o::value_c::operator=(const ricsubscription_resp_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ri_cactions_admitted: + c.set(other.c.get()); + break; + case types::ri_cactions_not_admitted: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_resp_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_resp_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +ri_caction_admitted_list_l& ricsubscription_resp_ies_o::value_c::ri_cactions_admitted() +{ + assert_choice_type(types::ri_cactions_admitted, type_, "Value"); + return c.get(); +} +ri_caction_not_admitted_list_l& ricsubscription_resp_ies_o::value_c::ri_cactions_not_admitted() +{ + assert_choice_type(types::ri_cactions_not_admitted, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_resp_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_resp_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const ri_caction_admitted_list_l& ricsubscription_resp_ies_o::value_c::ri_cactions_admitted() const +{ + assert_choice_type(types::ri_cactions_admitted, type_, "Value"); + return c.get(); +} +const ri_caction_not_admitted_list_l& ricsubscription_resp_ies_o::value_c::ri_cactions_not_admitted() const +{ + assert_choice_type(types::ri_cactions_not_admitted, type_, "Value"); + return c.get(); +} +void ricsubscription_resp_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ri_cactions_admitted: + j.start_array("RICaction-Admitted-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::ri_cactions_not_admitted: + j.start_array("RICaction-NotAdmitted-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_resp_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_cactions_admitted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 16, true)); + break; + case types::ri_cactions_not_admitted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 0, 16, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_resp_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_cactions_admitted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 16, true)); + break; + case types::ri_cactions_not_admitted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 0, 16, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_resp_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "RICrequestID", "INTEGER (0..4095)", "RICaction-Admitted-List", "RICaction-NotAdmitted-List"}; + return convert_enum_idx(options, 4, value, "ricsubscription_resp_ies_o::value_c::types"); +} +uint8_t ricsubscription_resp_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_resp_ies_o::value_c::types"); + return 0; +} + +// ResetRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t reset_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1}; + return map_enum_number(options, 2, idx, "id"); +} +bool reset_request_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e reset_request_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +reset_request_ies_o::value_c reset_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e reset_request_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void reset_request_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + default: + break; + } +} +void reset_request_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + } +} +reset_request_ies_o::value_c::value_c(const reset_request_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + } +} +reset_request_ies_o::value_c& reset_request_ies_o::value_c::operator=(const reset_request_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + } + + return *this; +} +uint16_t& reset_request_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& reset_request_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const uint16_t& reset_request_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& reset_request_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +void reset_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE reset_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE reset_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* reset_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "Cause"}; + return convert_enum_idx(options, 2, value, "reset_request_ies_o::value_c::types"); +} +uint8_t reset_request_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "reset_request_ies_o::value_c::types"); +} + +// ResetResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t reset_resp_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 2}; + return map_enum_number(options, 2, idx, "id"); +} +bool reset_resp_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e reset_resp_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +reset_resp_ies_o::value_c reset_resp_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e reset_resp_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void reset_resp_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void reset_resp_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + } +} +reset_resp_ies_o::value_c::value_c(const reset_resp_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + } +} +reset_resp_ies_o::value_c& reset_resp_ies_o::value_c::operator=(const reset_resp_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + } + + return *this; +} +uint16_t& reset_resp_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& reset_resp_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& reset_resp_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& reset_resp_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void reset_resp_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE reset_resp_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE reset_resp_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* reset_resp_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 2, value, "reset_resp_ies_o::value_c::types"); +} +uint8_t reset_resp_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "reset_resp_ies_o::value_c::types"); +} + +template struct asn1::protocol_ie_field_s; + +e2_removal_fail_ies_container::e2_removal_fail_ies_container() : + transaction_id(49, crit_e::reject), cause(1, crit_e::ignore), crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE e2_removal_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_removal_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2_removal_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2_removal_resp_ies_container::e2_removal_resp_ies_container() : + transaction_id(49, crit_e::reject), crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE e2_removal_resp_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_removal_resp_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2_removal_resp_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2conn_upd_ies_container::e2conn_upd_ies_container() : + transaction_id(49, crit_e::reject), + e2conn_upd_add(44, crit_e::reject), + e2conn_upd_rem(46, crit_e::reject), + e2conn_upd_modify(45, crit_e::reject) +{ +} +SRSASN_CODE e2conn_upd_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += e2conn_upd_add_present ? 1 : 0; + nof_ies += e2conn_upd_rem_present ? 1 : 0; + nof_ies += e2conn_upd_modify_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (e2conn_upd_add_present) { + HANDLE_CODE(e2conn_upd_add.pack(bref)); + } + if (e2conn_upd_rem_present) { + HANDLE_CODE(e2conn_upd_rem.pack(bref)); + } + if (e2conn_upd_modify_present) { + HANDLE_CODE(e2conn_upd_modify.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 44: { + e2conn_upd_add_present = true; + e2conn_upd_add.id = id; + HANDLE_CODE(e2conn_upd_add.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2conn_upd_add.value.unpack(bref)); + break; + } + case 46: { + e2conn_upd_rem_present = true; + e2conn_upd_rem.id = id; + HANDLE_CODE(e2conn_upd_rem.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2conn_upd_rem.value.unpack(bref)); + break; + } + case 45: { + e2conn_upd_modify_present = true; + e2conn_upd_modify.id = id; + HANDLE_CODE(e2conn_upd_modify.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2conn_upd_modify.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2conn_upd_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (e2conn_upd_add_present) { + j.write_fieldname(""); + e2conn_upd_add.to_json(j); + } + if (e2conn_upd_rem_present) { + j.write_fieldname(""); + e2conn_upd_rem.to_json(j); + } + if (e2conn_upd_modify_present) { + j.write_fieldname(""); + e2conn_upd_modify.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2conn_upd_ack_ies_container::e2conn_upd_ack_ies_container() : + transaction_id(49, crit_e::reject), e2conn_setup(39, crit_e::reject), e2conn_setup_failed(40, crit_e::reject) +{ +} +SRSASN_CODE e2conn_upd_ack_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += e2conn_setup_present ? 1 : 0; + nof_ies += e2conn_setup_failed_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (e2conn_setup_present) { + HANDLE_CODE(e2conn_setup.pack(bref)); + } + if (e2conn_setup_failed_present) { + HANDLE_CODE(e2conn_setup_failed.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_ack_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 39: { + e2conn_setup_present = true; + e2conn_setup.id = id; + HANDLE_CODE(e2conn_setup.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2conn_setup.value.unpack(bref)); + break; + } + case 40: { + e2conn_setup_failed_present = true; + e2conn_setup_failed.id = id; + HANDLE_CODE(e2conn_setup_failed.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2conn_setup_failed.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2conn_upd_ack_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (e2conn_setup_present) { + j.write_fieldname(""); + e2conn_setup.to_json(j); + } + if (e2conn_setup_failed_present) { + j.write_fieldname(""); + e2conn_setup_failed.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2conn_upd_fail_ies_container::e2conn_upd_fail_ies_container() : + transaction_id(49, crit_e::reject), + cause(1, crit_e::reject), + time_to_wait(31, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE e2conn_upd_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += cause_present ? 1 : 0; + nof_ies += time_to_wait_present ? 1 : 0; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (cause_present) { + HANDLE_CODE(cause.pack(bref)); + } + if (time_to_wait_present) { + HANDLE_CODE(time_to_wait.pack(bref)); + } + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + cause_present = true; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 31: { + time_to_wait_present = true; + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2conn_upd_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (cause_present) { + j.write_fieldname(""); + cause.to_json(j); + } + if (time_to_wait_present) { + j.write_fieldname(""); + time_to_wait.to_json(j); + } + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2node_cfg_upd_ies_container::e2node_cfg_upd_ies_container() : + transaction_id(49, crit_e::reject), + global_e2node_id(3, crit_e::reject), + e2node_component_cfg_addition(50, crit_e::reject), + e2node_component_cfg_upd(33, crit_e::reject), + e2node_component_cfg_removal(54, crit_e::reject), + e2node_tn_lassoc_removal(58, crit_e::reject) +{ +} +SRSASN_CODE e2node_cfg_upd_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += global_e2node_id_present ? 1 : 0; + nof_ies += e2node_component_cfg_addition_present ? 1 : 0; + nof_ies += e2node_component_cfg_upd_present ? 1 : 0; + nof_ies += e2node_component_cfg_removal_present ? 1 : 0; + nof_ies += e2node_tn_lassoc_removal_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (global_e2node_id_present) { + HANDLE_CODE(global_e2node_id.pack(bref)); + } + if (e2node_component_cfg_addition_present) { + HANDLE_CODE(e2node_component_cfg_addition.pack(bref)); + } + if (e2node_component_cfg_upd_present) { + HANDLE_CODE(e2node_component_cfg_upd.pack(bref)); + } + if (e2node_component_cfg_removal_present) { + HANDLE_CODE(e2node_component_cfg_removal.pack(bref)); + } + if (e2node_tn_lassoc_removal_present) { + HANDLE_CODE(e2node_tn_lassoc_removal.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 3: { + global_e2node_id_present = true; + global_e2node_id.id = id; + HANDLE_CODE(global_e2node_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_e2node_id.value.unpack(bref)); + break; + } + case 50: { + e2node_component_cfg_addition_present = true; + e2node_component_cfg_addition.id = id; + HANDLE_CODE(e2node_component_cfg_addition.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_addition.value.unpack(bref)); + break; + } + case 33: { + e2node_component_cfg_upd_present = true; + e2node_component_cfg_upd.id = id; + HANDLE_CODE(e2node_component_cfg_upd.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_upd.value.unpack(bref)); + break; + } + case 54: { + e2node_component_cfg_removal_present = true; + e2node_component_cfg_removal.id = id; + HANDLE_CODE(e2node_component_cfg_removal.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_removal.value.unpack(bref)); + break; + } + case 58: { + e2node_tn_lassoc_removal_present = true; + e2node_tn_lassoc_removal.id = id; + HANDLE_CODE(e2node_tn_lassoc_removal.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_tn_lassoc_removal.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2node_cfg_upd_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (global_e2node_id_present) { + j.write_fieldname(""); + global_e2node_id.to_json(j); + } + if (e2node_component_cfg_addition_present) { + j.write_fieldname(""); + e2node_component_cfg_addition.to_json(j); + } + if (e2node_component_cfg_upd_present) { + j.write_fieldname(""); + e2node_component_cfg_upd.to_json(j); + } + if (e2node_component_cfg_removal_present) { + j.write_fieldname(""); + e2node_component_cfg_removal.to_json(j); + } + if (e2node_tn_lassoc_removal_present) { + j.write_fieldname(""); + e2node_tn_lassoc_removal.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2node_cfg_upd_ack_ies_container::e2node_cfg_upd_ack_ies_container() : + transaction_id(49, crit_e::reject), + e2node_component_cfg_addition_ack(52, crit_e::reject), + e2node_component_cfg_upd_ack(35, crit_e::reject), + e2node_component_cfg_removal_ack(56, crit_e::reject) +{ +} +SRSASN_CODE e2node_cfg_upd_ack_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += e2node_component_cfg_addition_ack_present ? 1 : 0; + nof_ies += e2node_component_cfg_upd_ack_present ? 1 : 0; + nof_ies += e2node_component_cfg_removal_ack_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (e2node_component_cfg_addition_ack_present) { + HANDLE_CODE(e2node_component_cfg_addition_ack.pack(bref)); + } + if (e2node_component_cfg_upd_ack_present) { + HANDLE_CODE(e2node_component_cfg_upd_ack.pack(bref)); + } + if (e2node_component_cfg_removal_ack_present) { + HANDLE_CODE(e2node_component_cfg_removal_ack.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_ack_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 52: { + e2node_component_cfg_addition_ack_present = true; + e2node_component_cfg_addition_ack.id = id; + HANDLE_CODE(e2node_component_cfg_addition_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_addition_ack.value.unpack(bref)); + break; + } + case 35: { + e2node_component_cfg_upd_ack_present = true; + e2node_component_cfg_upd_ack.id = id; + HANDLE_CODE(e2node_component_cfg_upd_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_upd_ack.value.unpack(bref)); + break; + } + case 56: { + e2node_component_cfg_removal_ack_present = true; + e2node_component_cfg_removal_ack.id = id; + HANDLE_CODE(e2node_component_cfg_removal_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_removal_ack.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2node_cfg_upd_ack_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (e2node_component_cfg_addition_ack_present) { + j.write_fieldname(""); + e2node_component_cfg_addition_ack.to_json(j); + } + if (e2node_component_cfg_upd_ack_present) { + j.write_fieldname(""); + e2node_component_cfg_upd_ack.to_json(j); + } + if (e2node_component_cfg_removal_ack_present) { + j.write_fieldname(""); + e2node_component_cfg_removal_ack.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2node_cfg_upd_fail_ies_container::e2node_cfg_upd_fail_ies_container() : + transaction_id(49, crit_e::reject), + cause(1, crit_e::ignore), + time_to_wait(31, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE e2node_cfg_upd_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + nof_ies += time_to_wait_present ? 1 : 0; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (time_to_wait_present) { + HANDLE_CODE(time_to_wait.pack(bref)); + } + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 31: { + time_to_wait_present = true; + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2node_cfg_upd_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (time_to_wait_present) { + j.write_fieldname(""); + time_to_wait.to_json(j); + } + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2setup_fail_ies_container::e2setup_fail_ies_container() : + transaction_id(49, crit_e::reject), + cause(1, crit_e::ignore), + time_to_wait(31, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore), + tn_linfo(48, crit_e::ignore) +{ +} +SRSASN_CODE e2setup_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + nof_ies += time_to_wait_present ? 1 : 0; + nof_ies += crit_diagnostics_present ? 1 : 0; + nof_ies += tn_linfo_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (time_to_wait_present) { + HANDLE_CODE(time_to_wait.pack(bref)); + } + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + if (tn_linfo_present) { + HANDLE_CODE(tn_linfo.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 31: { + time_to_wait_present = true; + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + case 48: { + tn_linfo_present = true; + tn_linfo.id = id; + HANDLE_CODE(tn_linfo.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tn_linfo.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2setup_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (time_to_wait_present) { + j.write_fieldname(""); + time_to_wait.to_json(j); + } + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + if (tn_linfo_present) { + j.write_fieldname(""); + tn_linfo.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2setup_request_ies_container::e2setup_request_ies_container() : + transaction_id(49, crit_e::reject), + global_e2node_id(3, crit_e::reject), + ra_nfunctions_added(10, crit_e::reject), + e2node_component_cfg_addition(50, crit_e::reject) +{ +} +SRSASN_CODE e2setup_request_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 4; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(global_e2node_id.pack(bref)); + HANDLE_CODE(ra_nfunctions_added.pack(bref)); + HANDLE_CODE(e2node_component_cfg_addition.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_request_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 4; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 3: { + nof_mandatory_ies--; + global_e2node_id.id = id; + HANDLE_CODE(global_e2node_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_e2node_id.value.unpack(bref)); + break; + } + case 10: { + nof_mandatory_ies--; + ra_nfunctions_added.id = id; + HANDLE_CODE(ra_nfunctions_added.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_added.value.unpack(bref)); + break; + } + case 50: { + nof_mandatory_ies--; + e2node_component_cfg_addition.id = id; + HANDLE_CODE(e2node_component_cfg_addition.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_addition.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2setup_request_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + global_e2node_id.to_json(j); + j.write_fieldname(""); + ra_nfunctions_added.to_json(j); + j.write_fieldname(""); + e2node_component_cfg_addition.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2setup_resp_ies_container::e2setup_resp_ies_container() : + transaction_id(49, crit_e::reject), + global_ric_id(4, crit_e::reject), + ra_nfunctions_accepted(9, crit_e::reject), + ra_nfunctions_rejected(13, crit_e::reject), + e2node_component_cfg_addition_ack(52, crit_e::reject) +{ +} +SRSASN_CODE e2setup_resp_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + nof_ies += ra_nfunctions_accepted_present ? 1 : 0; + nof_ies += ra_nfunctions_rejected_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(global_ric_id.pack(bref)); + if (ra_nfunctions_accepted_present) { + HANDLE_CODE(ra_nfunctions_accepted.pack(bref)); + } + if (ra_nfunctions_rejected_present) { + HANDLE_CODE(ra_nfunctions_rejected.pack(bref)); + } + HANDLE_CODE(e2node_component_cfg_addition_ack.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_resp_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 4: { + nof_mandatory_ies--; + global_ric_id.id = id; + HANDLE_CODE(global_ric_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_ric_id.value.unpack(bref)); + break; + } + case 9: { + ra_nfunctions_accepted_present = true; + ra_nfunctions_accepted.id = id; + HANDLE_CODE(ra_nfunctions_accepted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_accepted.value.unpack(bref)); + break; + } + case 13: { + ra_nfunctions_rejected_present = true; + ra_nfunctions_rejected.id = id; + HANDLE_CODE(ra_nfunctions_rejected.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_rejected.value.unpack(bref)); + break; + } + case 52: { + nof_mandatory_ies--; + e2node_component_cfg_addition_ack.id = id; + HANDLE_CODE(e2node_component_cfg_addition_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_addition_ack.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2setup_resp_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + global_ric_id.to_json(j); + if (ra_nfunctions_accepted_present) { + j.write_fieldname(""); + ra_nfunctions_accepted.to_json(j); + } + if (ra_nfunctions_rejected_present) { + j.write_fieldname(""); + ra_nfunctions_rejected.to_json(j); + } + j.write_fieldname(""); + e2node_component_cfg_addition_ack.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +error_ind_ies_container::error_ind_ies_container() : + transaction_id(49, crit_e::reject), + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + cause(1, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE error_ind_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 0; + nof_ies += transaction_id_present ? 1 : 0; + nof_ies += ri_crequest_id_present ? 1 : 0; + nof_ies += ra_nfunction_id_present ? 1 : 0; + nof_ies += cause_present ? 1 : 0; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + if (transaction_id_present) { + HANDLE_CODE(transaction_id.pack(bref)); + } + if (ri_crequest_id_present) { + HANDLE_CODE(ri_crequest_id.pack(bref)); + } + if (ra_nfunction_id_present) { + HANDLE_CODE(ra_nfunction_id.pack(bref)); + } + if (cause_present) { + HANDLE_CODE(cause.pack(bref)); + } + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE error_ind_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + transaction_id_present = true; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 29: { + ri_crequest_id_present = true; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + ra_nfunction_id_present = true; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 1: { + cause_present = true; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + + return SRSASN_SUCCESS; +} +void error_ind_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + if (transaction_id_present) { + j.write_fieldname(""); + transaction_id.to_json(j); + } + if (ri_crequest_id_present) { + j.write_fieldname(""); + ri_crequest_id.to_json(j); + } + if (ra_nfunction_id_present) { + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + } + if (cause_present) { + j.write_fieldname(""); + cause.to_json(j); + } + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ri_cctrl_ack_ies_container::ri_cctrl_ack_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + ri_ccall_process_id(20, crit_e::reject), + ri_cctrl_outcome(32, crit_e::reject) +{ +} +SRSASN_CODE ri_cctrl_ack_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + nof_ies += ri_ccall_process_id_present ? 1 : 0; + nof_ies += ri_cctrl_outcome_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + if (ri_ccall_process_id_present) { + HANDLE_CODE(ri_ccall_process_id.pack(bref)); + } + if (ri_cctrl_outcome_present) { + HANDLE_CODE(ri_cctrl_outcome.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_ack_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 20: { + ri_ccall_process_id_present = true; + ri_ccall_process_id.id = id; + HANDLE_CODE(ri_ccall_process_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_ccall_process_id.value.unpack(bref)); + break; + } + case 32: { + ri_cctrl_outcome_present = true; + ri_cctrl_outcome.id = id; + HANDLE_CODE(ri_cctrl_outcome.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cctrl_outcome.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ri_cctrl_ack_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + if (ri_ccall_process_id_present) { + j.write_fieldname(""); + ri_ccall_process_id.to_json(j); + } + if (ri_cctrl_outcome_present) { + j.write_fieldname(""); + ri_cctrl_outcome.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ri_cctrl_fail_ies_container::ri_cctrl_fail_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + ri_ccall_process_id(20, crit_e::reject), + cause(1, crit_e::ignore), + ri_cctrl_outcome(32, crit_e::reject) +{ +} +SRSASN_CODE ri_cctrl_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + nof_ies += ri_ccall_process_id_present ? 1 : 0; + nof_ies += ri_cctrl_outcome_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + if (ri_ccall_process_id_present) { + HANDLE_CODE(ri_ccall_process_id.pack(bref)); + } + HANDLE_CODE(cause.pack(bref)); + if (ri_cctrl_outcome_present) { + HANDLE_CODE(ri_cctrl_outcome.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 20: { + ri_ccall_process_id_present = true; + ri_ccall_process_id.id = id; + HANDLE_CODE(ri_ccall_process_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_ccall_process_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 32: { + ri_cctrl_outcome_present = true; + ri_cctrl_outcome.id = id; + HANDLE_CODE(ri_cctrl_outcome.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cctrl_outcome.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ri_cctrl_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + if (ri_ccall_process_id_present) { + j.write_fieldname(""); + ri_ccall_process_id.to_json(j); + } + j.write_fieldname(""); + cause.to_json(j); + if (ri_cctrl_outcome_present) { + j.write_fieldname(""); + ri_cctrl_outcome.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ri_cctrl_request_ies_container::ri_cctrl_request_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + ri_ccall_process_id(20, crit_e::reject), + ri_cctrl_hdr(22, crit_e::reject), + ri_cctrl_msg(23, crit_e::reject), + ri_cctrl_ack_request(21, crit_e::reject) +{ +} +SRSASN_CODE ri_cctrl_request_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 4; + nof_ies += ri_ccall_process_id_present ? 1 : 0; + nof_ies += ri_cctrl_ack_request_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + if (ri_ccall_process_id_present) { + HANDLE_CODE(ri_ccall_process_id.pack(bref)); + } + HANDLE_CODE(ri_cctrl_hdr.pack(bref)); + HANDLE_CODE(ri_cctrl_msg.pack(bref)); + if (ri_cctrl_ack_request_present) { + HANDLE_CODE(ri_cctrl_ack_request.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_request_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 4; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 20: { + ri_ccall_process_id_present = true; + ri_ccall_process_id.id = id; + HANDLE_CODE(ri_ccall_process_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_ccall_process_id.value.unpack(bref)); + break; + } + case 22: { + nof_mandatory_ies--; + ri_cctrl_hdr.id = id; + HANDLE_CODE(ri_cctrl_hdr.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cctrl_hdr.value.unpack(bref)); + break; + } + case 23: { + nof_mandatory_ies--; + ri_cctrl_msg.id = id; + HANDLE_CODE(ri_cctrl_msg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cctrl_msg.value.unpack(bref)); + break; + } + case 21: { + ri_cctrl_ack_request_present = true; + ri_cctrl_ack_request.id = id; + HANDLE_CODE(ri_cctrl_ack_request.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cctrl_ack_request.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ri_cctrl_request_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + if (ri_ccall_process_id_present) { + j.write_fieldname(""); + ri_ccall_process_id.to_json(j); + } + j.write_fieldname(""); + ri_cctrl_hdr.to_json(j); + j.write_fieldname(""); + ri_cctrl_msg.to_json(j); + if (ri_cctrl_ack_request_present) { + j.write_fieldname(""); + ri_cctrl_ack_request.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ri_cind_ies_container::ri_cind_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + ri_caction_id(15, crit_e::reject), + ri_cind_sn(27, crit_e::reject), + ri_cind_type(28, crit_e::reject), + ri_cind_hdr(25, crit_e::reject), + ri_cind_msg(26, crit_e::reject), + ri_ccall_process_id(20, crit_e::reject) +{ +} +SRSASN_CODE ri_cind_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 6; + nof_ies += ri_cind_sn_present ? 1 : 0; + nof_ies += ri_ccall_process_id_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + HANDLE_CODE(ri_caction_id.pack(bref)); + if (ri_cind_sn_present) { + HANDLE_CODE(ri_cind_sn.pack(bref)); + } + HANDLE_CODE(ri_cind_type.pack(bref)); + HANDLE_CODE(ri_cind_hdr.pack(bref)); + HANDLE_CODE(ri_cind_msg.pack(bref)); + if (ri_ccall_process_id_present) { + HANDLE_CODE(ri_ccall_process_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cind_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 6; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 15: { + nof_mandatory_ies--; + ri_caction_id.id = id; + HANDLE_CODE(ri_caction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_caction_id.value.unpack(bref)); + break; + } + case 27: { + ri_cind_sn_present = true; + ri_cind_sn.id = id; + HANDLE_CODE(ri_cind_sn.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cind_sn.value.unpack(bref)); + break; + } + case 28: { + nof_mandatory_ies--; + ri_cind_type.id = id; + HANDLE_CODE(ri_cind_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cind_type.value.unpack(bref)); + break; + } + case 25: { + nof_mandatory_ies--; + ri_cind_hdr.id = id; + HANDLE_CODE(ri_cind_hdr.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cind_hdr.value.unpack(bref)); + break; + } + case 26: { + nof_mandatory_ies--; + ri_cind_msg.id = id; + HANDLE_CODE(ri_cind_msg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cind_msg.value.unpack(bref)); + break; + } + case 20: { + ri_ccall_process_id_present = true; + ri_ccall_process_id.id = id; + HANDLE_CODE(ri_ccall_process_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_ccall_process_id.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ri_cind_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.write_fieldname(""); + ri_caction_id.to_json(j); + if (ri_cind_sn_present) { + j.write_fieldname(""); + ri_cind_sn.to_json(j); + } + j.write_fieldname(""); + ri_cind_type.to_json(j); + j.write_fieldname(""); + ri_cind_hdr.to_json(j); + j.write_fieldname(""); + ri_cind_msg.to_json(j); + if (ri_ccall_process_id_present) { + j.write_fieldname(""); + ri_ccall_process_id.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricservice_query_ies_container::ricservice_query_ies_container() : + transaction_id(49, crit_e::reject), ra_nfunctions_accepted(9, crit_e::reject) +{ +} +SRSASN_CODE ricservice_query_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += ra_nfunctions_accepted_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (ra_nfunctions_accepted_present) { + HANDLE_CODE(ra_nfunctions_accepted.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_query_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 9: { + ra_nfunctions_accepted_present = true; + ra_nfunctions_accepted.id = id; + HANDLE_CODE(ra_nfunctions_accepted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_accepted.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricservice_query_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (ra_nfunctions_accepted_present) { + j.write_fieldname(""); + ra_nfunctions_accepted.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricservice_upd_ies_container::ricservice_upd_ies_container() : + transaction_id(49, crit_e::reject), + ra_nfunctions_added(10, crit_e::reject), + ra_nfunctions_modified(12, crit_e::reject), + ra_nfunctions_deleted(11, crit_e::reject) +{ +} +SRSASN_CODE ricservice_upd_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += ra_nfunctions_added_present ? 1 : 0; + nof_ies += ra_nfunctions_modified_present ? 1 : 0; + nof_ies += ra_nfunctions_deleted_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (ra_nfunctions_added_present) { + HANDLE_CODE(ra_nfunctions_added.pack(bref)); + } + if (ra_nfunctions_modified_present) { + HANDLE_CODE(ra_nfunctions_modified.pack(bref)); + } + if (ra_nfunctions_deleted_present) { + HANDLE_CODE(ra_nfunctions_deleted.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 10: { + ra_nfunctions_added_present = true; + ra_nfunctions_added.id = id; + HANDLE_CODE(ra_nfunctions_added.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_added.value.unpack(bref)); + break; + } + case 12: { + ra_nfunctions_modified_present = true; + ra_nfunctions_modified.id = id; + HANDLE_CODE(ra_nfunctions_modified.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_modified.value.unpack(bref)); + break; + } + case 11: { + ra_nfunctions_deleted_present = true; + ra_nfunctions_deleted.id = id; + HANDLE_CODE(ra_nfunctions_deleted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_deleted.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricservice_upd_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (ra_nfunctions_added_present) { + j.write_fieldname(""); + ra_nfunctions_added.to_json(j); + } + if (ra_nfunctions_modified_present) { + j.write_fieldname(""); + ra_nfunctions_modified.to_json(j); + } + if (ra_nfunctions_deleted_present) { + j.write_fieldname(""); + ra_nfunctions_deleted.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricservice_upd_ack_ies_container::ricservice_upd_ack_ies_container() : + transaction_id(49, crit_e::reject), + ra_nfunctions_accepted(9, crit_e::reject), + ra_nfunctions_rejected(13, crit_e::reject) +{ +} +SRSASN_CODE ricservice_upd_ack_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += ra_nfunctions_accepted_present ? 1 : 0; + nof_ies += ra_nfunctions_rejected_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (ra_nfunctions_accepted_present) { + HANDLE_CODE(ra_nfunctions_accepted.pack(bref)); + } + if (ra_nfunctions_rejected_present) { + HANDLE_CODE(ra_nfunctions_rejected.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_ack_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 9: { + ra_nfunctions_accepted_present = true; + ra_nfunctions_accepted.id = id; + HANDLE_CODE(ra_nfunctions_accepted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_accepted.value.unpack(bref)); + break; + } + case 13: { + ra_nfunctions_rejected_present = true; + ra_nfunctions_rejected.id = id; + HANDLE_CODE(ra_nfunctions_rejected.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_rejected.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricservice_upd_ack_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (ra_nfunctions_accepted_present) { + j.write_fieldname(""); + ra_nfunctions_accepted.to_json(j); + } + if (ra_nfunctions_rejected_present) { + j.write_fieldname(""); + ra_nfunctions_rejected.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricservice_upd_fail_ies_container::ricservice_upd_fail_ies_container() : + transaction_id(49, crit_e::reject), + cause(1, crit_e::reject), + time_to_wait(31, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE ricservice_upd_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + nof_ies += time_to_wait_present ? 1 : 0; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (time_to_wait_present) { + HANDLE_CODE(time_to_wait.pack(bref)); + } + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 31: { + time_to_wait_present = true; + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricservice_upd_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (time_to_wait_present) { + j.write_fieldname(""); + time_to_wait.to_json(j); + } + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_delete_fail_ies_container::ricsubscription_delete_fail_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + cause(1, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE ricsubscription_delete_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_delete_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_delete_request_ies_container::ricsubscription_delete_request_ies_container() : + ri_crequest_id(29, crit_e::reject), ra_nfunction_id(5, crit_e::reject) +{ +} +SRSASN_CODE ricsubscription_delete_request_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_request_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_delete_request_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_delete_resp_ies_container::ricsubscription_delete_resp_ies_container() : + ri_crequest_id(29, crit_e::reject), ra_nfunction_id(5, crit_e::reject) +{ +} +SRSASN_CODE ricsubscription_delete_resp_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_resp_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_delete_resp_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_fail_ies_container::ricsubscription_fail_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + cause(1, crit_e::reject), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE ricsubscription_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_request_ies_container::ricsubscription_request_ies_container() : + ri_crequest_id(29, crit_e::reject), ra_nfunction_id(5, crit_e::reject), ricsubscription_details(30, crit_e::reject) +{ +} +SRSASN_CODE ricsubscription_request_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + HANDLE_CODE(ricsubscription_details.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_request_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 30: { + nof_mandatory_ies--; + ricsubscription_details.id = id; + HANDLE_CODE(ricsubscription_details.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ricsubscription_details.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_request_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.write_fieldname(""); + ricsubscription_details.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_resp_ies_container::ricsubscription_resp_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + ri_cactions_admitted(17, crit_e::reject), + ri_cactions_not_admitted(18, crit_e::reject) +{ +} +SRSASN_CODE ricsubscription_resp_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + nof_ies += ri_cactions_not_admitted_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + HANDLE_CODE(ri_cactions_admitted.pack(bref)); + if (ri_cactions_not_admitted_present) { + HANDLE_CODE(ri_cactions_not_admitted.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_resp_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 17: { + nof_mandatory_ies--; + ri_cactions_admitted.id = id; + HANDLE_CODE(ri_cactions_admitted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cactions_admitted.value.unpack(bref)); + break; + } + case 18: { + ri_cactions_not_admitted_present = true; + ri_cactions_not_admitted.id = id; + HANDLE_CODE(ri_cactions_not_admitted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cactions_not_admitted.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_resp_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.write_fieldname(""); + ri_cactions_admitted.to_json(j); + if (ri_cactions_not_admitted_present) { + j.write_fieldname(""); + ri_cactions_not_admitted.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +reset_request_ies_container::reset_request_ies_container() : + transaction_id(49, crit_e::reject), cause(1, crit_e::ignore) +{ +} +SRSASN_CODE reset_request_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE reset_request_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void reset_request_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +reset_resp_ies_container::reset_resp_ies_container() : + transaction_id(49, crit_e::reject), crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE reset_resp_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE reset_resp_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void reset_resp_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +// E2AP-ELEMENTARY-PROCEDURES ::= OBJECT SET OF E2AP-ELEMENTARY-PROCEDURE +uint16_t e2_ap_elem_procs_o::idx_to_proc_code(uint32_t idx) +{ + static const uint16_t options[] = {8, 9, 7, 4, 1, 10, 11, 3, 13, 5, 6, 2, 12}; + return map_enum_number(options, 13, idx, "proc_code"); +} +bool e2_ap_elem_procs_o::is_proc_code_valid(const uint16_t& proc_code) +{ + static const uint16_t options[] = {8, 9, 7, 4, 1, 10, 11, 3, 13, 5, 6, 2, 12}; + for (const auto& o : options) { + if (o == proc_code) { + return true; + } + } + return false; +} +e2_ap_elem_procs_o::init_msg_c e2_ap_elem_procs_o::get_init_msg(const uint16_t& proc_code) +{ + init_msg_c ret{}; + switch (proc_code) { + case 8: + ret.set(init_msg_c::types::ricsubscription_request); + break; + case 9: + ret.set(init_msg_c::types::ricsubscription_delete_request); + break; + case 7: + ret.set(init_msg_c::types::ricservice_upd); + break; + case 4: + ret.set(init_msg_c::types::ri_cctrl_request); + break; + case 1: + ret.set(init_msg_c::types::e2setup_request); + break; + case 10: + ret.set(init_msg_c::types::e2node_cfg_upd); + break; + case 11: + ret.set(init_msg_c::types::e2conn_upd); + break; + case 3: + ret.set(init_msg_c::types::reset_request); + break; + case 13: + ret.set(init_msg_c::types::e2_removal_request); + break; + case 5: + ret.set(init_msg_c::types::ri_cind); + break; + case 6: + ret.set(init_msg_c::types::ricservice_query); + break; + case 2: + ret.set(init_msg_c::types::error_ind); + break; + case 12: + ret.set(init_msg_c::types::ricsubscription_delete_required); + break; + default: + asn1::log_error("The proc_code=%d is not recognized", proc_code); + } + return ret; +} +e2_ap_elem_procs_o::successful_outcome_c e2_ap_elem_procs_o::get_successful_outcome(const uint16_t& proc_code) +{ + successful_outcome_c ret{}; + switch (proc_code) { + case 8: + ret.set(successful_outcome_c::types::ricsubscription_resp); + break; + case 9: + ret.set(successful_outcome_c::types::ricsubscription_delete_resp); + break; + case 7: + ret.set(successful_outcome_c::types::ricservice_upd_ack); + break; + case 4: + ret.set(successful_outcome_c::types::ri_cctrl_ack); + break; + case 1: + ret.set(successful_outcome_c::types::e2setup_resp); + break; + case 10: + ret.set(successful_outcome_c::types::e2node_cfg_upd_ack); + break; + case 11: + ret.set(successful_outcome_c::types::e2conn_upd_ack); + break; + case 3: + ret.set(successful_outcome_c::types::reset_resp); + break; + case 13: + ret.set(successful_outcome_c::types::e2_removal_resp); + break; + default: + asn1::log_error("The proc_code=%d is not recognized", proc_code); + } + return ret; +} +e2_ap_elem_procs_o::unsuccessful_outcome_c e2_ap_elem_procs_o::get_unsuccessful_outcome(const uint16_t& proc_code) +{ + unsuccessful_outcome_c ret{}; + switch (proc_code) { + case 8: + ret.set(unsuccessful_outcome_c::types::ricsubscription_fail); + break; + case 9: + ret.set(unsuccessful_outcome_c::types::ricsubscription_delete_fail); + break; + case 7: + ret.set(unsuccessful_outcome_c::types::ricservice_upd_fail); + break; + case 4: + ret.set(unsuccessful_outcome_c::types::ri_cctrl_fail); + break; + case 1: + ret.set(unsuccessful_outcome_c::types::e2setup_fail); + break; + case 10: + ret.set(unsuccessful_outcome_c::types::e2node_cfg_upd_fail); + break; + case 11: + ret.set(unsuccessful_outcome_c::types::e2conn_upd_fail); + break; + case 13: + ret.set(unsuccessful_outcome_c::types::e2_removal_fail); + break; + default: + asn1::log_error("The proc_code=%d is not recognized", proc_code); + } + return ret; +} +crit_e e2_ap_elem_procs_o::get_crit(const uint16_t& proc_code) +{ + switch (proc_code) { + case 8: + return crit_e::reject; + case 9: + return crit_e::reject; + case 7: + return crit_e::reject; + case 4: + return crit_e::reject; + case 1: + return crit_e::reject; + case 10: + return crit_e::reject; + case 11: + return crit_e::reject; + case 3: + return crit_e::reject; + case 13: + return crit_e::reject; + case 5: + return crit_e::ignore; + case 6: + return crit_e::ignore; + case 2: + return crit_e::ignore; + case 12: + return crit_e::ignore; + default: + asn1::log_error("The proc_code=%d is not recognized", proc_code); + } + return {}; +} + +// InitiatingMessage ::= OPEN TYPE +void e2_ap_elem_procs_o::init_msg_c::destroy_() +{ + switch (type_) { + case types::ricsubscription_request: + c.destroy(); + break; + case types::ricsubscription_delete_request: + c.destroy(); + break; + case types::ricservice_upd: + c.destroy(); + break; + case types::ri_cctrl_request: + c.destroy(); + break; + case types::e2setup_request: + c.destroy(); + break; + case types::e2node_cfg_upd: + c.destroy(); + break; + case types::e2conn_upd: + c.destroy(); + break; + case types::reset_request: + c.destroy(); + break; + case types::e2_removal_request: + c.destroy(); + break; + case types::ri_cind: + c.destroy(); + break; + case types::ricservice_query: + c.destroy(); + break; + case types::error_ind: + c.destroy(); + break; + case types::ricsubscription_delete_required: + c.destroy(); + break; + default: + break; + } +} +void e2_ap_elem_procs_o::init_msg_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ricsubscription_request: + c.init(); + break; + case types::ricsubscription_delete_request: + c.init(); + break; + case types::ricservice_upd: + c.init(); + break; + case types::ri_cctrl_request: + c.init(); + break; + case types::e2setup_request: + c.init(); + break; + case types::e2node_cfg_upd: + c.init(); + break; + case types::e2conn_upd: + c.init(); + break; + case types::reset_request: + c.init(); + break; + case types::e2_removal_request: + c.init(); + break; + case types::ri_cind: + c.init(); + break; + case types::ricservice_query: + c.init(); + break; + case types::error_ind: + c.init(); + break; + case types::ricsubscription_delete_required: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + } +} +e2_ap_elem_procs_o::init_msg_c::init_msg_c(const e2_ap_elem_procs_o::init_msg_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ricsubscription_request: + c.init(other.c.get()); + break; + case types::ricsubscription_delete_request: + c.init(other.c.get()); + break; + case types::ricservice_upd: + c.init(other.c.get()); + break; + case types::ri_cctrl_request: + c.init(other.c.get()); + break; + case types::e2setup_request: + c.init(other.c.get()); + break; + case types::e2node_cfg_upd: + c.init(other.c.get()); + break; + case types::e2conn_upd: + c.init(other.c.get()); + break; + case types::reset_request: + c.init(other.c.get()); + break; + case types::e2_removal_request: + c.init(other.c.get()); + break; + case types::ri_cind: + c.init(other.c.get()); + break; + case types::ricservice_query: + c.init(other.c.get()); + break; + case types::error_ind: + c.init(other.c.get()); + break; + case types::ricsubscription_delete_required: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + } +} +e2_ap_elem_procs_o::init_msg_c& e2_ap_elem_procs_o::init_msg_c::operator=(const e2_ap_elem_procs_o::init_msg_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ricsubscription_request: + c.set(other.c.get()); + break; + case types::ricsubscription_delete_request: + c.set(other.c.get()); + break; + case types::ricservice_upd: + c.set(other.c.get()); + break; + case types::ri_cctrl_request: + c.set(other.c.get()); + break; + case types::e2setup_request: + c.set(other.c.get()); + break; + case types::e2node_cfg_upd: + c.set(other.c.get()); + break; + case types::e2conn_upd: + c.set(other.c.get()); + break; + case types::reset_request: + c.set(other.c.get()); + break; + case types::e2_removal_request: + c.set(other.c.get()); + break; + case types::ri_cind: + c.set(other.c.get()); + break; + case types::ricservice_query: + c.set(other.c.get()); + break; + case types::error_ind: + c.set(other.c.get()); + break; + case types::ricsubscription_delete_required: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + } + + return *this; +} +ricsubscription_request_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_request() +{ + assert_choice_type(types::ricsubscription_request, type_, "InitiatingMessage"); + return c.get(); +} +ricsubscription_delete_request_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_delete_request() +{ + assert_choice_type(types::ricsubscription_delete_request, type_, "InitiatingMessage"); + return c.get(); +} +ricservice_upd_s& e2_ap_elem_procs_o::init_msg_c::ricservice_upd() +{ + assert_choice_type(types::ricservice_upd, type_, "InitiatingMessage"); + return c.get(); +} +ri_cctrl_request_s& e2_ap_elem_procs_o::init_msg_c::ri_cctrl_request() +{ + assert_choice_type(types::ri_cctrl_request, type_, "InitiatingMessage"); + return c.get(); +} +e2setup_request_s& e2_ap_elem_procs_o::init_msg_c::e2setup_request() +{ + assert_choice_type(types::e2setup_request, type_, "InitiatingMessage"); + return c.get(); +} +e2node_cfg_upd_s& e2_ap_elem_procs_o::init_msg_c::e2node_cfg_upd() +{ + assert_choice_type(types::e2node_cfg_upd, type_, "InitiatingMessage"); + return c.get(); +} +e2conn_upd_s& e2_ap_elem_procs_o::init_msg_c::e2conn_upd() +{ + assert_choice_type(types::e2conn_upd, type_, "InitiatingMessage"); + return c.get(); +} +reset_request_s& e2_ap_elem_procs_o::init_msg_c::reset_request() +{ + assert_choice_type(types::reset_request, type_, "InitiatingMessage"); + return c.get(); +} +e2_removal_request_s& e2_ap_elem_procs_o::init_msg_c::e2_removal_request() +{ + assert_choice_type(types::e2_removal_request, type_, "InitiatingMessage"); + return c.get(); +} +ri_cind_s& e2_ap_elem_procs_o::init_msg_c::ri_cind() +{ + assert_choice_type(types::ri_cind, type_, "InitiatingMessage"); + return c.get(); +} +ricservice_query_s& e2_ap_elem_procs_o::init_msg_c::ricservice_query() +{ + assert_choice_type(types::ricservice_query, type_, "InitiatingMessage"); + return c.get(); +} +error_ind_s& e2_ap_elem_procs_o::init_msg_c::error_ind() +{ + assert_choice_type(types::error_ind, type_, "InitiatingMessage"); + return c.get(); +} +ricsubscription_delete_required_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_delete_required() +{ + assert_choice_type(types::ricsubscription_delete_required, type_, "InitiatingMessage"); + return c.get(); +} +const ricsubscription_request_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_request() const +{ + assert_choice_type(types::ricsubscription_request, type_, "InitiatingMessage"); + return c.get(); +} +const ricsubscription_delete_request_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_delete_request() const +{ + assert_choice_type(types::ricsubscription_delete_request, type_, "InitiatingMessage"); + return c.get(); +} +const ricservice_upd_s& e2_ap_elem_procs_o::init_msg_c::ricservice_upd() const +{ + assert_choice_type(types::ricservice_upd, type_, "InitiatingMessage"); + return c.get(); +} +const ri_cctrl_request_s& e2_ap_elem_procs_o::init_msg_c::ri_cctrl_request() const +{ + assert_choice_type(types::ri_cctrl_request, type_, "InitiatingMessage"); + return c.get(); +} +const e2setup_request_s& e2_ap_elem_procs_o::init_msg_c::e2setup_request() const +{ + assert_choice_type(types::e2setup_request, type_, "InitiatingMessage"); + return c.get(); +} +const e2node_cfg_upd_s& e2_ap_elem_procs_o::init_msg_c::e2node_cfg_upd() const +{ + assert_choice_type(types::e2node_cfg_upd, type_, "InitiatingMessage"); + return c.get(); +} +const e2conn_upd_s& e2_ap_elem_procs_o::init_msg_c::e2conn_upd() const +{ + assert_choice_type(types::e2conn_upd, type_, "InitiatingMessage"); + return c.get(); +} +const reset_request_s& e2_ap_elem_procs_o::init_msg_c::reset_request() const +{ + assert_choice_type(types::reset_request, type_, "InitiatingMessage"); + return c.get(); +} +const e2_removal_request_s& e2_ap_elem_procs_o::init_msg_c::e2_removal_request() const +{ + assert_choice_type(types::e2_removal_request, type_, "InitiatingMessage"); + return c.get(); +} +const ri_cind_s& e2_ap_elem_procs_o::init_msg_c::ri_cind() const +{ + assert_choice_type(types::ri_cind, type_, "InitiatingMessage"); + return c.get(); +} +const ricservice_query_s& e2_ap_elem_procs_o::init_msg_c::ricservice_query() const +{ + assert_choice_type(types::ricservice_query, type_, "InitiatingMessage"); + return c.get(); +} +const error_ind_s& e2_ap_elem_procs_o::init_msg_c::error_ind() const +{ + assert_choice_type(types::error_ind, type_, "InitiatingMessage"); + return c.get(); +} +const ricsubscription_delete_required_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_delete_required() const +{ + assert_choice_type(types::ricsubscription_delete_required, type_, "InitiatingMessage"); + return c.get(); +} +void e2_ap_elem_procs_o::init_msg_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ricsubscription_request: + j.write_fieldname("RICsubscriptionRequest"); + c.get().to_json(j); + break; + case types::ricsubscription_delete_request: + j.write_fieldname("RICsubscriptionDeleteRequest"); + c.get().to_json(j); + break; + case types::ricservice_upd: + j.write_fieldname("RICserviceUpdate"); + c.get().to_json(j); + break; + case types::ri_cctrl_request: + j.write_fieldname("RICcontrolRequest"); + c.get().to_json(j); + break; + case types::e2setup_request: + j.write_fieldname("E2setupRequest"); + c.get().to_json(j); + break; + case types::e2node_cfg_upd: + j.write_fieldname("E2nodeConfigurationUpdate"); + c.get().to_json(j); + break; + case types::e2conn_upd: + j.write_fieldname("E2connectionUpdate"); + c.get().to_json(j); + break; + case types::reset_request: + j.write_fieldname("ResetRequest"); + c.get().to_json(j); + break; + case types::e2_removal_request: + j.write_fieldname("E2RemovalRequest"); + c.get().to_json(j); + break; + case types::ri_cind: + j.write_fieldname("RICindication"); + c.get().to_json(j); + break; + case types::ricservice_query: + j.write_fieldname("RICserviceQuery"); + c.get().to_json(j); + break; + case types::error_ind: + j.write_fieldname("ErrorIndication"); + c.get().to_json(j); + break; + case types::ricsubscription_delete_required: + j.write_fieldname("RICsubscriptionDeleteRequired"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_ap_elem_procs_o::init_msg_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricsubscription_delete_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricservice_upd: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cctrl_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2setup_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_cfg_upd: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2conn_upd: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::reset_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2_removal_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cind: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricservice_query: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::error_ind: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricsubscription_delete_required: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_ap_elem_procs_o::init_msg_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricsubscription_delete_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricservice_upd: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cctrl_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2setup_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_cfg_upd: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2conn_upd: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::reset_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2_removal_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cind: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricservice_query: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::error_ind: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricsubscription_delete_required: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_ap_elem_procs_o::init_msg_c::types_opts::to_string() const +{ + static const char* options[] = {"RICsubscriptionRequest", + "RICsubscriptionDeleteRequest", + "RICserviceUpdate", + "RICcontrolRequest", + "E2setupRequest", + "E2nodeConfigurationUpdate", + "E2connectionUpdate", + "ResetRequest", + "E2RemovalRequest", + "RICindication", + "RICserviceQuery", + "ErrorIndication", + "RICsubscriptionDeleteRequired"}; + return convert_enum_idx(options, 13, value, "e2_ap_elem_procs_o::init_msg_c::types"); +} + +// SuccessfulOutcome ::= OPEN TYPE +void e2_ap_elem_procs_o::successful_outcome_c::destroy_() +{ + switch (type_) { + case types::ricsubscription_resp: + c.destroy(); + break; + case types::ricsubscription_delete_resp: + c.destroy(); + break; + case types::ricservice_upd_ack: + c.destroy(); + break; + case types::ri_cctrl_ack: + c.destroy(); + break; + case types::e2setup_resp: + c.destroy(); + break; + case types::e2node_cfg_upd_ack: + c.destroy(); + break; + case types::e2conn_upd_ack: + c.destroy(); + break; + case types::reset_resp: + c.destroy(); + break; + case types::e2_removal_resp: + c.destroy(); + break; + default: + break; + } +} +void e2_ap_elem_procs_o::successful_outcome_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ricsubscription_resp: + c.init(); + break; + case types::ricsubscription_delete_resp: + c.init(); + break; + case types::ricservice_upd_ack: + c.init(); + break; + case types::ri_cctrl_ack: + c.init(); + break; + case types::e2setup_resp: + c.init(); + break; + case types::e2node_cfg_upd_ack: + c.init(); + break; + case types::e2conn_upd_ack: + c.init(); + break; + case types::reset_resp: + c.init(); + break; + case types::e2_removal_resp: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + } +} +e2_ap_elem_procs_o::successful_outcome_c::successful_outcome_c(const e2_ap_elem_procs_o::successful_outcome_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ricsubscription_resp: + c.init(other.c.get()); + break; + case types::ricsubscription_delete_resp: + c.init(other.c.get()); + break; + case types::ricservice_upd_ack: + c.init(other.c.get()); + break; + case types::ri_cctrl_ack: + c.init(other.c.get()); + break; + case types::e2setup_resp: + c.init(other.c.get()); + break; + case types::e2node_cfg_upd_ack: + c.init(other.c.get()); + break; + case types::e2conn_upd_ack: + c.init(other.c.get()); + break; + case types::reset_resp: + c.init(other.c.get()); + break; + case types::e2_removal_resp: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + } +} +e2_ap_elem_procs_o::successful_outcome_c& +e2_ap_elem_procs_o::successful_outcome_c::operator=(const e2_ap_elem_procs_o::successful_outcome_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ricsubscription_resp: + c.set(other.c.get()); + break; + case types::ricsubscription_delete_resp: + c.set(other.c.get()); + break; + case types::ricservice_upd_ack: + c.set(other.c.get()); + break; + case types::ri_cctrl_ack: + c.set(other.c.get()); + break; + case types::e2setup_resp: + c.set(other.c.get()); + break; + case types::e2node_cfg_upd_ack: + c.set(other.c.get()); + break; + case types::e2conn_upd_ack: + c.set(other.c.get()); + break; + case types::reset_resp: + c.set(other.c.get()); + break; + case types::e2_removal_resp: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + } + + return *this; +} +ricsubscription_resp_s& e2_ap_elem_procs_o::successful_outcome_c::ricsubscription_resp() +{ + assert_choice_type(types::ricsubscription_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +ricsubscription_delete_resp_s& e2_ap_elem_procs_o::successful_outcome_c::ricsubscription_delete_resp() +{ + assert_choice_type(types::ricsubscription_delete_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +ricservice_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::ricservice_upd_ack() +{ + assert_choice_type(types::ricservice_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +ri_cctrl_ack_s& e2_ap_elem_procs_o::successful_outcome_c::ri_cctrl_ack() +{ + assert_choice_type(types::ri_cctrl_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +e2setup_resp_s& e2_ap_elem_procs_o::successful_outcome_c::e2setup_resp() +{ + assert_choice_type(types::e2setup_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +e2node_cfg_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::e2node_cfg_upd_ack() +{ + assert_choice_type(types::e2node_cfg_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +e2conn_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::e2conn_upd_ack() +{ + assert_choice_type(types::e2conn_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +reset_resp_s& e2_ap_elem_procs_o::successful_outcome_c::reset_resp() +{ + assert_choice_type(types::reset_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +e2_removal_resp_s& e2_ap_elem_procs_o::successful_outcome_c::e2_removal_resp() +{ + assert_choice_type(types::e2_removal_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +const ricsubscription_resp_s& e2_ap_elem_procs_o::successful_outcome_c::ricsubscription_resp() const +{ + assert_choice_type(types::ricsubscription_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +const ricsubscription_delete_resp_s& e2_ap_elem_procs_o::successful_outcome_c::ricsubscription_delete_resp() const +{ + assert_choice_type(types::ricsubscription_delete_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +const ricservice_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::ricservice_upd_ack() const +{ + assert_choice_type(types::ricservice_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +const ri_cctrl_ack_s& e2_ap_elem_procs_o::successful_outcome_c::ri_cctrl_ack() const +{ + assert_choice_type(types::ri_cctrl_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +const e2setup_resp_s& e2_ap_elem_procs_o::successful_outcome_c::e2setup_resp() const +{ + assert_choice_type(types::e2setup_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +const e2node_cfg_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::e2node_cfg_upd_ack() const +{ + assert_choice_type(types::e2node_cfg_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +const e2conn_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::e2conn_upd_ack() const +{ + assert_choice_type(types::e2conn_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +const reset_resp_s& e2_ap_elem_procs_o::successful_outcome_c::reset_resp() const +{ + assert_choice_type(types::reset_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +const e2_removal_resp_s& e2_ap_elem_procs_o::successful_outcome_c::e2_removal_resp() const +{ + assert_choice_type(types::e2_removal_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +void e2_ap_elem_procs_o::successful_outcome_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ricsubscription_resp: + j.write_fieldname("RICsubscriptionResponse"); + c.get().to_json(j); + break; + case types::ricsubscription_delete_resp: + j.write_fieldname("RICsubscriptionDeleteResponse"); + c.get().to_json(j); + break; + case types::ricservice_upd_ack: + j.write_fieldname("RICserviceUpdateAcknowledge"); + c.get().to_json(j); + break; + case types::ri_cctrl_ack: + j.write_fieldname("RICcontrolAcknowledge"); + c.get().to_json(j); + break; + case types::e2setup_resp: + j.write_fieldname("E2setupResponse"); + c.get().to_json(j); + break; + case types::e2node_cfg_upd_ack: + j.write_fieldname("E2nodeConfigurationUpdateAcknowledge"); + c.get().to_json(j); + break; + case types::e2conn_upd_ack: + j.write_fieldname("E2connectionUpdateAcknowledge"); + c.get().to_json(j); + break; + case types::reset_resp: + j.write_fieldname("ResetResponse"); + c.get().to_json(j); + break; + case types::e2_removal_resp: + j.write_fieldname("E2RemovalResponse"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_ap_elem_procs_o::successful_outcome_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_resp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricsubscription_delete_resp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricservice_upd_ack: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cctrl_ack: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2setup_resp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_cfg_upd_ack: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2conn_upd_ack: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::reset_resp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2_removal_resp: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_ap_elem_procs_o::successful_outcome_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_resp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricsubscription_delete_resp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricservice_upd_ack: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cctrl_ack: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2setup_resp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_cfg_upd_ack: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2conn_upd_ack: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::reset_resp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2_removal_resp: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_ap_elem_procs_o::successful_outcome_c::types_opts::to_string() const +{ + static const char* options[] = {"RICsubscriptionResponse", + "RICsubscriptionDeleteResponse", + "RICserviceUpdateAcknowledge", + "RICcontrolAcknowledge", + "E2setupResponse", + "E2nodeConfigurationUpdateAcknowledge", + "E2connectionUpdateAcknowledge", + "ResetResponse", + "E2RemovalResponse"}; + return convert_enum_idx(options, 9, value, "e2_ap_elem_procs_o::successful_outcome_c::types"); +} + +// UnsuccessfulOutcome ::= OPEN TYPE +void e2_ap_elem_procs_o::unsuccessful_outcome_c::destroy_() +{ + switch (type_) { + case types::ricsubscription_fail: + c.destroy(); + break; + case types::ricsubscription_delete_fail: + c.destroy(); + break; + case types::ricservice_upd_fail: + c.destroy(); + break; + case types::ri_cctrl_fail: + c.destroy(); + break; + case types::e2setup_fail: + c.destroy(); + break; + case types::e2node_cfg_upd_fail: + c.destroy(); + break; + case types::e2conn_upd_fail: + c.destroy(); + break; + case types::e2_removal_fail: + c.destroy(); + break; + default: + break; + } +} +void e2_ap_elem_procs_o::unsuccessful_outcome_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ricsubscription_fail: + c.init(); + break; + case types::ricsubscription_delete_fail: + c.init(); + break; + case types::ricservice_upd_fail: + c.init(); + break; + case types::ri_cctrl_fail: + c.init(); + break; + case types::e2setup_fail: + c.init(); + break; + case types::e2node_cfg_upd_fail: + c.init(); + break; + case types::e2conn_upd_fail: + c.init(); + break; + case types::e2_removal_fail: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + } +} +e2_ap_elem_procs_o::unsuccessful_outcome_c::unsuccessful_outcome_c( + const e2_ap_elem_procs_o::unsuccessful_outcome_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ricsubscription_fail: + c.init(other.c.get()); + break; + case types::ricsubscription_delete_fail: + c.init(other.c.get()); + break; + case types::ricservice_upd_fail: + c.init(other.c.get()); + break; + case types::ri_cctrl_fail: + c.init(other.c.get()); + break; + case types::e2setup_fail: + c.init(other.c.get()); + break; + case types::e2node_cfg_upd_fail: + c.init(other.c.get()); + break; + case types::e2conn_upd_fail: + c.init(other.c.get()); + break; + case types::e2_removal_fail: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + } +} +e2_ap_elem_procs_o::unsuccessful_outcome_c& +e2_ap_elem_procs_o::unsuccessful_outcome_c::operator=(const e2_ap_elem_procs_o::unsuccessful_outcome_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ricsubscription_fail: + c.set(other.c.get()); + break; + case types::ricsubscription_delete_fail: + c.set(other.c.get()); + break; + case types::ricservice_upd_fail: + c.set(other.c.get()); + break; + case types::ri_cctrl_fail: + c.set(other.c.get()); + break; + case types::e2setup_fail: + c.set(other.c.get()); + break; + case types::e2node_cfg_upd_fail: + c.set(other.c.get()); + break; + case types::e2conn_upd_fail: + c.set(other.c.get()); + break; + case types::e2_removal_fail: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + } + + return *this; +} +ricsubscription_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricsubscription_fail() +{ + assert_choice_type(types::ricsubscription_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +ricsubscription_delete_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricsubscription_delete_fail() +{ + assert_choice_type(types::ricsubscription_delete_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +ricservice_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricservice_upd_fail() +{ + assert_choice_type(types::ricservice_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +ri_cctrl_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ri_cctrl_fail() +{ + assert_choice_type(types::ri_cctrl_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +e2setup_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2setup_fail() +{ + assert_choice_type(types::e2setup_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +e2node_cfg_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2node_cfg_upd_fail() +{ + assert_choice_type(types::e2node_cfg_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +e2conn_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2conn_upd_fail() +{ + assert_choice_type(types::e2conn_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +e2_removal_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2_removal_fail() +{ + assert_choice_type(types::e2_removal_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const ricsubscription_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricsubscription_fail() const +{ + assert_choice_type(types::ricsubscription_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const ricsubscription_delete_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricsubscription_delete_fail() const +{ + assert_choice_type(types::ricsubscription_delete_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const ricservice_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricservice_upd_fail() const +{ + assert_choice_type(types::ricservice_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const ri_cctrl_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ri_cctrl_fail() const +{ + assert_choice_type(types::ri_cctrl_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const e2setup_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2setup_fail() const +{ + assert_choice_type(types::e2setup_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const e2node_cfg_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2node_cfg_upd_fail() const +{ + assert_choice_type(types::e2node_cfg_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const e2conn_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2conn_upd_fail() const +{ + assert_choice_type(types::e2conn_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const e2_removal_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2_removal_fail() const +{ + assert_choice_type(types::e2_removal_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +void e2_ap_elem_procs_o::unsuccessful_outcome_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ricsubscription_fail: + j.write_fieldname("RICsubscriptionFailure"); + c.get().to_json(j); + break; + case types::ricsubscription_delete_fail: + j.write_fieldname("RICsubscriptionDeleteFailure"); + c.get().to_json(j); + break; + case types::ricservice_upd_fail: + j.write_fieldname("RICserviceUpdateFailure"); + c.get().to_json(j); + break; + case types::ri_cctrl_fail: + j.write_fieldname("RICcontrolFailure"); + c.get().to_json(j); + break; + case types::e2setup_fail: + j.write_fieldname("E2setupFailure"); + c.get().to_json(j); + break; + case types::e2node_cfg_upd_fail: + j.write_fieldname("E2nodeConfigurationUpdateFailure"); + c.get().to_json(j); + break; + case types::e2conn_upd_fail: + j.write_fieldname("E2connectionUpdateFailure"); + c.get().to_json(j); + break; + case types::e2_removal_fail: + j.write_fieldname("E2RemovalFailure"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_ap_elem_procs_o::unsuccessful_outcome_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricsubscription_delete_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricservice_upd_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cctrl_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2setup_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_cfg_upd_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2conn_upd_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2_removal_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_ap_elem_procs_o::unsuccessful_outcome_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricsubscription_delete_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricservice_upd_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cctrl_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2setup_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_cfg_upd_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2conn_upd_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2_removal_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::to_string() const +{ + static const char* options[] = {"RICsubscriptionFailure", + "RICsubscriptionDeleteFailure", + "RICserviceUpdateFailure", + "RICcontrolFailure", + "E2setupFailure", + "E2nodeConfigurationUpdateFailure", + "E2connectionUpdateFailure", + "E2RemovalFailure"}; + return convert_enum_idx(options, 8, value, "e2_ap_elem_procs_o::unsuccessful_outcome_c::types"); +} + +// InitiatingMessage ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +SRSASN_CODE init_msg_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, proc_code, (uint16_t)0u, (uint16_t)255u, false, true)); + warn_assert(crit != e2_ap_elem_procs_o::get_crit(proc_code), __func__, __LINE__); + HANDLE_CODE(crit.pack(bref)); + HANDLE_CODE(value.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE init_msg_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(proc_code, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(crit.unpack(bref)); + value = e2_ap_elem_procs_o::get_init_msg(proc_code); + HANDLE_CODE(value.unpack(bref)); + + return SRSASN_SUCCESS; +} +void init_msg_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("procedureCode", proc_code); + j.write_str("criticality", crit.to_string()); + j.write_fieldname("value"); + value.to_json(j); + j.end_obj(); +} +bool init_msg_s::load_info_obj(const uint16_t& proc_code_) +{ + if (not e2_ap_elem_procs_o::is_proc_code_valid(proc_code_)) { + return false; + } + proc_code = proc_code_; + crit = e2_ap_elem_procs_o::get_crit(proc_code); + value = e2_ap_elem_procs_o::get_init_msg(proc_code); + return value.type().value != e2_ap_elem_procs_o::init_msg_c::types_opts::nulltype; +} + +// SuccessfulOutcome ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +SRSASN_CODE successful_outcome_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, proc_code, (uint16_t)0u, (uint16_t)255u, false, true)); + warn_assert(crit != e2_ap_elem_procs_o::get_crit(proc_code), __func__, __LINE__); + HANDLE_CODE(crit.pack(bref)); + HANDLE_CODE(value.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE successful_outcome_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(proc_code, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(crit.unpack(bref)); + value = e2_ap_elem_procs_o::get_successful_outcome(proc_code); + HANDLE_CODE(value.unpack(bref)); + + return SRSASN_SUCCESS; +} +void successful_outcome_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("procedureCode", proc_code); + j.write_str("criticality", crit.to_string()); + j.write_fieldname("value"); + value.to_json(j); + j.end_obj(); +} +bool successful_outcome_s::load_info_obj(const uint16_t& proc_code_) +{ + if (not e2_ap_elem_procs_o::is_proc_code_valid(proc_code_)) { + return false; + } + proc_code = proc_code_; + crit = e2_ap_elem_procs_o::get_crit(proc_code); + value = e2_ap_elem_procs_o::get_successful_outcome(proc_code); + return value.type().value != e2_ap_elem_procs_o::successful_outcome_c::types_opts::nulltype; +} + +// UnsuccessfulOutcome ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +SRSASN_CODE unsuccessful_outcome_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, proc_code, (uint16_t)0u, (uint16_t)255u, false, true)); + warn_assert(crit != e2_ap_elem_procs_o::get_crit(proc_code), __func__, __LINE__); + HANDLE_CODE(crit.pack(bref)); + HANDLE_CODE(value.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE unsuccessful_outcome_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(proc_code, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(crit.unpack(bref)); + value = e2_ap_elem_procs_o::get_unsuccessful_outcome(proc_code); + HANDLE_CODE(value.unpack(bref)); + + return SRSASN_SUCCESS; +} +void unsuccessful_outcome_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("procedureCode", proc_code); + j.write_str("criticality", crit.to_string()); + j.write_fieldname("value"); + value.to_json(j); + j.end_obj(); +} +bool unsuccessful_outcome_s::load_info_obj(const uint16_t& proc_code_) +{ + if (not e2_ap_elem_procs_o::is_proc_code_valid(proc_code_)) { + return false; + } + proc_code = proc_code_; + crit = e2_ap_elem_procs_o::get_crit(proc_code); + value = e2_ap_elem_procs_o::get_unsuccessful_outcome(proc_code); + return value.type().value != e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::nulltype; +} + +// E2AP-PDU ::= CHOICE +void e2_ap_pdu_c::destroy_() +{ + switch (type_) { + case types::init_msg: + c.destroy(); + break; + case types::successful_outcome: + c.destroy(); + break; + case types::unsuccessful_outcome: + c.destroy(); + break; + default: + break; + } +} +void e2_ap_pdu_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::init_msg: + c.init(); + break; + case types::successful_outcome: + c.init(); + break; + case types::unsuccessful_outcome: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + } +} +e2_ap_pdu_c::e2_ap_pdu_c(const e2_ap_pdu_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::init_msg: + c.init(other.c.get()); + break; + case types::successful_outcome: + c.init(other.c.get()); + break; + case types::unsuccessful_outcome: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + } +} +e2_ap_pdu_c& e2_ap_pdu_c::operator=(const e2_ap_pdu_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::init_msg: + c.set(other.c.get()); + break; + case types::successful_outcome: + c.set(other.c.get()); + break; + case types::unsuccessful_outcome: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + } + + return *this; +} +init_msg_s& e2_ap_pdu_c::set_init_msg() +{ + set(types::init_msg); + return c.get(); +} +successful_outcome_s& e2_ap_pdu_c::set_successful_outcome() +{ + set(types::successful_outcome); + return c.get(); +} +unsuccessful_outcome_s& e2_ap_pdu_c::set_unsuccessful_outcome() +{ + set(types::unsuccessful_outcome); + return c.get(); +} +void e2_ap_pdu_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::init_msg: + j.write_fieldname("initiatingMessage"); + c.get().to_json(j); + break; + case types::successful_outcome: + j.write_fieldname("successfulOutcome"); + c.get().to_json(j); + break; + case types::unsuccessful_outcome: + j.write_fieldname("unsuccessfulOutcome"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_ap_pdu_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::init_msg: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::successful_outcome: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::unsuccessful_outcome: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_ap_pdu_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::init_msg: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::successful_outcome: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::unsuccessful_outcome: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_ap_pdu_c::types_opts::to_string() const +{ + static const char* options[] = {"initiatingMessage", "successfulOutcome", "unsuccessfulOutcome"}; + return convert_enum_idx(options, 3, value, "e2_ap_pdu_c::types"); +} + +// ProtocolIE-FieldPair{E2AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE{{E2AP-PROTOCOL-IES-PAIR}} +template +SRSASN_CODE protocol_ie_field_pair_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); + warn_assert(first_crit != ies_set_paramT_::get_first_crit(id), __func__, __LINE__); + HANDLE_CODE(first_crit.pack(bref)); + HANDLE_CODE(first_value.pack(bref)); + warn_assert(second_crit != ies_set_paramT_::get_second_crit(id), __func__, __LINE__); + HANDLE_CODE(second_crit.pack(bref)); + HANDLE_CODE(second_value.pack(bref)); + + return SRSASN_SUCCESS; +} +template +SRSASN_CODE protocol_ie_field_pair_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(first_crit.unpack(bref)); + first_value = ies_set_paramT_::get_first_value(id); + HANDLE_CODE(first_value.unpack(bref)); + HANDLE_CODE(second_crit.unpack(bref)); + second_value = ies_set_paramT_::get_second_value(id); + HANDLE_CODE(second_value.unpack(bref)); + + return SRSASN_SUCCESS; +} +template +void protocol_ie_field_pair_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("id", id); + j.write_str("firstCriticality", first_crit.to_string()); + j.write_str("secondCriticality", second_crit.to_string()); + j.end_obj(); +} +template +bool protocol_ie_field_pair_s::load_info_obj(const uint32_t& id_) +{ + if (not ies_set_paramT_::is_id_valid(id_)) { + return false; + } + id = id_; + first_crit = ies_set_paramT_::get_first_crit(id); + first_value = ies_set_paramT_::get_first_value(id); + second_crit = ies_set_paramT_::get_second_crit(id); + second_value = ies_set_paramT_::get_second_value(id); + return first_value.type().value != ies_set_paramT_::first_value_c::types_opts::nulltype and + second_value.type().value != ies_set_paramT_::second_value_c::types_opts::nulltype; +} diff --git a/lib/src/asn1/e2sm.cpp b/lib/src/asn1/e2sm.cpp new file mode 100644 index 000000000..354c0953a --- /dev/null +++ b/lib/src/asn1/e2sm.cpp @@ -0,0 +1,3065 @@ +/** + * + * \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 "srsran/asn1/e2sm.h" +#include + +using namespace asn1; +using namespace asn1::e2sm; + +/******************************************************************************* + * Struct Methods + ******************************************************************************/ + +// EUTRA-CGI ::= SEQUENCE +SRSASN_CODE eutra_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(eutra_cell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE eutra_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(eutra_cell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void eutra_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("eUTRACellIdentity", eutra_cell_id.to_string()); + j.end_obj(); +} + +// NR-CGI ::= SEQUENCE +SRSASN_CODE nr_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(nrcell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(nrcell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void nr_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("nRCellIdentity", nrcell_id.to_string()); + j.end_obj(); +} + +// CGI ::= CHOICE +void cgi_c::destroy_() +{ + switch (type_) { + case types::nr_cgi: + c.destroy(); + break; + case types::eutra_cgi: + c.destroy(); + break; + default: + break; + } +} +void cgi_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr_cgi: + c.init(); + break; + case types::eutra_cgi: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c::cgi_c(const cgi_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr_cgi: + c.init(other.c.get()); + break; + case types::eutra_cgi: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c& cgi_c::operator=(const cgi_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr_cgi: + c.set(other.c.get()); + break; + case types::eutra_cgi: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + + return *this; +} +nr_cgi_s& cgi_c::set_nr_cgi() +{ + set(types::nr_cgi); + return c.get(); +} +eutra_cgi_s& cgi_c::set_eutra_cgi() +{ + set(types::eutra_cgi); + return c.get(); +} +void cgi_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr_cgi: + j.write_fieldname("nR-CGI"); + c.get().to_json(j); + break; + case types::eutra_cgi: + j.write_fieldname("eUTRA-CGI"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + j.end_obj(); +} +SRSASN_CODE cgi_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE cgi_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* cgi_c::types_opts::to_string() const +{ + static const char* options[] = {"nR-CGI", "eUTRA-CGI"}; + return convert_enum_idx(options, 2, value, "cgi_c::types"); +} + +// GUAMI ::= SEQUENCE +SRSASN_CODE guami_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(amf_region_id.pack(bref)); + HANDLE_CODE(amf_set_id.pack(bref)); + HANDLE_CODE(amf_pointer.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE guami_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(amf_region_id.unpack(bref)); + HANDLE_CODE(amf_set_id.unpack(bref)); + HANDLE_CODE(amf_pointer.unpack(bref)); + + return SRSASN_SUCCESS; +} +void guami_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("aMFRegionID", amf_region_id.to_string()); + j.write_str("aMFSetID", amf_set_id.to_string()); + j.write_str("aMFPointer", amf_pointer.to_string()); + j.end_obj(); +} + +// GUMMEI ::= SEQUENCE +SRSASN_CODE gummei_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(mme_group_id.pack(bref)); + HANDLE_CODE(mme_code.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE gummei_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(mme_group_id.unpack(bref)); + HANDLE_CODE(mme_code.unpack(bref)); + + return SRSASN_SUCCESS; +} +void gummei_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_str("mME-Group-ID", mme_group_id.to_string()); + j.write_str("mME-Code", mme_code.to_string()); + j.end_obj(); +} + +// CoreCPID ::= CHOICE +void core_cpid_c::destroy_() +{ + switch (type_) { + case types::five_gc: + c.destroy(); + break; + case types::epc: + c.destroy(); + break; + default: + break; + } +} +void core_cpid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::five_gc: + c.init(); + break; + case types::epc: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c::core_cpid_c(const core_cpid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c& core_cpid_c::operator=(const core_cpid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + + return *this; +} +guami_s& core_cpid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +gummei_s& core_cpid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void core_cpid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_fieldname("fiveGC"); + c.get().to_json(j); + break; + case types::epc: + j.write_fieldname("ePC"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + j.end_obj(); +} +SRSASN_CODE core_cpid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE core_cpid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* core_cpid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "core_cpid_c::types"); +} +uint8_t core_cpid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "core_cpid_c::types"); +} + +// ENB-ID ::= CHOICE +void enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_enb_id: + c.destroy >(); + break; + case types::home_enb_id: + c.destroy >(); + break; + case types::short_macro_enb_id: + c.destroy >(); + break; + case types::long_macro_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_enb_id: + c.init >(); + break; + case types::home_enb_id: + c.init >(); + break; + case types::short_macro_enb_id: + c.init >(); + break; + case types::long_macro_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c::enb_id_c(const enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_enb_id: + c.init(other.c.get >()); + break; + case types::home_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c& enb_id_c::operator=(const enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_enb_id: + c.set(other.c.get >()); + break; + case types::home_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_c::set_macro_enb_id() +{ + set(types::macro_enb_id); + return c.get >(); +} +fixed_bitstring<28, false, true>& enb_id_c::set_home_enb_id() +{ + set(types::home_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_c::set_short_macro_enb_id() +{ + set(types::short_macro_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_c::set_long_macro_enb_id() +{ + set(types::long_macro_enb_id); + return c.get >(); +} +void enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_enb_id: + j.write_str("macro-eNB-ID", c.get >().to_string()); + break; + case types::home_enb_id: + j.write_str("home-eNB-ID", c.get >().to_string()); + break; + case types::short_macro_enb_id: + j.write_str("short-Macro-eNB-ID", c.get >().to_string()); + break; + case types::long_macro_enb_id: + j.write_str("long-Macro-eNB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macro-eNB-ID", "home-eNB-ID", "short-Macro-eNB-ID", "long-Macro-eNB-ID"}; + return convert_enum_idx(options, 4, value, "enb_id_c::types"); +} + +// GlobalENB-ID ::= SEQUENCE +SRSASN_CODE global_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("eNB-ID"); + enb_id.to_json(j); + j.end_obj(); +} + +// GNB-ID ::= CHOICE +void gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB-ID"}; + return convert_enum_idx(options, 1, value, "gnb_id_c::types"); +} + +// GlobalGNB-ID ::= SEQUENCE +SRSASN_CODE global_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("gNB-ID"); + gnb_id.to_json(j); + j.end_obj(); +} + +// NgENB-ID ::= CHOICE +void ng_enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_ng_enb_id: + c.destroy >(); + break; + case types::short_macro_ng_enb_id: + c.destroy >(); + break; + case types::long_macro_ng_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void ng_enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_ng_enb_id: + c.init >(); + break; + case types::short_macro_ng_enb_id: + c.init >(); + break; + case types::long_macro_ng_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c::ng_enb_id_c(const ng_enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c& ng_enb_id_c::operator=(const ng_enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& ng_enb_id_c::set_macro_ng_enb_id() +{ + set(types::macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& ng_enb_id_c::set_short_macro_ng_enb_id() +{ + set(types::short_macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& ng_enb_id_c::set_long_macro_ng_enb_id() +{ + set(types::long_macro_ng_enb_id); + return c.get >(); +} +void ng_enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_ng_enb_id: + j.write_str("macroNgENB-ID", c.get >().to_string()); + break; + case types::short_macro_ng_enb_id: + j.write_str("shortMacroNgENB-ID", c.get >().to_string()); + break; + case types::long_macro_ng_enb_id: + j.write_str("longMacroNgENB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE ng_enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ng_enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ng_enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macroNgENB-ID", "shortMacroNgENB-ID", "longMacroNgENB-ID"}; + return convert_enum_idx(options, 3, value, "ng_enb_id_c::types"); +} + +// GlobalNgENB-ID ::= SEQUENCE +SRSASN_CODE global_ng_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(ng_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ng_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(ng_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_ng_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("ngENB-ID"); + ng_enb_id.to_json(j); + j.end_obj(); +} + +// GlobalRANNodeID ::= CHOICE +void global_ran_node_id_c::destroy_() +{ + switch (type_) { + case types::global_gnb_id: + c.destroy(); + break; + case types::global_ng_enb_id: + c.destroy(); + break; + default: + break; + } +} +void global_ran_node_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_gnb_id: + c.init(); + break; + case types::global_ng_enb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c::global_ran_node_id_c(const global_ran_node_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_gnb_id: + c.init(other.c.get()); + break; + case types::global_ng_enb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c& global_ran_node_id_c::operator=(const global_ran_node_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_gnb_id: + c.set(other.c.get()); + break; + case types::global_ng_enb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + + return *this; +} +global_gnb_id_s& global_ran_node_id_c::set_global_gnb_id() +{ + set(types::global_gnb_id); + return c.get(); +} +global_ng_enb_id_s& global_ran_node_id_c::set_global_ng_enb_id() +{ + set(types::global_ng_enb_id); + return c.get(); +} +void global_ran_node_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_gnb_id: + j.write_fieldname("globalGNB-ID"); + c.get().to_json(j); + break; + case types::global_ng_enb_id: + j.write_fieldname("globalNgENB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_ran_node_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ran_node_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_ran_node_id_c::types_opts::to_string() const +{ + static const char* options[] = {"globalGNB-ID", "globalNgENB-ID"}; + return convert_enum_idx(options, 2, value, "global_ran_node_id_c::types"); +} + +// EN-GNB-ID ::= CHOICE +void en_gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("en-gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE en_gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE en_gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "en_gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* en_gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"en-gNB-ID"}; + return convert_enum_idx(options, 1, value, "en_gnb_id_c::types"); +} + +// GlobalenGNB-ID ::= SEQUENCE +SRSASN_CODE globalen_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(en_g_nb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalen_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(en_g_nb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalen_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("en-gNB-ID"); + en_g_nb_id.to_json(j); + j.end_obj(); +} + +// GroupID ::= CHOICE +void group_id_c::destroy_() {} +void group_id_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +group_id_c::group_id_c(const group_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } +} +group_id_c& group_id_c::operator=(const group_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + + return *this; +} +uint16_t& group_id_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& group_id_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void group_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + j.end_obj(); +} +SRSASN_CODE group_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE group_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* group_id_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "group_id_c::types"); +} +uint8_t group_id_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "group_id_c::types"); +} + +// InterfaceID-E1 ::= SEQUENCE +SRSASN_CODE interface_id_e1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_e1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_e1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-CU-UP-ID", gnb_cu_up_id); + j.end_obj(); +} + +// InterfaceID-F1 ::= SEQUENCE +SRSASN_CODE interface_id_f1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_f1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_f1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-DU-ID", gnb_du_id); + j.end_obj(); +} + +// InterfaceID-NG ::= SEQUENCE +SRSASN_CODE interface_id_ng_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(guami.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_ng_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(guami.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_ng_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("guami"); + guami.to_json(j); + j.end_obj(); +} + +// InterfaceID-S1 ::= SEQUENCE +SRSASN_CODE interface_id_s1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(gummei.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_s1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(gummei.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_s1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + j.end_obj(); +} + +// InterfaceID-W1 ::= SEQUENCE +SRSASN_CODE interface_id_w1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_enb_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, ng_enb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_w1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + HANDLE_CODE(unpack_integer(ng_enb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_w1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-ng-eNB-ID"); + global_ng_enb_id.to_json(j); + j.write_int("ng-eNB-DU-ID", ng_enb_du_id); + j.end_obj(); +} + +// InterfaceID-X2 ::= SEQUENCE +SRSASN_CODE interface_id_x2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(node_type.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(node_type.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_x2_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("nodeType"); + node_type.to_json(j); + j.end_obj(); +} + +void interface_id_x2_s::node_type_c_::destroy_() +{ + switch (type_) { + case types::global_enb_id: + c.destroy(); + break; + case types::global_en_g_nb_id: + c.destroy(); + break; + default: + break; + } +} +void interface_id_x2_s::node_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_enb_id: + c.init(); + break; + case types::global_en_g_nb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_::node_type_c_(const interface_id_x2_s::node_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_enb_id: + c.init(other.c.get()); + break; + case types::global_en_g_nb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_& +interface_id_x2_s::node_type_c_::operator=(const interface_id_x2_s::node_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_enb_id: + c.set(other.c.get()); + break; + case types::global_en_g_nb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + + return *this; +} +global_enb_id_s& interface_id_x2_s::node_type_c_::set_global_enb_id() +{ + set(types::global_enb_id); + return c.get(); +} +globalen_gnb_id_s& interface_id_x2_s::node_type_c_::set_global_en_g_nb_id() +{ + set(types::global_en_g_nb_id); + return c.get(); +} +void interface_id_x2_s::node_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_enb_id: + j.write_fieldname("global-eNB-ID"); + c.get().to_json(j); + break; + case types::global_en_g_nb_id: + j.write_fieldname("global-en-gNB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_x2_s::node_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::node_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_x2_s::node_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"global-eNB-ID", "global-en-gNB-ID"}; + return convert_enum_idx(options, 2, value, "interface_id_x2_s::node_type_c_::types"); +} + +// InterfaceID-Xn ::= SEQUENCE +SRSASN_CODE interface_id_xn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_xn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_xn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.end_obj(); +} + +// InterfaceIdentifier ::= CHOICE +void interface_id_c::destroy_() +{ + switch (type_) { + case types::ng: + c.destroy(); + break; + case types::xn: + c.destroy(); + break; + case types::f1: + c.destroy(); + break; + case types::e1: + c.destroy(); + break; + case types::s1: + c.destroy(); + break; + case types::x2: + c.destroy(); + break; + case types::w1: + c.destroy(); + break; + default: + break; + } +} +void interface_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ng: + c.init(); + break; + case types::xn: + c.init(); + break; + case types::f1: + c.init(); + break; + case types::e1: + c.init(); + break; + case types::s1: + c.init(); + break; + case types::x2: + c.init(); + break; + case types::w1: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c::interface_id_c(const interface_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ng: + c.init(other.c.get()); + break; + case types::xn: + c.init(other.c.get()); + break; + case types::f1: + c.init(other.c.get()); + break; + case types::e1: + c.init(other.c.get()); + break; + case types::s1: + c.init(other.c.get()); + break; + case types::x2: + c.init(other.c.get()); + break; + case types::w1: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c& interface_id_c::operator=(const interface_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ng: + c.set(other.c.get()); + break; + case types::xn: + c.set(other.c.get()); + break; + case types::f1: + c.set(other.c.get()); + break; + case types::e1: + c.set(other.c.get()); + break; + case types::s1: + c.set(other.c.get()); + break; + case types::x2: + c.set(other.c.get()); + break; + case types::w1: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + + return *this; +} +interface_id_ng_s& interface_id_c::set_ng() +{ + set(types::ng); + return c.get(); +} +interface_id_xn_s& interface_id_c::set_xn() +{ + set(types::xn); + return c.get(); +} +interface_id_f1_s& interface_id_c::set_f1() +{ + set(types::f1); + return c.get(); +} +interface_id_e1_s& interface_id_c::set_e1() +{ + set(types::e1); + return c.get(); +} +interface_id_s1_s& interface_id_c::set_s1() +{ + set(types::s1); + return c.get(); +} +interface_id_x2_s& interface_id_c::set_x2() +{ + set(types::x2); + return c.get(); +} +interface_id_w1_s& interface_id_c::set_w1() +{ + set(types::w1); + return c.get(); +} +void interface_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ng: + j.write_fieldname("nG"); + c.get().to_json(j); + break; + case types::xn: + j.write_fieldname("xN"); + c.get().to_json(j); + break; + case types::f1: + j.write_fieldname("f1"); + c.get().to_json(j); + break; + case types::e1: + j.write_fieldname("e1"); + c.get().to_json(j); + break; + case types::s1: + j.write_fieldname("s1"); + c.get().to_json(j); + break; + case types::x2: + j.write_fieldname("x2"); + c.get().to_json(j); + break; + case types::w1: + j.write_fieldname("w1"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_c::types_opts::to_string() const +{ + static const char* options[] = {"nG", "xN", "f1", "e1", "s1", "x2", "w1"}; + return convert_enum_idx(options, 7, value, "interface_id_c::types"); +} + +// FreqBandNrItem ::= SEQUENCE +SRSASN_CODE freq_band_nr_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, freq_band_ind_nr, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE freq_band_nr_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(freq_band_ind_nr, bref, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +void freq_band_nr_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("freqBandIndicatorNr", freq_band_ind_nr); + j.end_obj(); +} + +// NR-ARFCN ::= SEQUENCE +SRSASN_CODE nr_arfcn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, nrarfcn, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list_nr, 1, 32, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_arfcn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(nrarfcn, bref, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(unpack_dyn_seq_of(freq_band_list_nr, bref, 1, 32, true)); + + return SRSASN_SUCCESS; +} +void nr_arfcn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("nRARFCN", nrarfcn); + j.start_array("freqBandListNr"); + for (const auto& e1 : freq_band_list_nr) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// QoSID ::= CHOICE +void qo_sid_c::destroy_() {} +void qo_sid_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +qo_sid_c::qo_sid_c(const qo_sid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } +} +qo_sid_c& qo_sid_c::operator=(const qo_sid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + + return *this; +} +uint16_t& qo_sid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& qo_sid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void qo_sid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + j.end_obj(); +} +SRSASN_CODE qo_sid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE qo_sid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* qo_sid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "qo_sid_c::types"); +} +uint8_t qo_sid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "qo_sid_c::types"); +} + +// RRCclass-LTE ::= ENUMERATED +const char* rr_cclass_lte_opts::to_string() const +{ + static const char* options[] = {"bCCH-BCH", + "bCCH-BCH-MBMS", + "bCCH-DL-SCH", + "bCCH-DL-SCH-BR", + "bCCH-DL-SCH-MBMS", + "mCCH", + "pCCH", + "dL-CCCH", + "dL-DCCH", + "uL-CCCH", + "uL-DCCH", + "sC-MCCH"}; + return convert_enum_idx(options, 12, value, "rr_cclass_lte_e"); +} + +// RRCclass-NR ::= ENUMERATED +const char* rr_cclass_nr_opts::to_string() const +{ + static const char* options[] = { + "bCCH-BCH", "bCCH-DL-SCH", "dL-CCCH", "dL-DCCH", "pCCH", "uL-CCCH", "uL-CCCH1", "uL-DCCH"}; + return convert_enum_idx(options, 8, value, "rr_cclass_nr_e"); +} +uint8_t rr_cclass_nr_opts::to_number() const +{ + if (value == ul_ccch1) { + return 1; + } + invalid_enum_number(value, "rr_cclass_nr_e"); + return 0; +} + +// RRC-MessageID ::= SEQUENCE +SRSASN_CODE rrc_msg_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(rrc_type.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, msg_id, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(rrc_type.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(msg_id, bref, false, true)); + + return SRSASN_SUCCESS; +} +void rrc_msg_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("rrcType"); + rrc_type.to_json(j); + j.write_int("messageID", msg_id); + j.end_obj(); +} + +void rrc_msg_id_s::rrc_type_c_::destroy_() {} +void rrc_msg_id_s::rrc_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +rrc_msg_id_s::rrc_type_c_::rrc_type_c_(const rrc_msg_id_s::rrc_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::lte: + c.init(other.c.get()); + break; + case types::nr: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } +} +rrc_msg_id_s::rrc_type_c_& rrc_msg_id_s::rrc_type_c_::operator=(const rrc_msg_id_s::rrc_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::lte: + c.set(other.c.get()); + break; + case types::nr: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + + return *this; +} +rr_cclass_lte_e& rrc_msg_id_s::rrc_type_c_::set_lte() +{ + set(types::lte); + return c.get(); +} +rr_cclass_nr_e& rrc_msg_id_s::rrc_type_c_::set_nr() +{ + set(types::nr); + return c.get(); +} +void rrc_msg_id_s::rrc_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::lte: + j.write_str("lTE", c.get().to_string()); + break; + case types::nr: + j.write_str("nR", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_msg_id_s::rrc_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"lTE", "nR"}; + return convert_enum_idx(options, 2, value, "rrc_msg_id_s::rrc_type_c_::types"); +} + +// S-NSSAI ::= SEQUENCE +SRSASN_CODE s_nssai_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(sd_present, 1)); + + HANDLE_CODE(sst.pack(bref)); + if (sd_present) { + HANDLE_CODE(sd.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE s_nssai_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(sd_present, 1)); + + HANDLE_CODE(sst.unpack(bref)); + if (sd_present) { + HANDLE_CODE(sd.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void s_nssai_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("sST", sst.to_string()); + if (sd_present) { + j.write_str("sD", sd.to_string()); + } + j.end_obj(); +} + +// ServingCell-ARFCN ::= CHOICE +void serving_cell_arfcn_c::destroy_() +{ + switch (type_) { + case types::nr: + c.destroy(); + break; + default: + break; + } +} +void serving_cell_arfcn_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr: + c.init(); + break; + case types::eutra: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c::serving_cell_arfcn_c(const serving_cell_arfcn_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c& serving_cell_arfcn_c::operator=(const serving_cell_arfcn_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + + return *this; +} +nr_arfcn_s& serving_cell_arfcn_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint32_t& serving_cell_arfcn_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_arfcn_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_fieldname("nR"); + c.get().to_json(j); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_arfcn_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_arfcn_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_arfcn_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_arfcn_c::types"); +} + +// ServingCell-PCI ::= CHOICE +void serving_cell_pci_c::destroy_() {} +void serving_cell_pci_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +serving_cell_pci_c::serving_cell_pci_c(const serving_cell_pci_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } +} +serving_cell_pci_c& serving_cell_pci_c::operator=(const serving_cell_pci_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + + return *this; +} +uint16_t& serving_cell_pci_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint16_t& serving_cell_pci_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_pci_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_int("nR", c.get()); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_pci_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_pci_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_pci_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_pci_c::types"); +} + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_e1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + j.end_obj(); +} + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_f1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + j.end_obj(); +} + +// UEID-EN-GNB ::= SEQUENCE +SRSASN_CODE ueid_en_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.pack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_en_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_en_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + if (gnb_cu_ue_f1_ap_id_present) { + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-ENB ::= SEQUENCE +SRSASN_CODE ueid_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(global_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, mme_ue_s1ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.pack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(global_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(mme_ue_s1ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.unpack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("mME-UE-S1AP-ID", mme_ue_s1ap_id); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + if (m_enb_ue_x2ap_id_present) { + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + } + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + if (global_enb_id_present) { + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB ::= SEQUENCE +SRSASN_CODE ueid_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_gnb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_ue_f1_ap_id_list, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool gnb_cu_ue_f1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_list_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_gnb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_ue_f1_ap_id_list, bref, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-UE-F1AP-ID-List"); + for (const auto& e1 : gnb_cu_ue_f1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_gnb_id_present) { + j.write_fieldname("globalGNB-ID"); + global_gnb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB-CU-UP ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_up_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_up_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_up_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-GNB-DU ::= SEQUENCE +SRSASN_CODE ueid_gnb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-NG-ENB ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (ng_enb_cu_ue_w1_ap_id_present) { + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_ng_enb_id_present) { + j.write_fieldname("globalNgENB-ID"); + global_ng_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-NG-ENB-DU ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + j.end_obj(); +} + +// UEID ::= CHOICE +void ueid_c::destroy_() +{ + switch (type_) { + case types::gnb_ueid: + c.destroy(); + break; + case types::gnb_du_ueid: + c.destroy(); + break; + case types::gnb_cu_up_ueid: + c.destroy(); + break; + case types::ng_enb_ueid: + c.destroy(); + break; + case types::ng_enb_du_ueid: + c.destroy(); + break; + case types::en_g_nb_ueid: + c.destroy(); + break; + case types::enb_ueid: + c.destroy(); + break; + default: + break; + } +} +void ueid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb_ueid: + c.init(); + break; + case types::gnb_du_ueid: + c.init(); + break; + case types::gnb_cu_up_ueid: + c.init(); + break; + case types::ng_enb_ueid: + c.init(); + break; + case types::ng_enb_du_ueid: + c.init(); + break; + case types::en_g_nb_ueid: + c.init(); + break; + case types::enb_ueid: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c::ueid_c(const ueid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb_ueid: + c.init(other.c.get()); + break; + case types::gnb_du_ueid: + c.init(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.init(other.c.get()); + break; + case types::en_g_nb_ueid: + c.init(other.c.get()); + break; + case types::enb_ueid: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c& ueid_c::operator=(const ueid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb_ueid: + c.set(other.c.get()); + break; + case types::gnb_du_ueid: + c.set(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.set(other.c.get()); + break; + case types::en_g_nb_ueid: + c.set(other.c.get()); + break; + case types::enb_ueid: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + + return *this; +} +ueid_gnb_s& ueid_c::set_gnb_ueid() +{ + set(types::gnb_ueid); + return c.get(); +} +ueid_gnb_du_s& ueid_c::set_gnb_du_ueid() +{ + set(types::gnb_du_ueid); + return c.get(); +} +ueid_gnb_cu_up_s& ueid_c::set_gnb_cu_up_ueid() +{ + set(types::gnb_cu_up_ueid); + return c.get(); +} +ueid_ng_enb_s& ueid_c::set_ng_enb_ueid() +{ + set(types::ng_enb_ueid); + return c.get(); +} +ueid_ng_enb_du_s& ueid_c::set_ng_enb_du_ueid() +{ + set(types::ng_enb_du_ueid); + return c.get(); +} +ueid_en_gnb_s& ueid_c::set_en_g_nb_ueid() +{ + set(types::en_g_nb_ueid); + return c.get(); +} +ueid_enb_s& ueid_c::set_enb_ueid() +{ + set(types::enb_ueid); + return c.get(); +} +void ueid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb_ueid: + j.write_fieldname("gNB-UEID"); + c.get().to_json(j); + break; + case types::gnb_du_ueid: + j.write_fieldname("gNB-DU-UEID"); + c.get().to_json(j); + break; + case types::gnb_cu_up_ueid: + j.write_fieldname("gNB-CU-UP-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_ueid: + j.write_fieldname("ng-eNB-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_du_ueid: + j.write_fieldname("ng-eNB-DU-UEID"); + c.get().to_json(j); + break; + case types::en_g_nb_ueid: + j.write_fieldname("en-gNB-UEID"); + c.get().to_json(j); + break; + case types::enb_ueid: + j.write_fieldname("eNB-UEID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + j.end_obj(); +} +SRSASN_CODE ueid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ueid_c::types_opts::to_string() const +{ + static const char* options[] = { + "gNB-UEID", "gNB-DU-UEID", "gNB-CU-UP-UEID", "ng-eNB-UEID", "ng-eNB-DU-UEID", "en-gNB-UEID", "eNB-UEID"}; + return convert_enum_idx(options, 7, value, "ueid_c::types"); +} diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 3bc690713..3c42bb44c 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -33,6 +33,7 @@ #include "srsenb/hdr/stack/mac/sched_interface.h" #include "srsgnb/hdr/stack/gnb_stack_nr.h" +#include "srsgnb/hdr/stack/ric/ric_client.h" #include "srsran/common/bcd_helpers.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/interfaces_common.h" @@ -169,6 +170,7 @@ private: std::unique_ptr nr_stack = nullptr; std::unique_ptr radio = nullptr; std::unique_ptr phy = nullptr; + std::unique_ptr ric = nullptr; // System metrics processor. srsran::sys_metrics_processor sys_proc; diff --git a/srsenb/src/CMakeLists.txt b/srsenb/src/CMakeLists.txt index 8c92d1b67..b994c3c96 100644 --- a/srsenb/src/CMakeLists.txt +++ b/srsenb/src/CMakeLists.txt @@ -29,8 +29,8 @@ add_executable(srsenb main.cc enb.cc metrics_stdout.cc metrics_csv.cc metrics_js set(SRSENB_SOURCES srsenb_phy srsenb_stack srsenb_common srsenb_s1ap srsenb_upper srsenb_mac srsenb_rrc srslog system) set(SRSRAN_SOURCES srsran_common srsran_mac srsran_phy srsran_gtpu srsran_rlc srsran_pdcp srsran_radio rrc_asn1 s1ap_asn1 enb_cfg_parser srslog support system) -set(SRSENB_SOURCES ${SRSENB_SOURCES} srsgnb_stack srsgnb_ngap srsgnb_mac srsgnb_rrc) -set(SRSRAN_SOURCES ${SRSRAN_SOURCES} rrc_nr_asn1 ngap_nr_asn1) +set(SRSENB_SOURCES ${SRSENB_SOURCES} srsgnb_stack srsgnb_ric srsgnb_ngap srsgnb_mac srsgnb_rrc) +set(SRSRAN_SOURCES ${SRSRAN_SOURCES} rrc_nr_asn1 ngap_nr_asn1 ric_e2) target_link_libraries(srsenb ${SRSENB_SOURCES} ${SRSRAN_SOURCES} diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 5b1a8c5ae..f8130ba3e 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -118,6 +118,15 @@ int enb::init(const all_args_t& args_) ret = SRSRAN_ERROR; } } + std::unique_ptr tmp_ric_client = std::unique_ptr(new srsenb::ric_client()); + if (tmp_ric_client == nullptr) { + srsran::console("Error creating RIC client instance.\n"); + return SRSRAN_ERROR; + } + if (tmp_ric_client->init()) { + srsran::console("Error initializing RIC client.\n"); + return SRSRAN_ERROR; + } if (tmp_eutra_stack) { eutra_stack = std::move(tmp_eutra_stack); @@ -127,7 +136,7 @@ int enb::init(const all_args_t& args_) } phy = std::move(tmp_phy); radio = std::move(tmp_radio); - + ric = std::move(tmp_ric_client); started = true; // set to true in any case to allow stopping the eNB if an error happened // Now that everything is setup, log sector start events. diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h new file mode 100644 index 000000000..5e2d97194 --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -0,0 +1,36 @@ +/** + * + * \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/asn1/e2ap.h" +#include "srsran/srsran.h" + +#ifndef RIC_E2AP_H +#define RIC_E2AP_H + +using namespace asn1::e2ap; + +class e2ap +{ +public: + e2_ap_pdu_c generate_setup_request(); + int process_setup_response(); + int process_setup_failure(); + int process_subscription_request(); + int generate_subscription_response(); + int generate_subscription_failure(); + int generate_indication(); + +private: +}; + +#endif /* RIC_E2AP_H */ diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h new file mode 100644 index 000000000..a0ac9e731 --- /dev/null +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -0,0 +1,42 @@ +/** + * + * \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. + * + * + */ + +#ifndef RIC_CLIENT_H +#define RIC_CLIENT_H + +#include "srsgnb/hdr/stack/ric/e2ap.h" +#include "srsran/common/network_utils.h" +#include "srsran/common/threads.h" +#include "srsran/srsran.h" +static const int e2ap_ppid = 70; +static const int e2ap_port = 36422; +namespace srsenb { +class ric_client : public srsran::thread +{ +public: + ric_client(); + bool init(); + void stop(); + void run_thread(); + bool send_sctp(srsran::unique_byte_buffer_t& buf); + bool send_e2_setup_request(); + +private: + e2ap e2ap_; + srsran::unique_socket ric_socket; + struct sockaddr_in ric_addr = {}; // RIC address + bool running = false; +}; +} // namespace srsenb + +#endif /* RIC_CLIENT_H */ diff --git a/srsgnb/src/stack/CMakeLists.txt b/srsgnb/src/stack/CMakeLists.txt index 369888e94..cdf0d97ea 100644 --- a/srsgnb/src/stack/CMakeLists.txt +++ b/srsgnb/src/stack/CMakeLists.txt @@ -10,6 +10,7 @@ include_directories(${PROJECT_SOURCE_DIR}) add_subdirectory(mac) add_subdirectory(ngap) +add_subdirectory(ric) add_subdirectory(rrc) add_subdirectory(sdap) diff --git a/srsgnb/src/stack/ric/CMakeLists.txt b/srsgnb/src/stack/ric/CMakeLists.txt new file mode 100644 index 000000000..651b588fc --- /dev/null +++ b/srsgnb/src/stack/ric/CMakeLists.txt @@ -0,0 +1,5 @@ +set(SOURCES ric_client.cc e2ap.cc) +add_library(srsgnb_ric STATIC ${SOURCES}) +#target_link_libraries(srsgnb_ric srsran_asn1) + +add_subdirectory(test) diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc new file mode 100644 index 000000000..1252f71aa --- /dev/null +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -0,0 +1,53 @@ + +#include "srsgnb/hdr/stack/ric/e2ap.h" +#include "stdint.h" + +e2_ap_pdu_c e2ap::generate_setup_request() +{ + e2_ap_pdu_c pdu; + init_msg_s& initmsg = pdu.set_init_msg(); + initmsg.load_info_obj(ASN1_E2AP_ID_E2SETUP); + + e2setup_request_s& setup = initmsg.value.e2setup_request(); + + setup->transaction_id.crit = asn1::crit_opts::reject; + setup->transaction_id.value.value = 1; + + setup->global_e2node_id.crit = asn1::crit_opts::reject; + auto& gnb_id = setup->global_e2node_id.value.set_gnb(); + // gnb_id.ext = true; + gnb_id.global_g_nb_id.plmn_id.from_number(3617847); + gnb_id.global_g_nb_id.gnb_id.gnb_id().from_number(381210353); + + setup->ra_nfunctions_added.crit = asn1::crit_opts::reject; + auto& list = setup->ra_nfunctions_added.value; + + 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 = 0; + // TODO use E2SM to correctly generate this message + item.value().ra_nfunction_item().ran_function_definition.from_string( + "20C04F52414E2D4532534D2D4B504D0000054F494431323305004B504D206D6F6E69746F720860283861AAE33F0060000101070050657269" + "6F646963207265706F727401051401011D004F2D4455204D6561737572656D656E7420436F6E7461696E657220666F722074686520354743" + "20636F6E6E6563746564206465706C6F796D656E74010101010001021D004F2D4455204D6561737572656D656E7420436F6E7461696E6572" + "20666F72207468652045504320636F6E6E6563746564206465706C6F796D656E74010101010001031E804F2D43552D4350204D6561737572" + "656D656E7420436F6E7461696E657220666F72207468652035474320636F6E6E6563746564206465706C6F796D656E74010101010001041E" + "804F2D43552D4350204D6561737572656D656E7420436F6E7461696E657220666F72207468652045504320636F6E6E656374656420646570" + "6C6F796D656E74010101010001051E804F2D43552D5550204D6561737572656D656E7420436F6E7461696E657220666F7220746865203547" + "4320636F6E6E6563746564206465706C6F796D656E74010101010001061E804F2D43552D5550204D6561737572656D656E7420436F6E7461" + "696E657220666F72207468652045504320636F6E6E6563746564206465706C6F796D656E7401010101"); + item.value().ra_nfunction_item().ran_function_oid.resize(1); + 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"); + item1.e2node_component_cfg.e2node_component_request_part.from_string("72657170617274"); + item1.e2node_component_cfg.e2node_component_resp_part.from_string("72657370617274"); + return pdu; +} diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc new file mode 100644 index 000000000..6e150551e --- /dev/null +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -0,0 +1,105 @@ +/** + * + * \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 "srsgnb/hdr/stack/ric/ric_client.h" +#include "srsran/asn1/e2ap.h" +#include "stdint.h" + +using namespace srsenb; +ric_client::ric_client() : thread("RIC_CLIENT_THREAD") {} +bool ric_client::init() +{ + printf("RIC_CLIENT: Init\n"); + using namespace srsran::net_utils; + // Open SCTP socket + if (not ric_socket.open_socket(addr_family::ipv4, socket_type::seqpacket, protocol_type::SCTP)) { + return false; + } + printf("RIC SCTP socket opened. fd=%d\n", ric_socket.fd()); + if (not ric_socket.sctp_subscribe_to_events()) { + ric_socket.close(); + return false; + } + + // Bind socket + + if (not ric_socket.bind_addr("172.17.0.3", 36422)) { + ric_socket.close(); + return false; + } + + // Connect to the AMF address + if (not ric_socket.connect_to("10.104.149.217", e2ap_port, &ric_addr)) { + return false; + } + printf("SCTP socket connected with RIC. fd=%d", ric_socket.fd()); + running = true; + start(0); + + return SRSRAN_SUCCESS; +} +void ric_client::stop() +{ + running = false; + wait_thread_finish(); +} +void ric_client::run_thread() +{ + while (running) { + send_e2_setup_request(); + printf("e2 setup request sent\n"); + sleep(5); + } +} +bool ric_client::send_sctp(srsran::unique_byte_buffer_t& buf) +{ + ssize_t ret; + ret = sctp_sendmsg(ric_socket.fd(), + buf->msg, + buf->N_bytes, + (struct sockaddr*)&ric_addr, + sizeof(ric_addr), + htonl(e2ap_ppid), + 0, + 0, + 0, + 0); + if (ret == -1) { + printf("failed to send %d bytes\n", buf->N_bytes); + return false; + } + return true; +} + +bool ric_client::send_e2_setup_request() +{ + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + if (buf == nullptr) { + // logger.error("Fatal Error: Couldn't allocate buffer for %s.", procedure_name); + return false; + } + + e2_ap_pdu_c setup_req_pdu = e2ap_.generate_setup_request(); + + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (setup_req_pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("Failed to pack TX E2 PDU\n"); + return false; + } + buf->N_bytes = bref.distance_bytes(); + printf("try to send %d bytes to addr %s \n", buf->N_bytes, inet_ntoa(ric_addr.sin_addr)); + if (!send_sctp(buf)) { + printf("failed to send e2 setup request\n"); + return false; + } + return true; +} diff --git a/srsgnb/src/stack/ric/test/CMakeLists.txt b/srsgnb/src/stack/ric/test/CMakeLists.txt new file mode 100644 index 000000000..a29d444f0 --- /dev/null +++ b/srsgnb/src/stack/ric/test/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# 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. +# + +add_executable(e2ap_test e2ap_test.cc) +target_link_libraries(e2ap_test srsran_common ric_e2 srsgnb_ric srsenb_upper srsgnb_stack ${SCTP_LIBRARIES}) + +add_test(e2ap_test e2ap_test) \ No newline at end of file diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc new file mode 100644 index 000000000..4a0835650 --- /dev/null +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -0,0 +1,106 @@ +#include "srsgnb/hdr/stack/ric/e2ap.h" +#include "srsran/asn1/e2ap.h" +#include "srsran/common/test_common.h" +#include "srsran/srsran.h" + +// function to test the encoding of the E2AP message +void test_reference_e2ap_setup_request() +{ + uint8_t e2ap_msg_foreign[] = { + 0x00, 0x01, 0x00, 0x82, 0x40, 0x00, 0x00, 0x04, 0x00, 0x31, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x09, 0x00, + 0x37, 0x34, 0x37, 0x38, 0xb5, 0xc6, 0x77, 0x88, 0x00, 0x0a, 0x00, 0x81, 0xff, 0x00, 0x00, 0x08, 0x00, 0x81, 0xf9, + 0x00, 0x00, 0x00, 0x81, 0xe9, 0x20, 0xc0, 0x4f, 0x52, 0x41, 0x4e, 0x2d, 0x45, 0x32, 0x53, 0x4d, 0x2d, 0x4b, 0x50, + 0x4d, 0x00, 0x00, 0x05, 0x4f, 0x49, 0x44, 0x31, 0x32, 0x33, 0x05, 0x00, 0x4b, 0x50, 0x4d, 0x20, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x08, 0xdc, 0x2b, 0xda, 0xe3, 0xae, 0xd1, 0x4d, 0x00, 0x60, 0x00, 0x01, 0x01, 0x07, 0x00, + 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x01, 0x05, 0x14, 0x01, + 0x01, 0x1d, 0x00, 0x4f, 0x2d, 0x44, 0x55, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x35, 0x47, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x1d, 0x00, 0x4f, 0x2d, 0x44, 0x55, 0x20, + 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x01, 0x03, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x43, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x35, 0x47, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x04, 0x1e, + 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x43, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, + 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x05, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, + 0x2d, 0x55, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x35, 0x47, 0x43, 0x20, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x06, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x55, 0x50, 0x20, 0x4d, + 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x02, 0x00, 0x00, 0x05, 0x4f, 0x49, 0x44, 0x31, 0x32, 0x33, 0x00, 0x32, 0x00, 0x22, 0x00, 0x00, 0x00, 0x33, + 0x00, 0x1c, 0x00, 0x00, 0xe0, 0x6e, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x00, 0x07, 0x72, 0x65, 0x71, 0x70, + 0x61, 0x72, 0x74, 0x07, 0x72, 0x65, 0x73, 0x70, 0x61, 0x72, 0x74}; + uint8_t e2ap_msg_self[] = { + 0x00, 0x01, 0x00, 0x82, 0x3c, 0x00, 0x00, 0x04, 0x00, 0x31, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x09, 0x00, + 0x37, 0x34, 0x37, 0x38, 0xb5, 0xc6, 0x77, 0x88, 0x00, 0x0a, 0x00, 0x81, 0xfa, 0x00, 0x00, 0x08, 0x00, 0x81, 0xf4, + 0x00, 0x00, 0x00, 0x81, 0xe9, 0x20, 0xc0, 0x4f, 0x52, 0x41, 0x4e, 0x2d, 0x45, 0x32, 0x53, 0x4d, 0x2d, 0x4b, 0x50, + 0x4d, 0x00, 0x00, 0x05, 0x4f, 0x49, 0x44, 0x31, 0x32, 0x33, 0x05, 0x00, 0x4b, 0x50, 0x4d, 0x20, 0x6d, 0x6f, 0x6e, + 0x69, 0x74, 0x6f, 0x72, 0x08, 0x60, 0x28, 0x38, 0x61, 0xaa, 0xe3, 0x3f, 0x00, 0x60, 0x00, 0x01, 0x01, 0x07, 0x00, + 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x01, 0x05, 0x14, 0x01, + 0x01, 0x1d, 0x00, 0x4f, 0x2d, 0x44, 0x55, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x35, 0x47, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x1d, 0x00, 0x4f, 0x2d, 0x44, 0x55, 0x20, + 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x01, 0x03, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x43, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x35, 0x47, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x04, 0x1e, + 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x43, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, + 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x05, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, + 0x2d, 0x55, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x35, 0x47, 0x43, 0x20, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x06, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x55, 0x50, 0x20, 0x4d, + 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x23, 0x00, 0x00, 0x00, 0x33, 0x00, 0x1d, 0x00, 0x00, 0x03, + 0x80, 0x6e, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x00, 0x07, 0x72, 0x65, 0x71, 0x70, 0x61, 0x72, 0x74, 0x07, + 0x72, 0x65, 0x73, 0x70, 0x61, 0x72, 0x74}; + + asn1::cbit_ref bref(&e2ap_msg_foreign[0], sizeof(e2ap_msg_foreign)); + e2_ap_pdu_c pdu, pdu2; + asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked E2AP PDU %d\n", (int)unpack_ret); +} + +void test_native_e2ap_setup_request() +{ + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + e2_ap_pdu_c pdu, pdu2; + e2ap e2ap_; + pdu = e2ap_.generate_setup_request(); + + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("Failed to pack TX E2 PDU\n"); + return; + } + + asn1::cbit_ref bref2(buf->msg, buf->get_tailroom()); + + asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked native E2AP PDU %d\n", (int)unpack_ret); +} + +int main() +{ + test_reference_e2ap_setup_request(); + test_native_e2ap_setup_request(); + return 0; +} \ No newline at end of file From 93202d152ae8a7c03854e0aa5f0faded99bf8b69 Mon Sep 17 00:00:00 2001 From: yagoda Date: Mon, 14 Nov 2022 20:07:18 +0100 Subject: [PATCH 007/167] e2ap, asn1: removing extra byte alignment from packing/unpacking of printable string --- lib/src/asn1/asn1_utils.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/src/asn1/asn1_utils.cc b/lib/src/asn1/asn1_utils.cc index 8b9a53708..d09072cce 100644 --- a/lib/src/asn1/asn1_utils.cc +++ b/lib/src/asn1/asn1_utils.cc @@ -1276,9 +1276,7 @@ pack(bit_ref& bref, const std::string& s, size_t lb, size_t ub, size_t alb, size size_t b = asn_string_utils::get_nof_bits_per_char(lb, ub, aligned); bool octet_aligned = asn_string_utils::is_octet_aligned(b, alb, aub, aligned); bool length_encoded = asn_string_utils::is_length_encoded(alb, aub, aligned); - if (octet_aligned) { - bref.align_bytes_zero(); - } + if (ext) { HANDLE_CODE(bref.pack(0, 1)); } @@ -1300,9 +1298,7 @@ SRSASN_CODE unpack(std::string& s, cbit_ref& bref, size_t lb, size_t ub, size_t bool octet_aligned = asn_string_utils::is_octet_aligned(b, alb, aub, aligned); bool length_encoded = asn_string_utils::is_length_encoded(alb, aub, aligned); size_t max_nof_bits = b * aub; - if (octet_aligned) { - bref.align_bytes(); - } + if (ext) { bool is_ext; HANDLE_CODE(bref.unpack(is_ext, 1)); From ec8bf3ea6f6909d036d0534ed2882bce1e26cbc8 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 16 Nov 2022 12:24:38 +0100 Subject: [PATCH 008/167] lib,sctp: changing sctp sock opts to be compatible with RIC --- lib/src/common/network_utils.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/common/network_utils.cc b/lib/src/common/network_utils.cc index 3bf566556..b7c5c3b6d 100644 --- a/lib/src/common/network_utils.cc +++ b/lib/src/common/network_utils.cc @@ -225,7 +225,7 @@ bool sctp_subscribe_to_events(int fd) evnts.sctp_data_io_event = 1; evnts.sctp_shutdown_event = 1; evnts.sctp_address_event = 1; - if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) != 0) { + if (setsockopt(fd, SOL_SOCKET, SCTP_EVENTS, &evnts, sizeof(evnts)) != 0) { srslog::fetch_basic_logger(LOGSERVICE).error("Failed to subscribe to SCTP_SHUTDOWN event: %s", strerror(errno)); perror("Could not register socket to SCTP events\n"); close(fd); From b3d3c4436f4a6a98933e54fb0756382fb73304cb Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 16 Nov 2022 12:35:22 +0100 Subject: [PATCH 009/167] ric: adding logger to RIC client --- srsenb/src/enb.cc | 3 ++- srsgnb/hdr/stack/ric/ric_client.h | 3 ++- srsgnb/src/stack/ric/ric_client.cc | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index f8130ba3e..0d4db990b 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -118,7 +118,8 @@ int enb::init(const all_args_t& args_) ret = SRSRAN_ERROR; } } - std::unique_ptr tmp_ric_client = std::unique_ptr(new srsenb::ric_client()); + std::unique_ptr tmp_ric_client = + std::unique_ptr(new srsenb::ric_client(srslog::fetch_basic_logger("RIC", log_sink, false))); if (tmp_ric_client == nullptr) { srsran::console("Error creating RIC client instance.\n"); return SRSRAN_ERROR; diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index a0ac9e731..c5ea078c7 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -24,7 +24,7 @@ namespace srsenb { class ric_client : public srsran::thread { public: - ric_client(); + ric_client(srslog::basic_logger& logger); bool init(); void stop(); void run_thread(); @@ -36,6 +36,7 @@ private: srsran::unique_socket ric_socket; struct sockaddr_in ric_addr = {}; // RIC address bool running = false; + srslog::basic_logger& logger; }; } // namespace srsenb diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 6e150551e..754a69a5e 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -15,7 +15,7 @@ #include "stdint.h" using namespace srsenb; -ric_client::ric_client() : thread("RIC_CLIENT_THREAD") {} +ric_client::ric_client(srslog::basic_logger& logger) : logger(logger), thread("RIC_CLIENT_THREAD") {} bool ric_client::init() { printf("RIC_CLIENT: Init\n"); From eda5600ab0290c92fc5334d4a40d76265a148d89 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 16 Nov 2022 12:38:54 +0100 Subject: [PATCH 010/167] ric: adding receiver socket with taskqueue for E2 --- srsgnb/hdr/stack/ric/ric_client.h | 20 +++++++++++++++----- srsgnb/src/stack/ric/ric_client.cc | 15 +++++++++++++-- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index c5ea078c7..baacc8410 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -16,6 +16,7 @@ #include "srsgnb/hdr/stack/ric/e2ap.h" #include "srsran/common/network_utils.h" +#include "srsran/common/task_scheduler.h" #include "srsran/common/threads.h" #include "srsran/srsran.h" static const int e2ap_ppid = 70; @@ -30,13 +31,22 @@ public: void run_thread(); bool send_sctp(srsran::unique_byte_buffer_t& buf); bool send_e2_setup_request(); + bool + handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); + bool handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg); + bool handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& successful_outcome); + bool handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome); + bool handle_e2_setup_response(e2setup_resp_s setup_response); private: - e2ap e2ap_; - srsran::unique_socket ric_socket; - struct sockaddr_in ric_addr = {}; // RIC address - bool running = false; - srslog::basic_logger& logger; + e2ap e2ap_; + srsran::unique_socket ric_socket; + srsran::task_queue_handle ric_rece_task_queue; + srsran::task_scheduler task_sched; + srsran::socket_manager rx_sockets; + srslog::basic_logger& logger; + struct sockaddr_in ric_addr = {}; // RIC address + bool running = false; }; } // namespace srsenb diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 754a69a5e..dce625f41 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -15,7 +15,10 @@ #include "stdint.h" using namespace srsenb; -ric_client::ric_client(srslog::basic_logger& logger) : logger(logger), thread("RIC_CLIENT_THREAD") {} +ric_client::ric_client(srslog::basic_logger& logger) : + task_sched(), logger(logger), rx_sockets(), thread("RIC_CLIENT_THREAD") +{ +} bool ric_client::init() { printf("RIC_CLIENT: Init\n"); @@ -41,10 +44,18 @@ bool ric_client::init() if (not ric_socket.connect_to("10.104.149.217", e2ap_port, &ric_addr)) { return false; } + // Assign a handler to rx RIC packets + ric_rece_task_queue = task_sched.make_task_queue(); + auto rx_callback = + [this](srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags) { + handle_e2_rx_msg(std::move(pdu), from, sri, flags); + }; + rx_sockets.add_socket_handler(ric_socket.fd(), + srsran::make_sctp_sdu_handler(logger, ric_rece_task_queue, rx_callback)); + printf("SCTP socket connected with RIC. fd=%d", ric_socket.fd()); running = true; start(0); - return SRSRAN_SUCCESS; } void ric_client::stop() From be2442a459df31100c194a38278f60ca9a74d294 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 16 Nov 2022 12:45:06 +0100 Subject: [PATCH 011/167] ric, e2ap: adding initial incomming E2 message handling, simple processing of E2 setup response --- srsgnb/hdr/stack/ric/e2ap.h | 4 +- srsgnb/src/stack/ric/e2ap.cc | 7 +++ srsgnb/src/stack/ric/ric_client.cc | 95 ++++++++++++++++++++++++++++-- 3 files changed, 101 insertions(+), 5 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 5e2d97194..406f70059 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -23,14 +23,16 @@ class e2ap { public: e2_ap_pdu_c generate_setup_request(); - int process_setup_response(); + int process_setup_response(e2setup_resp_s setup_response); int process_setup_failure(); int process_subscription_request(); int generate_subscription_response(); int generate_subscription_failure(); int generate_indication(); + bool has_setup_response() { return setup_response_received; } private: + bool setup_response_received = false; }; #endif /* RIC_E2AP_H */ diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 1252f71aa..76ccfbc7a 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -51,3 +51,10 @@ e2_ap_pdu_c e2ap::generate_setup_request() item1.e2node_component_cfg.e2node_component_resp_part.from_string("72657370617274"); return pdu; } + +int e2ap::process_setup_response(e2setup_resp_s setup_response) +{ + setup_response_received = true; + // TODO process setup response + return 0; +} \ No newline at end of file diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index dce625f41..591875c91 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -66,8 +66,12 @@ void ric_client::stop() void ric_client::run_thread() { while (running) { - send_e2_setup_request(); - printf("e2 setup request sent\n"); + if (!e2ap_.has_setup_response()) { + send_e2_setup_request(); + printf("e2 setup request sent\n"); + } + sleep(1); + task_sched.run_next_task(); sleep(5); } } @@ -103,14 +107,97 @@ bool ric_client::send_e2_setup_request() asn1::bit_ref bref(buf->msg, buf->get_tailroom()); if (setup_req_pdu.pack(bref) != asn1::SRSASN_SUCCESS) { - printf("Failed to pack TX E2 PDU\n"); + logger.error("Failed to pack TX E2 PDU"); return false; } buf->N_bytes = bref.distance_bytes(); printf("try to send %d bytes to addr %s \n", buf->N_bytes, inet_ntoa(ric_addr.sin_addr)); if (!send_sctp(buf)) { - printf("failed to send e2 setup request\n"); + logger.error("failed to send e2 setup request"); return false; } return true; } + +bool ric_client::handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, + const sockaddr_in& from, + const sctp_sndrcvinfo& sri, + int flags) +{ + printf("RIC_CLIENT: Received %d bytes from %s\n", pdu->N_bytes, inet_ntoa(from.sin_addr)); + e2_ap_pdu_c pdu_c; + asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); + if (pdu_c.unpack(bref) != asn1::SRSASN_SUCCESS) { + logger.error("Failed to unpack RX E2 PDU"); + return false; + } + if (pdu_c.type().value == e2_ap_pdu_c::types_opts::init_msg) { + logger.info("Received E2AP Init Message"); + handle_e2_init_msg(pdu_c.init_msg()); + } else if (pdu_c.type().value == e2_ap_pdu_c::types_opts::successful_outcome) { + logger.info("Received E2AP Successful Outcome"); + // handle_e2_successful_outcome(pdu_c.successful_outcome()); + } else if (pdu_c.type().value == e2_ap_pdu_c::types_opts::unsuccessful_outcome) { + logger.info("Received E2AP Unsuccessful Outcome "); + // handle_e2_unsuccessful_outcome(pdu_c.unsuccessful_outcome()); + } else { + logger.warning("Received E2AP Unknown Message "); + } + return true; +} + +bool ric_client::handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg) +{ + using namespace asn1::e2ap; + // TODO check for different type of RIC generated init messages + // eg. RIC subscription request, RIC Reset request, RIC control request, RIC subscription delete request + return true; +} + +bool ric_client::handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& successful_outcome) +{ + using namespace asn1::e2ap; + if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::e2setup_resp) { + logger.info("Received E2AP E2 Setup Successful Outcome"); + handle_e2_setup_response(successful_outcome.value.e2setup_resp()); + } else if (successful_outcome.value.type() == + e2_ap_elem_procs_o::successful_outcome_c::types_opts::ricsubscription_resp) { + logger.info("Received E2AP RIC Subscription Response"); + // handle_ric_subscription_response(successful_outcome.value.ric_subscription()); + } else if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::ri_cctrl_ack) { + logger.info("Received E2AP RIC Control acknowlegement \n"); + // handle_ric_control_response(successful_outcome.value.ric_control()); + } else if (successful_outcome.value.type() == + e2_ap_elem_procs_o::successful_outcome_c::types_opts::ricservice_upd_ack) { + logger.info("Received E2AP RIC Service Update acknowlegement \n"); + // handle_ric_service_update_ack(successful_outcome.value.ric_service_update()); + } else if (successful_outcome.value.type() == + e2_ap_elem_procs_o::successful_outcome_c::types_opts::ricsubscription_delete_resp) { + logger.info("Received E2AP RIC Subscription Delete Response \n"); + // handle_ric_subscription_delete_response(successful_outcome.value.ric_subscription_delete()); + } else if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::e2_removal_resp) { + logger.info("Received E2AP RIC Service Status Successful Outcome \n"); + // handle_e2_removal_response(successful_outcome.value.e2_removal()); + } else { + logger.info("Received E2AP Unknown Successful Outcome \n"); + } + return true; +} + +bool ric_client::handle_e2_setup_response(e2setup_resp_s setup_response) +{ + printf("Received E2AP E2 Setup Response \n"); + if (e2ap_.process_setup_response(setup_response)) { + logger.error("Failed to process E2 Setup Response"); + return false; + } + return true; +} + +bool ric_client::handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome) +{ + using namespace asn1::e2ap; + // TODO check for different type of RIC generated unsuccessful outcomes + // eg. RIC subscription failure, RIC Reset failure, RIC control failure, RIC subscription delete failure + return true; +} From d34bd957bc7b8fb35331f4a5171d3d59f6119040 Mon Sep 17 00:00:00 2001 From: yagoda Date: Tue, 22 Nov 2022 22:21:43 +0100 Subject: [PATCH 012/167] e2ap,ric: adding support of E2-RIC subscription request/response --- srsgnb/hdr/stack/ric/e2ap.h | 5 ++-- srsgnb/hdr/stack/ric/ric_client.h | 1 + srsgnb/src/stack/ric/e2ap.cc | 28 ++++++++++++++++++++ srsgnb/src/stack/ric/ric_client.cc | 34 +++++++++++++++++++++++- srsgnb/src/stack/ric/test/e2ap_test.cc | 36 ++++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 3 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 406f70059..01b8d8d41 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -25,14 +25,15 @@ public: e2_ap_pdu_c generate_setup_request(); int process_setup_response(e2setup_resp_s setup_response); int process_setup_failure(); - int process_subscription_request(); - int generate_subscription_response(); + int process_subscription_request(ricsubscription_request_s subscription_request); + e2_ap_pdu_c generate_subscription_response(); int generate_subscription_failure(); int generate_indication(); bool has_setup_response() { return setup_response_received; } private: bool setup_response_received = false; + bool pending_subscription_request = false; }; #endif /* RIC_E2AP_H */ diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index baacc8410..6bf836b76 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -37,6 +37,7 @@ public: bool handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& successful_outcome); bool handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome); bool handle_e2_setup_response(e2setup_resp_s setup_response); + bool handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request); private: e2ap e2ap_; diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 76ccfbc7a..34d94926f 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -52,9 +52,37 @@ e2_ap_pdu_c e2ap::generate_setup_request() return pdu; } +e2_ap_pdu_c e2ap::generate_subscription_response() +{ + e2_ap_pdu_c pdu; + successful_outcome_s& success = pdu.set_successful_outcome(); + success.load_info_obj(ASN1_E2AP_ID_RICSUBSCRIPTION); + ricsubscription_resp_s& sub_resp = success.value.ricsubscription_resp(); + + sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; + sub_resp->ri_crequest_id.id = ASN1_E2AP_ID_RI_CREQUEST_ID; + sub_resp->ri_crequest_id.value.ric_requestor_id = 123; + sub_resp->ri_crequest_id.value.ric_instance_id = 21; + + sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; + sub_resp->ra_nfunction_id.id = ASN1_E2AP_ID_RA_NFUNCTION_ID; + sub_resp->ri_cactions_admitted.crit = asn1::crit_opts::reject; + auto& action_admit_list = sub_resp->ri_cactions_admitted.value; + action_admit_list.resize(1); + action_admit_list[0].load_info_obj(ASN1_E2AP_ID_RI_CACTION_ADMITTED_ITEM); + action_admit_list[0].value().ri_caction_admitted_item().ric_action_id = 1; + return pdu; +} int e2ap::process_setup_response(e2setup_resp_s setup_response) { setup_response_received = true; // TODO process setup response return 0; +} + +int e2ap::process_subscription_request(ricsubscription_request_s subscription_request) +{ + pending_subscription_request = true; + // TODO process subscription request + return 0; } \ No newline at end of file diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 591875c91..b896d7794 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -136,7 +136,7 @@ bool ric_client::handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, handle_e2_init_msg(pdu_c.init_msg()); } else if (pdu_c.type().value == e2_ap_pdu_c::types_opts::successful_outcome) { logger.info("Received E2AP Successful Outcome"); - // handle_e2_successful_outcome(pdu_c.successful_outcome()); + handle_e2_successful_outcome(pdu_c.successful_outcome()); } else if (pdu_c.type().value == e2_ap_pdu_c::types_opts::unsuccessful_outcome) { logger.info("Received E2AP Unsuccessful Outcome "); // handle_e2_unsuccessful_outcome(pdu_c.unsuccessful_outcome()); @@ -149,6 +149,27 @@ bool ric_client::handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, bool ric_client::handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg) { using namespace asn1::e2ap; + if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::ricsubscription_request) { + logger.info("Received E2AP RIC Subscription Request"); + handle_ric_subscription_request(init_msg.value.ricsubscription_request()); + } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::ricsubscription_delete_request) { + logger.info("Received E2AP RIC Subscription Delete Request"); + // handle_ric_subscription_delete_request(init_msg.value.ricsubscription_delete_request()); + } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::ri_cctrl_request) { + logger.info("Received E2AP RIC Control Request"); + // handle_ri_cctrl_request(init_msg.value.ri_cctrl_request()); + } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::e2conn_upd) { + logger.info("Received E2AP E2 Connection Update"); + //handle_e2conn_upd(init_msg.value.e2conn_upd()); + } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::reset_request) { + logger.info("Received E2AP E2 Reset Request"); + //handle_reset_request(init_msg.value.reset_request()); + } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::e2_removal_request) { + logger.info("Received E2AP E2 Removal Request"); + //handle_e2_removal_request(init_msg.value.e2_removal_request()); + } else { + logger.warning("Received E2AP Unknown Init Message "); + } // TODO check for different type of RIC generated init messages // eg. RIC subscription request, RIC Reset request, RIC control request, RIC subscription delete request return true; @@ -201,3 +222,14 @@ bool ric_client::handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome // eg. RIC subscription failure, RIC Reset failure, RIC control failure, RIC subscription delete failure return true; } + +bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request) +{ + auto send_sub_resp = + [this]() { + send_e2_msg(E2_SUB_RESPONSE); + }; + ric_rece_task_queue.push(send_sub_resp); + // TODO handle RIC subscription request + return true; +} diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index 4a0835650..39338bbed 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -98,9 +98,45 @@ void test_native_e2ap_setup_request() printf("Unpacked native E2AP PDU %d\n", (int)unpack_ret); } +void test_reference_e2ap_subscription_request() +{ + uint8_t e2ap_msg_foreign[] = {0x00, 0x08, 0x40, 0x2b, 0x00, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x05, 0x00, + 0x00, 0x7b, 0x00, 0x15, 0x00, 0x05, 0x00, 0x02, 0x00, 0x01, 0x00, 0x1e, + 0x00, 0x15, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x13, 0x40, + 0x0a, 0x60, 0x01, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x02, 0x00}; + + asn1::cbit_ref bref(&e2ap_msg_foreign[0], sizeof(e2ap_msg_foreign)); + e2_ap_pdu_c pdu; + asn1::SRSASN_CODE unpack_ret = pdu.unpack(bref); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked E2AP PDU (subscription request) %d\n", (int)unpack_ret); +} + +void test_native_e2ap_subscription_response() +{ + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + e2_ap_pdu_c pdu, pdu2; + e2ap e2ap_; + pdu = e2ap_.generate_subscription_response(); + + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("Failed to pack TX E2 PDU\n"); + return; + } + + asn1::cbit_ref bref2(buf->msg, buf->get_tailroom()); + + asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked native E2AP PDU (subscription response) %d\n", (int)unpack_ret); +} + int main() { test_reference_e2ap_setup_request(); test_native_e2ap_setup_request(); + test_reference_e2ap_subscription_request(); + test_native_e2ap_subscription_response(); return 0; } \ No newline at end of file From d4fbdfd54bd2c93946b38438d3de2a43ba0f5bbf Mon Sep 17 00:00:00 2001 From: yagoda Date: Tue, 22 Nov 2022 22:28:50 +0100 Subject: [PATCH 013/167] ric: making the e2 pack/send function generic --- srsgnb/hdr/stack/ric/ric_client.h | 3 ++- srsgnb/src/stack/ric/ric_client.cc | 24 ++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index 6bf836b76..8d5f23267 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -21,6 +21,7 @@ #include "srsran/srsran.h" static const int e2ap_ppid = 70; static const int e2ap_port = 36422; +enum e2_msg_type_t { E2_SETUP_REQUEST, E2_SUB_RESPONSE, E2_INDICATION }; namespace srsenb { class ric_client : public srsran::thread { @@ -30,7 +31,7 @@ public: void stop(); void run_thread(); bool send_sctp(srsran::unique_byte_buffer_t& buf); - bool send_e2_setup_request(); + bool send_e2_msg(e2_msg_type_t msg_type); bool handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); bool handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg); diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index b896d7794..79eb60f9d 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -67,7 +67,7 @@ void ric_client::run_thread() { while (running) { if (!e2ap_.has_setup_response()) { - send_e2_setup_request(); + send_e2_msg(E2_SETUP_REQUEST); printf("e2 setup request sent\n"); } sleep(1); @@ -95,18 +95,30 @@ bool ric_client::send_sctp(srsran::unique_byte_buffer_t& buf) return true; } -bool ric_client::send_e2_setup_request() +bool ric_client::send_e2_msg(e2_msg_type_t msg_type) { srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); if (buf == nullptr) { // logger.error("Fatal Error: Couldn't allocate buffer for %s.", procedure_name); return false; } - - e2_ap_pdu_c setup_req_pdu = e2ap_.generate_setup_request(); - + e2_ap_pdu_c send_pdu; + switch (msg_type) { + case e2_msg_type_t::E2_SETUP_REQUEST: + send_pdu = e2ap_.generate_setup_request(); + break; + case e2_msg_type_t::E2_SUB_RESPONSE: + send_pdu = e2ap_.generate_subscription_response(); + break; + case e2_msg_type_t::E2_INDICATION: + // TODO create E2 INDICATION generation + break; + default: + printf("Unknown E2AP message type\n"); + return false; + } asn1::bit_ref bref(buf->msg, buf->get_tailroom()); - if (setup_req_pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + if (send_pdu.pack(bref) != asn1::SRSASN_SUCCESS) { logger.error("Failed to pack TX E2 PDU"); return false; } From a8631828d42bfedb441479f6c9e376c8234cbfe8 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 4 Jan 2023 11:15:05 +0100 Subject: [PATCH 014/167] e2ap: adding logger to e2ap class --- srsgnb/hdr/stack/ric/e2ap.h | 6 ++++-- srsgnb/src/stack/ric/e2ap.cc | 2 ++ srsgnb/src/stack/ric/ric_client.cc | 5 ++--- srsgnb/src/stack/ric/test/e2ap_test.cc | 6 ++++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 01b8d8d41..1dcea7b03 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -22,6 +22,7 @@ using namespace asn1::e2ap; class e2ap { public: + e2ap(srslog::basic_logger& logger); e2_ap_pdu_c generate_setup_request(); int process_setup_response(e2setup_resp_s setup_response); int process_setup_failure(); @@ -32,8 +33,9 @@ public: bool has_setup_response() { return setup_response_received; } private: - bool setup_response_received = false; - bool pending_subscription_request = false; + srslog::basic_logger& logger; + bool setup_response_received = false; + bool pending_subscription_request = false; }; #endif /* RIC_E2AP_H */ diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 34d94926f..174850138 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -2,6 +2,8 @@ #include "srsgnb/hdr/stack/ric/e2ap.h" #include "stdint.h" +e2ap::e2ap(srslog::basic_logger& logger) : logger(logger) {} + e2_ap_pdu_c e2ap::generate_setup_request() { e2_ap_pdu_c pdu; diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 79eb60f9d..e376587c3 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -16,7 +16,7 @@ using namespace srsenb; ric_client::ric_client(srslog::basic_logger& logger) : - task_sched(), logger(logger), rx_sockets(), thread("RIC_CLIENT_THREAD") + task_sched(), logger(logger), rx_sockets(), thread("RIC_CLIENT_THREAD"), e2ap_(logger) { } bool ric_client::init() @@ -191,7 +191,7 @@ bool ric_client::handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& { using namespace asn1::e2ap; if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::e2setup_resp) { - logger.info("Received E2AP E2 Setup Successful Outcome"); + logger.info("Received E2AP E2 Setup Response"); handle_e2_setup_response(successful_outcome.value.e2setup_resp()); } else if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::ricsubscription_resp) { @@ -219,7 +219,6 @@ bool ric_client::handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& bool ric_client::handle_e2_setup_response(e2setup_resp_s setup_response) { - printf("Received E2AP E2 Setup Response \n"); if (e2ap_.process_setup_response(setup_response)) { logger.error("Failed to process E2 Setup Response"); return false; diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index 39338bbed..12a49da74 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -82,7 +82,8 @@ void test_native_e2ap_setup_request() { srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); e2_ap_pdu_c pdu, pdu2; - e2ap e2ap_; + srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); + e2ap e2ap_(logger); pdu = e2ap_.generate_setup_request(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); @@ -116,7 +117,8 @@ void test_native_e2ap_subscription_response() { srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); e2_ap_pdu_c pdu, pdu2; - e2ap e2ap_; + srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); + e2ap e2ap_(logger); pdu = e2ap_.generate_subscription_response(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); From 5ef7ee0e494c4faba370bb5dc3097022ad5be7eb Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 4 Jan 2023 12:48:55 +0100 Subject: [PATCH 015/167] e2ap: adding e2sm_kpm asn1 packing/unpacking --- lib/include/srsran/asn1/e2sm_kpm.h | 2276 ++++++++++++ lib/src/asn1/CMakeLists.txt | 3 +- lib/src/asn1/e2sm_kpm.cpp | 5178 +++++++++++++++++++++++++++ srsgnb/src/stack/ric/CMakeLists.txt | 4 +- 4 files changed, 7457 insertions(+), 4 deletions(-) create mode 100644 lib/include/srsran/asn1/e2sm_kpm.h create mode 100644 lib/src/asn1/e2sm_kpm.cpp diff --git a/lib/include/srsran/asn1/e2sm_kpm.h b/lib/include/srsran/asn1/e2sm_kpm.h new file mode 100644 index 000000000..01940560c --- /dev/null +++ b/lib/include/srsran/asn1/e2sm_kpm.h @@ -0,0 +1,2276 @@ +/* + * + * 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. + * + */ + +/******************************************************************************* + * + * 3GPP TS ASN1 E2SM KPM v15.3.0 (2019-03) + * + ******************************************************************************/ + +#pragma once + +#include "asn1_utils.h" +#include +#include + +namespace asn1 { +namespace e2sm_kpm { + +/******************************************************************************* + * Constant Definitions + ******************************************************************************/ + +#define ASN1_E2SM_KPM_MAXOF_MSG_PROTOCOL_TESTS 15 +#define ASN1_E2SM_KPM_MAXOF_RICSTYLES 63 +#define ASN1_E2SM_KPM_MAXNOOF_QCI 256 +#define ASN1_E2SM_KPM_MAXNOOF_QOSFLOWS 64 +#define ASN1_E2SM_KPM_MAXNOOF_SLICE_ITEMS 1024 +#define ASN1_E2SM_KPM_MAXNOOF_CONTAINER_LIST_ITEMS 3 +#define ASN1_E2SM_KPM_MAX_CELLING_NBDU 512 +#define ASN1_E2SM_KPM_MAXOF_CONTAINERS 8 +#define ASN1_E2SM_KPM_MAX_PLMN 12 + +/******************************************************************************* + * Struct Definitions + ******************************************************************************/ + +// EUTRA-CGI ::= SEQUENCE +struct eutra_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<28, false, true> eutra_cell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-CGI ::= SEQUENCE +struct nr_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<36, false, true> nrcell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CGI ::= CHOICE +struct cgi_c { + struct types_opts { + enum options { nr_cgi, eutra_cgi, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + cgi_c() = default; + cgi_c(const cgi_c& other); + cgi_c& operator=(const cgi_c& other); + ~cgi_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_cgi_s& nr_cgi() + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + eutra_cgi_s& eutra_cgi() + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + const nr_cgi_s& nr_cgi() const + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + const eutra_cgi_s& eutra_cgi() const + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + nr_cgi_s& set_nr_cgi(); + eutra_cgi_s& set_eutra_cgi(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// FQIPERSlicesPerPlmnListItem ::= SEQUENCE +struct fqiper_slices_per_plmn_list_item_s { + bool ext = false; + bool pdcp_bytes_dl_present = false; + bool pdcp_bytes_ul_present = false; + uint16_t five_qi = 0; + uint64_t pdcp_bytes_dl = 0; + uint64_t pdcp_bytes_ul = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SNSSAI ::= SEQUENCE +struct snssai_s { + bool sd_present = false; + fixed_octstring<1, true> sst; + fixed_octstring<3, true> sd; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PerQCIReportListItemFormat ::= SEQUENCE +struct per_qci_report_list_item_format_s { + bool ext = false; + bool pdcp_bytes_dl_present = false; + bool pdcp_bytes_ul_present = false; + uint16_t qci = 0; + uint64_t pdcp_bytes_dl = 0; + uint64_t pdcp_bytes_ul = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SliceToReportListItem ::= SEQUENCE +struct slice_to_report_list_item_s { + using fqiper_slices_per_plmn_list_l_ = dyn_array; + + // member variables + bool ext = false; + snssai_s slice_id; + fqiper_slices_per_plmn_list_l_ fqiper_slices_per_plmn_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// EPC-CUUP-PM-Format ::= SEQUENCE +struct epc_cuup_pm_format_s { + using per_qci_report_list_l_ = dyn_array; + + // member variables + bool ext = false; + per_qci_report_list_l_ per_qci_report_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// FGC-CUUP-PM-Format ::= SEQUENCE +struct fgc_cuup_pm_format_s { + using slice_to_report_list_l_ = dyn_array; + + // member variables + bool ext = false; + slice_to_report_list_l_ slice_to_report_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PlmnID-List ::= SEQUENCE +struct plmn_id_list_s { + bool ext = false; + bool cu_up_pm_minus5_gc_present = false; + bool cu_up_pm_epc_present = false; + fixed_octstring<3, true> plmn_id; + fgc_cuup_pm_format_s cu_up_pm_minus5_gc; + epc_cuup_pm_format_s cu_up_pm_epc; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CUUPMeasurement-Container ::= SEQUENCE +struct cuup_meas_container_s { + using plmn_list_l_ = dyn_array; + + // member variables + bool ext = false; + plmn_list_l_ plmn_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// FQIPERSlicesPerPlmnPerCellListItem ::= SEQUENCE +struct fqiper_slices_per_plmn_per_cell_list_item_s { + bool ext = false; + bool dl_prbusage_present = false; + bool ul_prbusage_present = false; + uint16_t five_qi = 0; + uint8_t dl_prbusage = 0; + uint8_t ul_prbusage = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PerQCIReportListItem ::= SEQUENCE +struct per_qci_report_list_item_s { + bool ext = false; + bool dl_prbusage_present = false; + bool ul_prbusage_present = false; + uint16_t qci = 0; + uint8_t dl_prbusage = 0; + uint8_t ul_prbusage = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SlicePerPlmnPerCellListItem ::= SEQUENCE +struct slice_per_plmn_per_cell_list_item_s { + using fqiper_slices_per_plmn_per_cell_list_l_ = dyn_array; + + // member variables + bool ext = false; + snssai_s slice_id; + fqiper_slices_per_plmn_per_cell_list_l_ fqiper_slices_per_plmn_per_cell_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// EPC-DU-PM-Container ::= SEQUENCE +struct epc_du_pm_container_s { + using per_qci_report_list_l_ = dyn_array; + + // member variables + bool ext = false; + per_qci_report_list_l_ per_qci_report_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// FGC-DU-PM-Container ::= SEQUENCE +struct fgc_du_pm_container_s { + using slice_per_plmn_per_cell_list_l_ = dyn_array; + + // member variables + bool ext = false; + slice_per_plmn_per_cell_list_l_ slice_per_plmn_per_cell_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NRCGI ::= SEQUENCE +struct nrcgi_s { + fixed_octstring<3, true> plmn_id; + fixed_bitstring<36, false, true> nrcell_id; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ServedPlmnPerCellListItem ::= SEQUENCE +struct served_plmn_per_cell_list_item_s { + bool ext = false; + bool du_pm_minus5_gc_present = false; + bool du_pm_epc_present = false; + fixed_octstring<3, true> plmn_id; + fgc_du_pm_container_s du_pm_minus5_gc; + epc_du_pm_container_s du_pm_epc; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CellResourceReportListItem ::= SEQUENCE +struct cell_res_report_list_item_s { + using served_plmn_per_cell_list_l_ = dyn_array; + + // member variables + bool ext = false; + bool dl_totalof_available_prbs_present = false; + bool ul_totalof_available_prbs_present = false; + nrcgi_s nrcgi; + uint8_t dl_totalof_available_prbs = 0; + uint8_t ul_totalof_available_prbs = 0; + served_plmn_per_cell_list_l_ served_plmn_per_cell_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GUAMI ::= SEQUENCE +struct guami_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<8, false, true> amf_region_id; + fixed_bitstring<10, false, true> amf_set_id; + fixed_bitstring<6, false, true> amf_pointer; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GUMMEI ::= SEQUENCE +struct gummei_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_octstring<2, true> mme_group_id; + fixed_octstring<1, true> mme_code; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CoreCPID ::= CHOICE +struct core_cpid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + core_cpid_c() = default; + core_cpid_c(const core_cpid_c& other); + core_cpid_c& operator=(const core_cpid_c& other); + ~core_cpid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + guami_s& five_gc() + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + gummei_s& epc() + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + const guami_s& five_gc() const + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + const gummei_s& epc() const + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + guami_s& set_five_gc(); + gummei_s& set_epc(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// E2SM-KPM-ActionDefinition ::= SEQUENCE +struct e2_sm_kpm_action_definition_s { + bool ext = false; + int64_t ric_style_type = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RT-Period-IE ::= ENUMERATED +struct rt_period_ie_opts { + enum options { + ms10, + ms20, + ms32, + ms40, + ms60, + ms64, + ms70, + ms80, + ms128, + ms160, + ms256, + ms320, + ms512, + ms640, + ms1024, + ms1280, + ms2048, + ms2560, + ms5120, + ms10240, + // ... + nulltype + } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; +}; +typedef enumerated rt_period_ie_e; + +// Trigger-ConditionIE-Item ::= SEQUENCE +struct trigger_condition_ie_item_s { + bool ext = false; + rt_period_ie_e report_period_ie; + // ... + + // sequence methRaods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-EventTriggerDefinition-Format1 ::= SEQUENCE +struct e2_sm_kpm_event_trigger_definition_format1_s { + using policy_test_list_l_ = dyn_array; + + // member variables + bool ext = false; + policy_test_list_l_ policy_test_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-EventTriggerDefinition ::= CHOICE +struct e2_sm_kpm_event_trigger_definition_c { + struct types_opts { + enum options { event_definition_format1, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::event_definition_format1; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_event_trigger_definition_format1_s& event_definition_format1() { return c; } + const e2_sm_kpm_event_trigger_definition_format1_s& event_definition_format1() const { return c; } + +private: + e2_sm_kpm_event_trigger_definition_format1_s c; +}; + +// ENB-ID ::= CHOICE +struct enb_id_c { + struct types_opts { + enum options { macro_enb_id, home_enb_id, /*...*/ short_macro_enb_id, long_macro_enb_id, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_c() = default; + enb_id_c(const enb_id_c& other); + enb_id_c& operator=(const enb_id_c& other); + ~enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_enb_id() + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<28, false, true>& home_enb_id() + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_enb_id() + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_enb_id() + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_enb_id() const + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<28, false, true>& home_enb_id() const + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_enb_id() const + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_enb_id() const + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_enb_id(); + fixed_bitstring<28, false, true>& set_home_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// ENB-ID-Choice ::= CHOICE +struct enb_id_choice_c { + struct types_opts { + enum options { enb_id_macro, enb_id_shortmacro, enb_id_longmacro, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_choice_c() = default; + enb_id_choice_c(const enb_id_choice_c& other); + enb_id_choice_c& operator=(const enb_id_choice_c& other); + ~enb_id_choice_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& enb_id_macro() + { + assert_choice_type(types::enb_id_macro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<18, false, true>& enb_id_shortmacro() + { + assert_choice_type(types::enb_id_shortmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<21, false, true>& enb_id_longmacro() + { + assert_choice_type(types::enb_id_longmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& enb_id_macro() const + { + assert_choice_type(types::enb_id_macro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& enb_id_shortmacro() const + { + assert_choice_type(types::enb_id_shortmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& enb_id_longmacro() const + { + assert_choice_type(types::enb_id_longmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_enb_id_macro(); + fixed_bitstring<18, false, true>& set_enb_id_shortmacro(); + fixed_bitstring<21, false, true>& set_enb_id_longmacro(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// ENGNB-ID ::= CHOICE +struct engnb_id_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GNB-ID-Choice ::= CHOICE +struct gnb_id_choice_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalENB-ID ::= SEQUENCE +struct global_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalenGNB-ID ::= SEQUENCE +struct globalen_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + engnb_id_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalgNB-ID ::= SEQUENCE +struct globalg_nb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + gnb_id_choice_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalngeNB-ID ::= SEQUENCE +struct globalngenb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_choice_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalKPMnode-eNB-ID ::= SEQUENCE +struct global_kp_mnode_enb_id_s { + bool ext = false; + global_enb_id_s global_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalKPMnode-en-gNB-ID ::= SEQUENCE +struct global_kp_mnode_en_g_nb_id_s { + bool ext = false; + globalen_gnb_id_s global_g_nb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalKPMnode-gNB-ID ::= SEQUENCE +struct global_kp_mnode_g_nb_id_s { + bool ext = false; + bool gnb_cu_up_id_present = false; + bool gnb_du_id_present = false; + globalg_nb_id_s global_g_nb_id; + uint64_t gnb_cu_up_id = 0; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalKPMnode-ng-eNB-ID ::= SEQUENCE +struct global_kp_mnode_ng_enb_id_s { + bool ext = false; + globalngenb_id_s global_ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalKPMnode-ID ::= CHOICE +struct global_kp_mnode_id_c { + struct types_opts { + enum options { gnb, en_g_nb, ng_enb, enb, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_kp_mnode_id_c() = default; + global_kp_mnode_id_c(const global_kp_mnode_id_c& other); + global_kp_mnode_id_c& operator=(const global_kp_mnode_id_c& other); + ~global_kp_mnode_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_kp_mnode_g_nb_id_s& gnb() + { + assert_choice_type(types::gnb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + global_kp_mnode_en_g_nb_id_s& en_g_nb() + { + assert_choice_type(types::en_g_nb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + global_kp_mnode_ng_enb_id_s& ng_enb() + { + assert_choice_type(types::ng_enb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + global_kp_mnode_enb_id_s& enb() + { + assert_choice_type(types::enb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + const global_kp_mnode_g_nb_id_s& gnb() const + { + assert_choice_type(types::gnb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + const global_kp_mnode_en_g_nb_id_s& en_g_nb() const + { + assert_choice_type(types::en_g_nb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + const global_kp_mnode_ng_enb_id_s& ng_enb() const + { + assert_choice_type(types::ng_enb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + const global_kp_mnode_enb_id_s& enb() const + { + assert_choice_type(types::enb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + global_kp_mnode_g_nb_id_s& set_gnb(); + global_kp_mnode_en_g_nb_id_s& set_en_g_nb(); + global_kp_mnode_ng_enb_id_s& set_ng_enb(); + global_kp_mnode_enb_id_s& set_enb(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// E2SM-KPM-IndicationHeader-Format1 ::= SEQUENCE +struct e2_sm_kpm_ind_hdr_format1_s { + bool ext = false; + bool id_global_kp_mnode_id_present = false; + bool nrcgi_present = false; + bool plmn_id_present = false; + bool slice_id_present = false; + bool five_qi_present = false; + bool qci_present = false; + global_kp_mnode_id_c id_global_kp_mnode_id; + nrcgi_s nrcgi; + fixed_octstring<3, true> plmn_id; + snssai_s slice_id; + uint16_t five_qi = 0; + uint16_t qci = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationHeader ::= CHOICE +struct e2_sm_kpm_ind_hdr_c { + struct types_opts { + enum options { ind_hdr_format1, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ind_hdr_format1; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_ind_hdr_format1_s& ind_hdr_format1() { return c; } + const e2_sm_kpm_ind_hdr_format1_s& ind_hdr_format1() const { return c; } + +private: + e2_sm_kpm_ind_hdr_format1_s c; +}; + +// NI-Type ::= ENUMERATED +struct ni_type_opts { + enum options { x2_u, xn_u, f1_u, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated ni_type_e; + +// PF-ContainerListItem ::= SEQUENCE +struct pf_container_list_item_s { + bool ext = false; + ni_type_e interface_type; + cuup_meas_container_s o_cu_up_pm_container; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// OCUCP-PF-Container ::= SEQUENCE +struct ocucp_pf_container_s { + struct cu_cp_res_status_s_ { + bool nof_active_ues_present = false; + uint32_t nof_active_ues = 1; + }; + + // member variables + bool gnb_cu_cp_name_present = false; + printable_string<1, 150, true, true> gnb_cu_cp_name; + cu_cp_res_status_s_ cu_cp_res_status; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// OCUUP-PF-Container ::= SEQUENCE +struct ocuup_pf_container_s { + using pf_container_list_l_ = dyn_array; + + // member variables + bool ext = false; + bool gnb_cu_up_name_present = false; + printable_string<1, 150, true, true> gnb_cu_up_name; + pf_container_list_l_ pf_container_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ODU-PF-Container ::= SEQUENCE +struct odu_pf_container_s { + using cell_res_report_list_l_ = dyn_array; + + // member variables + bool ext = false; + cell_res_report_list_l_ cell_res_report_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PF-Container ::= CHOICE +struct pf_container_c { + struct types_opts { + enum options { odu, ocu_cp, ocu_up, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + pf_container_c() = default; + pf_container_c(const pf_container_c& other); + pf_container_c& operator=(const pf_container_c& other); + ~pf_container_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + odu_pf_container_s& odu() + { + assert_choice_type(types::odu, type_, "PF-Container"); + return c.get(); + } + ocucp_pf_container_s& ocu_cp() + { + assert_choice_type(types::ocu_cp, type_, "PF-Container"); + return c.get(); + } + ocuup_pf_container_s& ocu_up() + { + assert_choice_type(types::ocu_up, type_, "PF-Container"); + return c.get(); + } + const odu_pf_container_s& odu() const + { + assert_choice_type(types::odu, type_, "PF-Container"); + return c.get(); + } + const ocucp_pf_container_s& ocu_cp() const + { + assert_choice_type(types::ocu_cp, type_, "PF-Container"); + return c.get(); + } + const ocuup_pf_container_s& ocu_up() const + { + assert_choice_type(types::ocu_up, type_, "PF-Container"); + return c.get(); + } + odu_pf_container_s& set_odu(); + ocucp_pf_container_s& set_ocu_cp(); + ocuup_pf_container_s& set_ocu_up(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// PM-Containers-List ::= SEQUENCE +struct pm_containers_list_s { + bool ext = false; + bool performance_container_present = false; + pf_container_c performance_container; + unbounded_octstring the_ran_container; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationMessage-Format1 ::= SEQUENCE +struct e2_sm_kpm_ind_msg_format1_s { + using pm_containers_l_ = dyn_array; + + // member variables + bool ext = false; + pm_containers_l_ pm_containers; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationMessage ::= CHOICE +struct e2_sm_kpm_ind_msg_c { + struct types_opts { + enum options { ric_style_type, ind_msg_format1, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + e2_sm_kpm_ind_msg_c() = default; + e2_sm_kpm_ind_msg_c(const e2_sm_kpm_ind_msg_c& other); + e2_sm_kpm_ind_msg_c& operator=(const e2_sm_kpm_ind_msg_c& other); + ~e2_sm_kpm_ind_msg_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + int64_t& ric_style_type() + { + assert_choice_type(types::ric_style_type, type_, "E2SM-KPM-IndicationMessage"); + return c.get(); + } + e2_sm_kpm_ind_msg_format1_s& ind_msg_format1() + { + assert_choice_type(types::ind_msg_format1, type_, "E2SM-KPM-IndicationMessage"); + return c.get(); + } + const int64_t& ric_style_type() const + { + assert_choice_type(types::ric_style_type, type_, "E2SM-KPM-IndicationMessage"); + return c.get(); + } + const e2_sm_kpm_ind_msg_format1_s& ind_msg_format1() const + { + assert_choice_type(types::ind_msg_format1, type_, "E2SM-KPM-IndicationMessage"); + return c.get(); + } + int64_t& set_ric_style_type(); + e2_sm_kpm_ind_msg_format1_s& set_ind_msg_format1(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// RANfunction-Name ::= SEQUENCE +struct ra_nfunction_name_s { + bool ext = false; + bool ran_function_instance_present = false; + printable_string<1, 150, true, true> ran_function_short_name; + printable_string<1, 1000, true, true> ran_function_e2_sm_oid; + printable_string<1, 150, true, true> ran_function_description; + int64_t ran_function_instance = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RIC-EventTriggerStyle-List ::= SEQUENCE +struct ric_event_trigger_style_list_s { + bool ext = false; + int64_t ric_event_trigger_style_type = 0; + printable_string<1, 150, true, true> ric_event_trigger_style_name; + int64_t ric_event_trigger_format_type = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RIC-ReportStyle-List ::= SEQUENCE +struct ric_report_style_list_s { + bool ext = false; + int64_t ric_report_style_type = 0; + printable_string<1, 150, true, true> ric_report_style_name; + int64_t ric_ind_hdr_format_type = 0; + int64_t ric_ind_msg_format_type = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-RANfunction-Description ::= SEQUENCE +struct e2_sm_kpm_ra_nfunction_description_s { + struct e2_sm_kpm_ra_nfunction_item_s_ { + using ric_event_trigger_style_list_l_ = dyn_array; + using ric_report_style_list_l_ = dyn_array; + + // member variables + bool ext = false; + ric_event_trigger_style_list_l_ ric_event_trigger_style_list; + ric_report_style_list_l_ ric_report_style_list; + // ... + }; + + // member variables + bool ext = false; + ra_nfunction_name_s ran_function_name; + e2_sm_kpm_ra_nfunction_item_s_ e2_sm_kpm_ra_nfunction_item; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GNB-ID ::= CHOICE +struct gnb_id_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalGNB-ID ::= SEQUENCE +struct global_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + gnb_id_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NgENB-ID ::= CHOICE +struct ng_enb_id_c { + struct types_opts { + enum options { macro_ng_enb_id, short_macro_ng_enb_id, long_macro_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ng_enb_id_c() = default; + ng_enb_id_c(const ng_enb_id_c& other); + ng_enb_id_c& operator=(const ng_enb_id_c& other); + ~ng_enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_ng_enb_id() + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_ng_enb_id() + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_ng_enb_id() + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_ng_enb_id() const + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_ng_enb_id() const + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_ng_enb_id() const + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_ng_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_ng_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_ng_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// GlobalNgENB-ID ::= SEQUENCE +struct global_ng_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + ng_enb_id_c ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalRANNodeID ::= CHOICE +struct global_ran_node_id_c { + struct types_opts { + enum options { global_gnb_id, global_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_ran_node_id_c() = default; + global_ran_node_id_c(const global_ran_node_id_c& other); + global_ran_node_id_c& operator=(const global_ran_node_id_c& other); + ~global_ran_node_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_gnb_id_s& global_gnb_id() + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_ng_enb_id_s& global_ng_enb_id() + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_gnb_id_s& global_gnb_id() const + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_ng_enb_id_s& global_ng_enb_id() const + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_gnb_id_s& set_global_gnb_id(); + global_ng_enb_id_s& set_global_ng_enb_id(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// EN-GNB-ID ::= CHOICE +struct en_gnb_id_c { + struct types_opts { + enum options { en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::en_g_nb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& en_g_nb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& en_g_nb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GroupID ::= CHOICE +struct group_id_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + group_id_c() = default; + group_id_c(const group_id_c& other); + group_id_c& operator=(const group_id_c& other); + ~group_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// InterfaceID-E1 ::= SEQUENCE +struct interface_id_e1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_cu_up_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-F1 ::= SEQUENCE +struct interface_id_f1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-NG ::= SEQUENCE +struct interface_id_ng_s { + bool ext = false; + guami_s guami; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-S1 ::= SEQUENCE +struct interface_id_s1_s { + bool ext = false; + gummei_s gummei; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-W1 ::= SEQUENCE +struct interface_id_w1_s { + bool ext = false; + global_ng_enb_id_s global_ng_enb_id; + uint64_t ng_enb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-X2 ::= SEQUENCE +struct interface_id_x2_s { + struct node_type_c_ { + struct types_opts { + enum options { global_enb_id, global_en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + node_type_c_() = default; + node_type_c_(const node_type_c_& other); + node_type_c_& operator=(const node_type_c_& other); + ~node_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_enb_id_s& global_enb_id() + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + globalen_gnb_id_s& global_en_g_nb_id() + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + const global_enb_id_s& global_enb_id() const + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + const globalen_gnb_id_s& global_en_g_nb_id() const + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + global_enb_id_s& set_global_enb_id(); + globalen_gnb_id_s& set_global_en_g_nb_id(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + node_type_c_ node_type; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-Xn ::= SEQUENCE +struct interface_id_xn_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceIdentifier ::= CHOICE +struct interface_id_c { + struct types_opts { + enum options { ng, xn, f1, e1, s1, x2, w1, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + interface_id_c() = default; + interface_id_c(const interface_id_c& other); + interface_id_c& operator=(const interface_id_c& other); + ~interface_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + interface_id_ng_s& ng() + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_xn_s& xn() + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_f1_s& f1() + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_e1_s& e1() + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_s1_s& s1() + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_x2_s& x2() + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_w1_s& w1() + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_ng_s& ng() const + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_xn_s& xn() const + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_f1_s& f1() const + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_e1_s& e1() const + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_s1_s& s1() const + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_x2_s& x2() const + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_w1_s& w1() const + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_ng_s& set_ng(); + interface_id_xn_s& set_xn(); + interface_id_f1_s& set_f1(); + interface_id_e1_s& set_e1(); + interface_id_s1_s& set_s1(); + interface_id_x2_s& set_x2(); + interface_id_w1_s& set_w1(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// FreqBandNrItem ::= SEQUENCE +struct freq_band_nr_item_s { + bool ext = false; + uint16_t freq_band_ind_nr = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-ARFCN ::= SEQUENCE +struct nr_arfcn_s { + using freq_band_list_nr_l_ = dyn_array; + + // member variables + bool ext = false; + uint32_t nrarfcn = 0; + freq_band_list_nr_l_ freq_band_list_nr; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// QoSID ::= CHOICE +struct qo_sid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + qo_sid_c() = default; + qo_sid_c(const qo_sid_c& other); + qo_sid_c& operator=(const qo_sid_c& other); + ~qo_sid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// RRCclass-LTE ::= ENUMERATED +struct rr_cclass_lte_opts { + enum options { + bcch_bch, + bcch_bch_mbms, + bcch_dl_sch, + bcch_dl_sch_br, + bcch_dl_sch_mbms, + mcch, + pcch, + dl_ccch, + dl_dcch, + ul_ccch, + ul_dcch, + sc_mcch, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated rr_cclass_lte_e; + +// RRCclass-NR ::= ENUMERATED +struct rr_cclass_nr_opts { + enum options { bcch_bch, bcch_dl_sch, dl_ccch, dl_dcch, pcch, ul_ccch, ul_ccch1, ul_dcch, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated rr_cclass_nr_e; + +// RRC-MessageID ::= SEQUENCE +struct rrc_msg_id_s { + struct rrc_type_c_ { + struct types_opts { + enum options { lte, nr, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + rrc_type_c_() = default; + rrc_type_c_(const rrc_type_c_& other); + rrc_type_c_& operator=(const rrc_type_c_& other); + ~rrc_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + rr_cclass_lte_e& lte() + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + rr_cclass_nr_e& nr() + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + const rr_cclass_lte_e& lte() const + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + const rr_cclass_nr_e& nr() const + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + rr_cclass_lte_e& set_lte(); + rr_cclass_nr_e& set_nr(); + + private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + rrc_type_c_ rrc_type; + int64_t msg_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// S-NSSAI ::= SEQUENCE +struct s_nssai_s { + bool ext = false; + bool sd_present = false; + fixed_octstring<1, true> sst; + fixed_octstring<3, true> sd; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ServingCell-ARFCN ::= CHOICE +struct serving_cell_arfcn_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_arfcn_c() = default; + serving_cell_arfcn_c(const serving_cell_arfcn_c& other); + serving_cell_arfcn_c& operator=(const serving_cell_arfcn_c& other); + ~serving_cell_arfcn_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_arfcn_s& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + uint32_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + const nr_arfcn_s& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + const uint32_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + nr_arfcn_s& set_nr(); + uint32_t& set_eutra(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// ServingCell-PCI ::= CHOICE +struct serving_cell_pci_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_pci_c() = default; + serving_cell_pci_c(const serving_cell_pci_c& other); + serving_cell_pci_c& operator=(const serving_cell_pci_c& other); + ~serving_cell_pci_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& set_nr(); + uint16_t& set_eutra(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_e1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_f1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-E1AP-ID-List ::= SEQUENCE (SIZE (1..65535)) OF UEID-GNB-CU-CP-E1AP-ID-Item +using ueid_gnb_cu_cp_e1_ap_id_list_l = dyn_array; + +// UEID-GNB-CU-F1AP-ID-List ::= SEQUENCE (SIZE (1..4)) OF UEID-GNB-CU-CP-F1AP-ID-Item +using ueid_gnb_cu_f1_ap_id_list_l = dyn_array; + +// UEID-EN-GNB ::= SEQUENCE +struct ueid_en_gnb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool gnb_cu_ue_f1_ap_id_present = false; + bool ran_ueid_present = false; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + uint64_t gnb_cu_ue_f1_ap_id = 0; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-ENB ::= SEQUENCE +struct ueid_enb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_present = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool global_enb_id_present = false; + uint64_t mme_ue_s1ap_id = 0; + gummei_s gummei; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB ::= SEQUENCE +struct ueid_gnb_s { + bool ext = false; + bool ran_ueid_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_gnb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + ueid_gnb_cu_f1_ap_id_list_l gnb_cu_ue_f1_ap_id_list; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_gnb_id_s global_gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-UP ::= SEQUENCE +struct ueid_gnb_cu_up_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-DU ::= SEQUENCE +struct ueid_gnb_du_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB ::= SEQUENCE +struct ueid_ng_enb_s { + bool ext = false; + bool ng_enb_cu_ue_w1_ap_id_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_ng_enb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_ng_enb_id_s global_ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB-DU ::= SEQUENCE +struct ueid_ng_enb_du_s { + bool ext = false; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID ::= CHOICE +struct ueid_c { + struct types_opts { + enum options { + gnb_ueid, + gnb_du_ueid, + gnb_cu_up_ueid, + ng_enb_ueid, + ng_enb_du_ueid, + en_g_nb_ueid, + enb_ueid, + // ... + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ueid_c() = default; + ueid_c(const ueid_c& other); + ueid_c& operator=(const ueid_c& other); + ~ueid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ueid_gnb_s& gnb_ueid() + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_du_s& gnb_du_ueid() + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_cu_up_s& gnb_cu_up_ueid() + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_s& ng_enb_ueid() + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_du_s& ng_enb_du_ueid() + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_en_gnb_s& en_g_nb_ueid() + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + ueid_enb_s& enb_ueid() + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_s& gnb_ueid() const + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_du_s& gnb_du_ueid() const + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_cu_up_s& gnb_cu_up_ueid() const + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_s& ng_enb_ueid() const + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_du_s& ng_enb_du_ueid() const + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_en_gnb_s& en_g_nb_ueid() const + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_enb_s& enb_ueid() const + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_s& set_gnb_ueid(); + ueid_gnb_du_s& set_gnb_du_ueid(); + ueid_gnb_cu_up_s& set_gnb_cu_up_ueid(); + ueid_ng_enb_s& set_ng_enb_ueid(); + ueid_ng_enb_du_s& set_ng_enb_du_ueid(); + ueid_en_gnb_s& set_en_g_nb_ueid(); + ueid_enb_s& set_enb_ueid(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +} // namespace e2sm_kpm +} // namespace asn1 diff --git a/lib/src/asn1/CMakeLists.txt b/lib/src/asn1/CMakeLists.txt index 94fb79bf0..566ed56c8 100644 --- a/lib/src/asn1/CMakeLists.txt +++ b/lib/src/asn1/CMakeLists.txt @@ -67,8 +67,7 @@ target_compile_options(nas_5g_msg PRIVATE "-Os") target_link_libraries(nas_5g_msg asn1_utils srsran_common) install(TARGETS nas_5g_msg DESTINATION ${LIBRARY_DIR} OPTIONAL) ## ORAN E2 RIC -add_library(ric_e2 STATIC e2ap.cpp e2sm.cpp) +add_library(ric_e2 STATIC e2sm_kpm.cpp e2ap.cpp e2sm.cpp) target_compile_options(ric_e2 PRIVATE "-Os") target_link_libraries(ric_e2 asn1_utils srsran_common) install(TARGETS ric_e2 DESTINATION ${LIBRARY_DIR} OPTIONAL) - diff --git a/lib/src/asn1/e2sm_kpm.cpp b/lib/src/asn1/e2sm_kpm.cpp new file mode 100644 index 000000000..9c4855f4f --- /dev/null +++ b/lib/src/asn1/e2sm_kpm.cpp @@ -0,0 +1,5178 @@ +/* + * + * 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/asn1/e2sm_kpm.h" +#include + +using namespace asn1; +using namespace asn1::e2sm_kpm; + +/******************************************************************************* + * Struct Methods + ******************************************************************************/ + +// EUTRA-CGI ::= SEQUENCE +SRSASN_CODE eutra_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(eutra_cell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE eutra_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(eutra_cell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void eutra_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("eUTRACellIdentity", eutra_cell_id.to_string()); + j.end_obj(); +} + +// NR-CGI ::= SEQUENCE +SRSASN_CODE nr_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(nrcell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(nrcell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void nr_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("nRCellIdentity", nrcell_id.to_string()); + j.end_obj(); +} + +// CGI ::= CHOICE +void cgi_c::destroy_() +{ + switch (type_) { + case types::nr_cgi: + c.destroy(); + break; + case types::eutra_cgi: + c.destroy(); + break; + default: + break; + } +} +void cgi_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr_cgi: + c.init(); + break; + case types::eutra_cgi: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c::cgi_c(const cgi_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr_cgi: + c.init(other.c.get()); + break; + case types::eutra_cgi: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c& cgi_c::operator=(const cgi_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr_cgi: + c.set(other.c.get()); + break; + case types::eutra_cgi: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + + return *this; +} +nr_cgi_s& cgi_c::set_nr_cgi() +{ + set(types::nr_cgi); + return c.get(); +} +eutra_cgi_s& cgi_c::set_eutra_cgi() +{ + set(types::eutra_cgi); + return c.get(); +} +void cgi_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr_cgi: + j.write_fieldname("nR-CGI"); + c.get().to_json(j); + break; + case types::eutra_cgi: + j.write_fieldname("eUTRA-CGI"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + j.end_obj(); +} +SRSASN_CODE cgi_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE cgi_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* cgi_c::types_opts::to_string() const +{ + static const char* options[] = {"nR-CGI", "eUTRA-CGI"}; + return convert_enum_idx(options, 2, value, "cgi_c::types"); +} + +// FQIPERSlicesPerPlmnListItem ::= SEQUENCE +SRSASN_CODE fqiper_slices_per_plmn_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(pdcp_bytes_dl_present, 1)); + HANDLE_CODE(bref.pack(pdcp_bytes_ul_present, 1)); + + HANDLE_CODE(pack_integer(bref, five_qi, (uint16_t)0u, (uint16_t)255u, false, true)); + if (pdcp_bytes_dl_present) { + HANDLE_CODE(pack_integer(bref, pdcp_bytes_dl, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + if (pdcp_bytes_ul_present) { + HANDLE_CODE(pack_integer(bref, pdcp_bytes_ul, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE fqiper_slices_per_plmn_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(pdcp_bytes_dl_present, 1)); + HANDLE_CODE(bref.unpack(pdcp_bytes_ul_present, 1)); + + HANDLE_CODE(unpack_integer(five_qi, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + if (pdcp_bytes_dl_present) { + HANDLE_CODE(unpack_integer(pdcp_bytes_dl, bref, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + if (pdcp_bytes_ul_present) { + HANDLE_CODE(unpack_integer(pdcp_bytes_ul, bref, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + + return SRSASN_SUCCESS; +} +void fqiper_slices_per_plmn_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("fiveQI", five_qi); + if (pdcp_bytes_dl_present) { + j.write_int("pDCPBytesDL", pdcp_bytes_dl); + } + if (pdcp_bytes_ul_present) { + j.write_int("pDCPBytesUL", pdcp_bytes_ul); + } + j.end_obj(); +} + +// SNSSAI ::= SEQUENCE +SRSASN_CODE snssai_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(sd_present, 1)); + + HANDLE_CODE(sst.pack(bref)); + if (sd_present) { + HANDLE_CODE(sd.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE snssai_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(sd_present, 1)); + + HANDLE_CODE(sst.unpack(bref)); + if (sd_present) { + HANDLE_CODE(sd.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void snssai_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("sST", sst.to_string()); + if (sd_present) { + j.write_str("sD", sd.to_string()); + } + j.end_obj(); +} + +// PerQCIReportListItemFormat ::= SEQUENCE +SRSASN_CODE per_qci_report_list_item_format_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(pdcp_bytes_dl_present, 1)); + HANDLE_CODE(bref.pack(pdcp_bytes_ul_present, 1)); + + HANDLE_CODE(pack_integer(bref, qci, (uint16_t)0u, (uint16_t)255u, false, true)); + if (pdcp_bytes_dl_present) { + HANDLE_CODE(pack_integer(bref, pdcp_bytes_dl, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + if (pdcp_bytes_ul_present) { + HANDLE_CODE(pack_integer(bref, pdcp_bytes_ul, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE per_qci_report_list_item_format_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(pdcp_bytes_dl_present, 1)); + HANDLE_CODE(bref.unpack(pdcp_bytes_ul_present, 1)); + + HANDLE_CODE(unpack_integer(qci, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + if (pdcp_bytes_dl_present) { + HANDLE_CODE(unpack_integer(pdcp_bytes_dl, bref, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + if (pdcp_bytes_ul_present) { + HANDLE_CODE(unpack_integer(pdcp_bytes_ul, bref, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + + return SRSASN_SUCCESS; +} +void per_qci_report_list_item_format_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("qci", qci); + if (pdcp_bytes_dl_present) { + j.write_int("pDCPBytesDL", pdcp_bytes_dl); + } + if (pdcp_bytes_ul_present) { + j.write_int("pDCPBytesUL", pdcp_bytes_ul); + } + j.end_obj(); +} + +// SliceToReportListItem ::= SEQUENCE +SRSASN_CODE slice_to_report_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(slice_id.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, fqiper_slices_per_plmn_list, 1, 64, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE slice_to_report_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(slice_id.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(fqiper_slices_per_plmn_list, bref, 1, 64, true)); + + return SRSASN_SUCCESS; +} +void slice_to_report_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("sliceID"); + slice_id.to_json(j); + j.start_array("fQIPERSlicesPerPlmnList"); + for (const auto& e1 : fqiper_slices_per_plmn_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// EPC-CUUP-PM-Format ::= SEQUENCE +SRSASN_CODE epc_cuup_pm_format_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, per_qci_report_list, 1, 256, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE epc_cuup_pm_format_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(per_qci_report_list, bref, 1, 256, true)); + + return SRSASN_SUCCESS; +} +void epc_cuup_pm_format_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("perQCIReportList"); + for (const auto& e1 : per_qci_report_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// FGC-CUUP-PM-Format ::= SEQUENCE +SRSASN_CODE fgc_cuup_pm_format_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, slice_to_report_list, 1, 1024, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE fgc_cuup_pm_format_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(slice_to_report_list, bref, 1, 1024, true)); + + return SRSASN_SUCCESS; +} +void fgc_cuup_pm_format_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("sliceToReportList"); + for (const auto& e1 : slice_to_report_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// PlmnID-List ::= SEQUENCE +SRSASN_CODE plmn_id_list_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(cu_up_pm_minus5_gc_present, 1)); + HANDLE_CODE(bref.pack(cu_up_pm_epc_present, 1)); + + HANDLE_CODE(plmn_id.pack(bref)); + if (cu_up_pm_minus5_gc_present) { + HANDLE_CODE(cu_up_pm_minus5_gc.pack(bref)); + } + if (cu_up_pm_epc_present) { + HANDLE_CODE(cu_up_pm_epc.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE plmn_id_list_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(cu_up_pm_minus5_gc_present, 1)); + HANDLE_CODE(bref.unpack(cu_up_pm_epc_present, 1)); + + HANDLE_CODE(plmn_id.unpack(bref)); + if (cu_up_pm_minus5_gc_present) { + HANDLE_CODE(cu_up_pm_minus5_gc.unpack(bref)); + } + if (cu_up_pm_epc_present) { + HANDLE_CODE(cu_up_pm_epc.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void plmn_id_list_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + if (cu_up_pm_minus5_gc_present) { + j.write_fieldname("cu-UP-PM-5GC"); + cu_up_pm_minus5_gc.to_json(j); + } + if (cu_up_pm_epc_present) { + j.write_fieldname("cu-UP-PM-EPC"); + cu_up_pm_epc.to_json(j); + } + j.end_obj(); +} + +// CUUPMeasurement-Container ::= SEQUENCE +SRSASN_CODE cuup_meas_container_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, plmn_list, 1, 12, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cuup_meas_container_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(plmn_list, bref, 1, 12, true)); + + return SRSASN_SUCCESS; +} +void cuup_meas_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("plmnList"); + for (const auto& e1 : plmn_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// FQIPERSlicesPerPlmnPerCellListItem ::= SEQUENCE +SRSASN_CODE fqiper_slices_per_plmn_per_cell_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(dl_prbusage_present, 1)); + HANDLE_CODE(bref.pack(ul_prbusage_present, 1)); + + HANDLE_CODE(pack_integer(bref, five_qi, (uint16_t)0u, (uint16_t)255u, false, true)); + if (dl_prbusage_present) { + HANDLE_CODE(pack_integer(bref, dl_prbusage, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_prbusage_present) { + HANDLE_CODE(pack_integer(bref, ul_prbusage, (uint8_t)0u, (uint8_t)100u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE fqiper_slices_per_plmn_per_cell_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(dl_prbusage_present, 1)); + HANDLE_CODE(bref.unpack(ul_prbusage_present, 1)); + + HANDLE_CODE(unpack_integer(five_qi, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + if (dl_prbusage_present) { + HANDLE_CODE(unpack_integer(dl_prbusage, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_prbusage_present) { + HANDLE_CODE(unpack_integer(ul_prbusage, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + + return SRSASN_SUCCESS; +} +void fqiper_slices_per_plmn_per_cell_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("fiveQI", five_qi); + if (dl_prbusage_present) { + j.write_int("dl-PRBUsage", dl_prbusage); + } + if (ul_prbusage_present) { + j.write_int("ul-PRBUsage", ul_prbusage); + } + j.end_obj(); +} + +// PerQCIReportListItem ::= SEQUENCE +SRSASN_CODE per_qci_report_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(dl_prbusage_present, 1)); + HANDLE_CODE(bref.pack(ul_prbusage_present, 1)); + + HANDLE_CODE(pack_integer(bref, qci, (uint16_t)0u, (uint16_t)255u, false, true)); + if (dl_prbusage_present) { + HANDLE_CODE(pack_integer(bref, dl_prbusage, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_prbusage_present) { + HANDLE_CODE(pack_integer(bref, ul_prbusage, (uint8_t)0u, (uint8_t)100u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE per_qci_report_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(dl_prbusage_present, 1)); + HANDLE_CODE(bref.unpack(ul_prbusage_present, 1)); + + HANDLE_CODE(unpack_integer(qci, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + if (dl_prbusage_present) { + HANDLE_CODE(unpack_integer(dl_prbusage, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_prbusage_present) { + HANDLE_CODE(unpack_integer(ul_prbusage, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + + return SRSASN_SUCCESS; +} +void per_qci_report_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("qci", qci); + if (dl_prbusage_present) { + j.write_int("dl-PRBUsage", dl_prbusage); + } + if (ul_prbusage_present) { + j.write_int("ul-PRBUsage", ul_prbusage); + } + j.end_obj(); +} + +// SlicePerPlmnPerCellListItem ::= SEQUENCE +SRSASN_CODE slice_per_plmn_per_cell_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(slice_id.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, fqiper_slices_per_plmn_per_cell_list, 1, 64, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE slice_per_plmn_per_cell_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(slice_id.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(fqiper_slices_per_plmn_per_cell_list, bref, 1, 64, true)); + + return SRSASN_SUCCESS; +} +void slice_per_plmn_per_cell_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("sliceID"); + slice_id.to_json(j); + j.start_array("fQIPERSlicesPerPlmnPerCellList"); + for (const auto& e1 : fqiper_slices_per_plmn_per_cell_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// EPC-DU-PM-Container ::= SEQUENCE +SRSASN_CODE epc_du_pm_container_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, per_qci_report_list, 1, 256, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE epc_du_pm_container_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(per_qci_report_list, bref, 1, 256, true)); + + return SRSASN_SUCCESS; +} +void epc_du_pm_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("perQCIReportList"); + for (const auto& e1 : per_qci_report_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// FGC-DU-PM-Container ::= SEQUENCE +SRSASN_CODE fgc_du_pm_container_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, slice_per_plmn_per_cell_list, 1, 1024, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE fgc_du_pm_container_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(slice_per_plmn_per_cell_list, bref, 1, 1024, true)); + + return SRSASN_SUCCESS; +} +void fgc_du_pm_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("slicePerPlmnPerCellList"); + for (const auto& e1 : slice_per_plmn_per_cell_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// NRCGI ::= SEQUENCE +SRSASN_CODE nrcgi_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(nrcell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nrcgi_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(nrcell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void nrcgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_str("nRCellIdentity", nrcell_id.to_string()); + j.end_obj(); +} + +// ServedPlmnPerCellListItem ::= SEQUENCE +SRSASN_CODE served_plmn_per_cell_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(du_pm_minus5_gc_present, 1)); + HANDLE_CODE(bref.pack(du_pm_epc_present, 1)); + + HANDLE_CODE(plmn_id.pack(bref)); + if (du_pm_minus5_gc_present) { + HANDLE_CODE(du_pm_minus5_gc.pack(bref)); + } + if (du_pm_epc_present) { + HANDLE_CODE(du_pm_epc.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE served_plmn_per_cell_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(du_pm_minus5_gc_present, 1)); + HANDLE_CODE(bref.unpack(du_pm_epc_present, 1)); + + HANDLE_CODE(plmn_id.unpack(bref)); + if (du_pm_minus5_gc_present) { + HANDLE_CODE(du_pm_minus5_gc.unpack(bref)); + } + if (du_pm_epc_present) { + HANDLE_CODE(du_pm_epc.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void served_plmn_per_cell_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + if (du_pm_minus5_gc_present) { + j.write_fieldname("du-PM-5GC"); + du_pm_minus5_gc.to_json(j); + } + if (du_pm_epc_present) { + j.write_fieldname("du-PM-EPC"); + du_pm_epc.to_json(j); + } + j.end_obj(); +} + +// CellResourceReportListItem ::= SEQUENCE +SRSASN_CODE cell_res_report_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(dl_totalof_available_prbs_present, 1)); + HANDLE_CODE(bref.pack(ul_totalof_available_prbs_present, 1)); + + HANDLE_CODE(nrcgi.pack(bref)); + if (dl_totalof_available_prbs_present) { + HANDLE_CODE(pack_integer(bref, dl_totalof_available_prbs, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_totalof_available_prbs_present) { + HANDLE_CODE(pack_integer(bref, ul_totalof_available_prbs, (uint8_t)0u, (uint8_t)100u, false, true)); + } + HANDLE_CODE(pack_dyn_seq_of(bref, served_plmn_per_cell_list, 1, 12, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cell_res_report_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(dl_totalof_available_prbs_present, 1)); + HANDLE_CODE(bref.unpack(ul_totalof_available_prbs_present, 1)); + + HANDLE_CODE(nrcgi.unpack(bref)); + if (dl_totalof_available_prbs_present) { + HANDLE_CODE(unpack_integer(dl_totalof_available_prbs, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_totalof_available_prbs_present) { + HANDLE_CODE(unpack_integer(ul_totalof_available_prbs, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + HANDLE_CODE(unpack_dyn_seq_of(served_plmn_per_cell_list, bref, 1, 12, true)); + + return SRSASN_SUCCESS; +} +void cell_res_report_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("nRCGI"); + nrcgi.to_json(j); + if (dl_totalof_available_prbs_present) { + j.write_int("dl-TotalofAvailablePRBs", dl_totalof_available_prbs); + } + if (ul_totalof_available_prbs_present) { + j.write_int("ul-TotalofAvailablePRBs", ul_totalof_available_prbs); + } + j.start_array("servedPlmnPerCellList"); + for (const auto& e1 : served_plmn_per_cell_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// GUAMI ::= SEQUENCE +SRSASN_CODE guami_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(amf_region_id.pack(bref)); + HANDLE_CODE(amf_set_id.pack(bref)); + HANDLE_CODE(amf_pointer.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE guami_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(amf_region_id.unpack(bref)); + HANDLE_CODE(amf_set_id.unpack(bref)); + HANDLE_CODE(amf_pointer.unpack(bref)); + + return SRSASN_SUCCESS; +} +void guami_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("aMFRegionID", amf_region_id.to_string()); + j.write_str("aMFSetID", amf_set_id.to_string()); + j.write_str("aMFPointer", amf_pointer.to_string()); + j.end_obj(); +} + +// GUMMEI ::= SEQUENCE +SRSASN_CODE gummei_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(mme_group_id.pack(bref)); + HANDLE_CODE(mme_code.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE gummei_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(mme_group_id.unpack(bref)); + HANDLE_CODE(mme_code.unpack(bref)); + + return SRSASN_SUCCESS; +} +void gummei_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_str("mME-Group-ID", mme_group_id.to_string()); + j.write_str("mME-Code", mme_code.to_string()); + j.end_obj(); +} + +// CoreCPID ::= CHOICE +void core_cpid_c::destroy_() +{ + switch (type_) { + case types::five_gc: + c.destroy(); + break; + case types::epc: + c.destroy(); + break; + default: + break; + } +} +void core_cpid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::five_gc: + c.init(); + break; + case types::epc: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c::core_cpid_c(const core_cpid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c& core_cpid_c::operator=(const core_cpid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + + return *this; +} +guami_s& core_cpid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +gummei_s& core_cpid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void core_cpid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_fieldname("fiveGC"); + c.get().to_json(j); + break; + case types::epc: + j.write_fieldname("ePC"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + j.end_obj(); +} +SRSASN_CODE core_cpid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE core_cpid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* core_cpid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "core_cpid_c::types"); +} +uint8_t core_cpid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "core_cpid_c::types"); +} + +// E2SM-KPM-e2_sm_kpm_action_definition_s ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_style_type, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_style_type, bref, false, true)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-Style-Type", ric_style_type); + j.end_obj(); +} + +// RT-Period-IE ::= ENUMERATED +const char* rt_period_ie_opts::to_string() const +{ + static const char* options[] = {"ms10", "ms20", "ms32", "ms40", "ms60", "ms64", "ms70", + "ms80", "ms128", "ms160", "ms256", "ms320", "ms512", "ms640", + "ms1024", "ms1280", "ms2048", "ms2560", "ms5120", "ms10240"}; + return convert_enum_idx(options, 20, value, "rt_period_ie_e"); +} +uint16_t rt_period_ie_opts::to_number() const +{ + static const uint16_t options[] = {10, 20, 32, 40, 60, 64, 70, 80, 128, 160, + 256, 320, 512, 640, 1024, 1280, 2048, 2560, 5120, 10240}; + return map_enum_number(options, 20, value, "rt_period_ie_e"); +} + +// Trigger-ConditionIE-Item ::= SEQUENCE +SRSASN_CODE trigger_condition_ie_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(report_period_ie.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE trigger_condition_ie_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(report_period_ie.unpack(bref)); + + return SRSASN_SUCCESS; +} +void trigger_condition_ie_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("report-Period-IE", report_period_ie.to_string()); + j.end_obj(); +} + +// E2SM-KPM-EventTriggerDefinition-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_event_trigger_definition_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(policy_test_list.size() > 0, 1)); + + if (policy_test_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, policy_test_list, 1, 15, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool policy_test_list_present; + HANDLE_CODE(bref.unpack(policy_test_list_present, 1)); + + if (policy_test_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(policy_test_list, bref, 1, 15, true)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_event_trigger_definition_format1_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (policy_test_list.size() > 0) { + j.start_array("policyTest-List"); + for (const auto& e1 : policy_test_list) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// E2SM-KPM-EventTriggerDefinition ::= CHOICE +void e2_sm_kpm_event_trigger_definition_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("eventDefinition-Format1"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "e2_sm_kpm_event_trigger_definition_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_event_trigger_definition_c::types_opts::to_string() const +{ + static const char* options[] = {"eventDefinition-Format1"}; + return convert_enum_idx(options, 1, value, "e2_sm_kpm_event_trigger_definition_c::types"); +} +uint8_t e2_sm_kpm_event_trigger_definition_c::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "e2_sm_kpm_event_trigger_definition_c::types"); +} + +// ENB-ID ::= CHOICE +void enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_enb_id: + c.destroy >(); + break; + case types::home_enb_id: + c.destroy >(); + break; + case types::short_macro_enb_id: + c.destroy >(); + break; + case types::long_macro_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_enb_id: + c.init >(); + break; + case types::home_enb_id: + c.init >(); + break; + case types::short_macro_enb_id: + c.init >(); + break; + case types::long_macro_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c::enb_id_c(const enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_enb_id: + c.init(other.c.get >()); + break; + case types::home_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c& enb_id_c::operator=(const enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_enb_id: + c.set(other.c.get >()); + break; + case types::home_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_c::set_macro_enb_id() +{ + set(types::macro_enb_id); + return c.get >(); +} +fixed_bitstring<28, false, true>& enb_id_c::set_home_enb_id() +{ + set(types::home_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_c::set_short_macro_enb_id() +{ + set(types::short_macro_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_c::set_long_macro_enb_id() +{ + set(types::long_macro_enb_id); + return c.get >(); +} +void enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_enb_id: + j.write_str("macro-eNB-ID", c.get >().to_string()); + break; + case types::home_enb_id: + j.write_str("home-eNB-ID", c.get >().to_string()); + break; + case types::short_macro_enb_id: + j.write_str("short-Macro-eNB-ID", c.get >().to_string()); + break; + case types::long_macro_enb_id: + j.write_str("long-Macro-eNB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macro-eNB-ID", "home-eNB-ID", "short-Macro-eNB-ID", "long-Macro-eNB-ID"}; + return convert_enum_idx(options, 4, value, "enb_id_c::types"); +} + +// ENB-ID-Choice ::= CHOICE +void enb_id_choice_c::destroy_() +{ + switch (type_) { + case types::enb_id_macro: + c.destroy >(); + break; + case types::enb_id_shortmacro: + c.destroy >(); + break; + case types::enb_id_longmacro: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_choice_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::enb_id_macro: + c.init >(); + break; + case types::enb_id_shortmacro: + c.init >(); + break; + case types::enb_id_longmacro: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } +} +enb_id_choice_c::enb_id_choice_c(const enb_id_choice_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::enb_id_macro: + c.init(other.c.get >()); + break; + case types::enb_id_shortmacro: + c.init(other.c.get >()); + break; + case types::enb_id_longmacro: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } +} +enb_id_choice_c& enb_id_choice_c::operator=(const enb_id_choice_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::enb_id_macro: + c.set(other.c.get >()); + break; + case types::enb_id_shortmacro: + c.set(other.c.get >()); + break; + case types::enb_id_longmacro: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_choice_c::set_enb_id_macro() +{ + set(types::enb_id_macro); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_choice_c::set_enb_id_shortmacro() +{ + set(types::enb_id_shortmacro); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_choice_c::set_enb_id_longmacro() +{ + set(types::enb_id_longmacro); + return c.get >(); +} +void enb_id_choice_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::enb_id_macro: + j.write_str("enb-ID-macro", c.get >().to_string()); + break; + case types::enb_id_shortmacro: + j.write_str("enb-ID-shortmacro", c.get >().to_string()); + break; + case types::enb_id_longmacro: + j.write_str("enb-ID-longmacro", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_choice_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::enb_id_macro: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::enb_id_shortmacro: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::enb_id_longmacro: + HANDLE_CODE((c.get >().pack(bref))); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_choice_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::enb_id_macro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::enb_id_shortmacro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::enb_id_longmacro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_choice_c::types_opts::to_string() const +{ + static const char* options[] = {"enb-ID-macro", "enb-ID-shortmacro", "enb-ID-longmacro"}; + return convert_enum_idx(options, 3, value, "enb_id_choice_c::types"); +} + +// ENGNB-ID ::= CHOICE +void engnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE engnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE engnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "engnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* engnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB-ID"}; + return convert_enum_idx(options, 1, value, "engnb_id_c::types"); +} + +// GNB-ID-Choice ::= CHOICE +void gnb_id_choice_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gnb-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE gnb_id_choice_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE gnb_id_choice_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "gnb_id_choice_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* gnb_id_choice_c::types_opts::to_string() const +{ + static const char* options[] = {"gnb-ID"}; + return convert_enum_idx(options, 1, value, "gnb_id_choice_c::types"); +} + +// GlobalENB-ID ::= SEQUENCE +SRSASN_CODE global_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("eNB-ID"); + enb_id.to_json(j); + j.end_obj(); +} + +// GlobalenGNB-ID ::= SEQUENCE +SRSASN_CODE globalen_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalen_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalen_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("gNB-ID"); + gnb_id.to_json(j); + j.end_obj(); +} + +// GlobalgNB-ID ::= SEQUENCE +SRSASN_CODE globalg_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalg_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalg_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("plmn-id", plmn_id.to_string()); + j.write_fieldname("gnb-id"); + gnb_id.to_json(j); + j.end_obj(); +} + +// GlobalngeNB-ID ::= SEQUENCE +SRSASN_CODE globalngenb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalngenb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalngenb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("plmn-id", plmn_id.to_string()); + j.write_fieldname("enb-id"); + enb_id.to_json(j); + j.end_obj(); +} + +// GlobalKPMnode-eNB-ID ::= SEQUENCE +SRSASN_CODE global_kp_mnode_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_kp_mnode_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_kp_mnode_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-eNB-ID"); + global_enb_id.to_json(j); + j.end_obj(); +} + +// GlobalKPMnode-en-gNB-ID ::= SEQUENCE +SRSASN_CODE global_kp_mnode_en_g_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_g_nb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_kp_mnode_en_g_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_g_nb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_kp_mnode_en_g_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-gNB-ID"); + global_g_nb_id.to_json(j); + j.end_obj(); +} + +// GlobalKPMnode-gNB-ID ::= SEQUENCE +SRSASN_CODE global_kp_mnode_g_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(gnb_cu_up_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_du_id_present, 1)); + + HANDLE_CODE(global_g_nb_id.pack(bref)); + if (gnb_cu_up_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (gnb_du_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_kp_mnode_g_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(gnb_cu_up_id_present, 1)); + HANDLE_CODE(bref.unpack(gnb_du_id_present, 1)); + + HANDLE_CODE(global_g_nb_id.unpack(bref)); + if (gnb_cu_up_id_present) { + HANDLE_CODE(unpack_integer(gnb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (gnb_du_id_present) { + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +void global_kp_mnode_g_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-gNB-ID"); + global_g_nb_id.to_json(j); + if (gnb_cu_up_id_present) { + j.write_int("gNB-CU-UP-ID", gnb_cu_up_id); + } + if (gnb_du_id_present) { + j.write_int("gNB-DU-ID", gnb_du_id); + } + j.end_obj(); +} + +// GlobalKPMnode-ng-eNB-ID ::= SEQUENCE +SRSASN_CODE global_kp_mnode_ng_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_kp_mnode_ng_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_kp_mnode_ng_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-ng-eNB-ID"); + global_ng_enb_id.to_json(j); + j.end_obj(); +} + +// GlobalKPMnode-ID ::= CHOICE +void global_kp_mnode_id_c::destroy_() +{ + switch (type_) { + case types::gnb: + c.destroy(); + break; + case types::en_g_nb: + c.destroy(); + break; + case types::ng_enb: + c.destroy(); + break; + case types::enb: + c.destroy(); + break; + default: + break; + } +} +void global_kp_mnode_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb: + c.init(); + break; + case types::en_g_nb: + c.init(); + break; + case types::ng_enb: + c.init(); + break; + case types::enb: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + } +} +global_kp_mnode_id_c::global_kp_mnode_id_c(const global_kp_mnode_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb: + c.init(other.c.get()); + break; + case types::en_g_nb: + c.init(other.c.get()); + break; + case types::ng_enb: + c.init(other.c.get()); + break; + case types::enb: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + } +} +global_kp_mnode_id_c& global_kp_mnode_id_c::operator=(const global_kp_mnode_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb: + c.set(other.c.get()); + break; + case types::en_g_nb: + c.set(other.c.get()); + break; + case types::ng_enb: + c.set(other.c.get()); + break; + case types::enb: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + } + + return *this; +} +global_kp_mnode_g_nb_id_s& global_kp_mnode_id_c::set_gnb() +{ + set(types::gnb); + return c.get(); +} +global_kp_mnode_en_g_nb_id_s& global_kp_mnode_id_c::set_en_g_nb() +{ + set(types::en_g_nb); + return c.get(); +} +global_kp_mnode_ng_enb_id_s& global_kp_mnode_id_c::set_ng_enb() +{ + set(types::ng_enb); + return c.get(); +} +global_kp_mnode_enb_id_s& global_kp_mnode_id_c::set_enb() +{ + set(types::enb); + return c.get(); +} +void global_kp_mnode_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb: + j.write_fieldname("gNB"); + c.get().to_json(j); + break; + case types::en_g_nb: + j.write_fieldname("en-gNB"); + c.get().to_json(j); + break; + case types::ng_enb: + j.write_fieldname("ng-eNB"); + c.get().to_json(j); + break; + case types::enb: + j.write_fieldname("eNB"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_kp_mnode_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::en_g_nb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::enb: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_kp_mnode_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::en_g_nb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::enb: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_kp_mnode_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB", "en-gNB", "ng-eNB", "eNB"}; + return convert_enum_idx(options, 4, value, "global_kp_mnode_id_c::types"); +} + +// E2SM-KPM-IndicationHeader-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_hdr_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(id_global_kp_mnode_id_present, 1)); + HANDLE_CODE(bref.pack(nrcgi_present, 1)); + HANDLE_CODE(bref.pack(plmn_id_present, 1)); + HANDLE_CODE(bref.pack(slice_id_present, 1)); + HANDLE_CODE(bref.pack(five_qi_present, 1)); + HANDLE_CODE(bref.pack(qci_present, 1)); + + if (id_global_kp_mnode_id_present) { + HANDLE_CODE(id_global_kp_mnode_id.pack(bref)); + } + if (nrcgi_present) { + HANDLE_CODE(nrcgi.pack(bref)); + } + if (plmn_id_present) { + HANDLE_CODE(plmn_id.pack(bref)); + } + if (slice_id_present) { + HANDLE_CODE(slice_id.pack(bref)); + } + if (five_qi_present) { + HANDLE_CODE(pack_integer(bref, five_qi, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qci_present) { + HANDLE_CODE(pack_integer(bref, qci, (uint16_t)0u, (uint16_t)255u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_hdr_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(id_global_kp_mnode_id_present, 1)); + HANDLE_CODE(bref.unpack(nrcgi_present, 1)); + HANDLE_CODE(bref.unpack(plmn_id_present, 1)); + HANDLE_CODE(bref.unpack(slice_id_present, 1)); + HANDLE_CODE(bref.unpack(five_qi_present, 1)); + HANDLE_CODE(bref.unpack(qci_present, 1)); + + if (id_global_kp_mnode_id_present) { + HANDLE_CODE(id_global_kp_mnode_id.unpack(bref)); + } + if (nrcgi_present) { + HANDLE_CODE(nrcgi.unpack(bref)); + } + if (plmn_id_present) { + HANDLE_CODE(plmn_id.unpack(bref)); + } + if (slice_id_present) { + HANDLE_CODE(slice_id.unpack(bref)); + } + if (five_qi_present) { + HANDLE_CODE(unpack_integer(five_qi, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qci_present) { + HANDLE_CODE(unpack_integer(qci, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_hdr_format1_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (id_global_kp_mnode_id_present) { + j.write_fieldname("id-GlobalKPMnode-ID"); + id_global_kp_mnode_id.to_json(j); + } + if (nrcgi_present) { + j.write_fieldname("nRCGI"); + nrcgi.to_json(j); + } + if (plmn_id_present) { + j.write_str("pLMN-Identity", plmn_id.to_string()); + } + if (slice_id_present) { + j.write_fieldname("sliceID"); + slice_id.to_json(j); + } + if (five_qi_present) { + j.write_int("fiveQI", five_qi); + } + if (qci_present) { + j.write_int("qci", qci); + } + j.end_obj(); +} + +// E2SM-KPM-IndicationHeader ::= CHOICE +void e2_sm_kpm_ind_hdr_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("indicationHeader-Format1"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_ind_hdr_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_hdr_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "e2_sm_kpm_ind_hdr_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_ind_hdr_c::types_opts::to_string() const +{ + static const char* options[] = {"indicationHeader-Format1"}; + return convert_enum_idx(options, 1, value, "e2_sm_kpm_ind_hdr_c::types"); +} +uint8_t e2_sm_kpm_ind_hdr_c::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "e2_sm_kpm_ind_hdr_c::types"); +} + +// NI-Type ::= ENUMERATED +const char* ni_type_opts::to_string() const +{ + static const char* options[] = {"x2-u", "xn-u", "f1-u"}; + return convert_enum_idx(options, 3, value, "ni_type_e"); +} +uint8_t ni_type_opts::to_number() const +{ + switch (value) { + case x2_u: + return 2; + case f1_u: + return 1; + default: + invalid_enum_number(value, "ni_type_e"); + } + return 0; +} + +// PF-ContainerListItem ::= SEQUENCE +SRSASN_CODE pf_container_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(interface_type.pack(bref)); + HANDLE_CODE(o_cu_up_pm_container.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE pf_container_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(interface_type.unpack(bref)); + HANDLE_CODE(o_cu_up_pm_container.unpack(bref)); + + return SRSASN_SUCCESS; +} +void pf_container_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("interface-type", interface_type.to_string()); + j.write_fieldname("o-CU-UP-PM-Container"); + o_cu_up_pm_container.to_json(j); + j.end_obj(); +} + +// OCUCP-PF-Container ::= SEQUENCE +SRSASN_CODE ocucp_pf_container_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(gnb_cu_cp_name_present, 1)); + + if (gnb_cu_cp_name_present) { + HANDLE_CODE(gnb_cu_cp_name.pack(bref)); + } + HANDLE_CODE(bref.pack(cu_cp_res_status.nof_active_ues_present, 1)); + if (cu_cp_res_status.nof_active_ues_present) { + HANDLE_CODE(pack_integer(bref, cu_cp_res_status.nof_active_ues, (uint32_t)1u, (uint32_t)65536u, true, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ocucp_pf_container_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(gnb_cu_cp_name_present, 1)); + + if (gnb_cu_cp_name_present) { + HANDLE_CODE(gnb_cu_cp_name.unpack(bref)); + } + HANDLE_CODE(bref.unpack(cu_cp_res_status.nof_active_ues_present, 1)); + if (cu_cp_res_status.nof_active_ues_present) { + HANDLE_CODE(unpack_integer(cu_cp_res_status.nof_active_ues, bref, (uint32_t)1u, (uint32_t)65536u, true, true)); + } + + return SRSASN_SUCCESS; +} +void ocucp_pf_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (gnb_cu_cp_name_present) { + j.write_str("gNB-CU-CP-Name", gnb_cu_cp_name.to_string()); + } + j.write_fieldname("cu-CP-Resource-Status"); + j.start_obj(); + if (cu_cp_res_status.nof_active_ues_present) { + j.write_int("numberOfActive-UEs", cu_cp_res_status.nof_active_ues); + } + j.end_obj(); + j.end_obj(); +} + +// OCUUP-PF-Container ::= SEQUENCE +SRSASN_CODE ocuup_pf_container_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(gnb_cu_up_name_present, 1)); + + if (gnb_cu_up_name_present) { + HANDLE_CODE(gnb_cu_up_name.pack(bref)); + } + HANDLE_CODE(pack_dyn_seq_of(bref, pf_container_list, 1, 3, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ocuup_pf_container_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(gnb_cu_up_name_present, 1)); + + if (gnb_cu_up_name_present) { + HANDLE_CODE(gnb_cu_up_name.unpack(bref)); + } + HANDLE_CODE(unpack_dyn_seq_of(pf_container_list, bref, 1, 3, true)); + + return SRSASN_SUCCESS; +} +void ocuup_pf_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (gnb_cu_up_name_present) { + j.write_str("gNB-CU-UP-Name", gnb_cu_up_name.to_string()); + } + j.start_array("pf-ContainerList"); + for (const auto& e1 : pf_container_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// ODU-PF-Container ::= SEQUENCE +SRSASN_CODE odu_pf_container_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, cell_res_report_list, 1, 512, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE odu_pf_container_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(cell_res_report_list, bref, 1, 512, true)); + + return SRSASN_SUCCESS; +} +void odu_pf_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("cellResourceReportList"); + for (const auto& e1 : cell_res_report_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// PF-Container ::= CHOICE +void pf_container_c::destroy_() +{ + switch (type_) { + case types::odu: + c.destroy(); + break; + case types::ocu_cp: + c.destroy(); + break; + case types::ocu_up: + c.destroy(); + break; + default: + break; + } +} +void pf_container_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::odu: + c.init(); + break; + case types::ocu_cp: + c.init(); + break; + case types::ocu_up: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + } +} +pf_container_c::pf_container_c(const pf_container_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::odu: + c.init(other.c.get()); + break; + case types::ocu_cp: + c.init(other.c.get()); + break; + case types::ocu_up: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + } +} +pf_container_c& pf_container_c::operator=(const pf_container_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::odu: + c.set(other.c.get()); + break; + case types::ocu_cp: + c.set(other.c.get()); + break; + case types::ocu_up: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + } + + return *this; +} +odu_pf_container_s& pf_container_c::set_odu() +{ + set(types::odu); + return c.get(); +} +ocucp_pf_container_s& pf_container_c::set_ocu_cp() +{ + set(types::ocu_cp); + return c.get(); +} +ocuup_pf_container_s& pf_container_c::set_ocu_up() +{ + set(types::ocu_up); + return c.get(); +} +void pf_container_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::odu: + j.write_fieldname("oDU"); + c.get().to_json(j); + break; + case types::ocu_cp: + j.write_fieldname("oCU-CP"); + c.get().to_json(j); + break; + case types::ocu_up: + j.write_fieldname("oCU-UP"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + } + j.end_obj(); +} +SRSASN_CODE pf_container_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::odu: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ocu_cp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ocu_up: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE pf_container_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::odu: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ocu_cp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ocu_up: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* pf_container_c::types_opts::to_string() const +{ + static const char* options[] = {"oDU", "oCU-CP", "oCU-UP"}; + return convert_enum_idx(options, 3, value, "pf_container_c::types"); +} + +// PM-Containers-List ::= SEQUENCE +SRSASN_CODE pm_containers_list_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(performance_container_present, 1)); + HANDLE_CODE(bref.pack(the_ran_container.size() > 0, 1)); + + if (performance_container_present) { + HANDLE_CODE(performance_container.pack(bref)); + } + if (the_ran_container.size() > 0) { + HANDLE_CODE(the_ran_container.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pm_containers_list_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(performance_container_present, 1)); + bool the_ran_container_present; + HANDLE_CODE(bref.unpack(the_ran_container_present, 1)); + + if (performance_container_present) { + HANDLE_CODE(performance_container.unpack(bref)); + } + if (the_ran_container_present) { + HANDLE_CODE(the_ran_container.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void pm_containers_list_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (performance_container_present) { + j.write_fieldname("performanceContainer"); + performance_container.to_json(j); + } + if (the_ran_container.size() > 0) { + j.write_str("theRANContainer", the_ran_container.to_string()); + } + j.end_obj(); +} + +// E2SM-KPM-IndicationMessage-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_msg_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, pm_containers, 1, 512, true)); + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(pm_containers, bref, 1, 512, true)); + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_msg_format1_s::to_json(json_writer& j) const +{ + j.start_array(); + j.start_obj(); + j.start_obj("E2SM-KPM-IndicationMessage-Format1"); + j.start_array("pm-Containers"); + for (const auto& e1 : pm_containers) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +// E2SM-KPM-IndicationMessage ::= CHOICE +void e2_sm_kpm_ind_msg_c::destroy_() +{ + switch (type_) { + case types::ind_msg_format1: + c.destroy(); + break; + default: + break; + } +} +void e2_sm_kpm_ind_msg_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ric_style_type: + break; + case types::ind_msg_format1: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + } +} +e2_sm_kpm_ind_msg_c::e2_sm_kpm_ind_msg_c(const e2_sm_kpm_ind_msg_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ric_style_type: + c.init(other.c.get()); + break; + case types::ind_msg_format1: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + } +} +e2_sm_kpm_ind_msg_c& e2_sm_kpm_ind_msg_c::operator=(const e2_sm_kpm_ind_msg_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ric_style_type: + c.set(other.c.get()); + break; + case types::ind_msg_format1: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + } + + return *this; +} +int64_t& e2_sm_kpm_ind_msg_c::set_ric_style_type() +{ + set(types::ric_style_type); + return c.get(); +} +e2_sm_kpm_ind_msg_format1_s& e2_sm_kpm_ind_msg_c::set_ind_msg_format1() +{ + set(types::ind_msg_format1); + return c.get(); +} +void e2_sm_kpm_ind_msg_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ric_style_type: + j.write_int("ric-Style-Type", c.get()); + break; + case types::ind_msg_format1: + j.write_fieldname("indicationMessage-Format1"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_ind_msg_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ric_style_type: + HANDLE_CODE(pack_unconstrained_integer(bref, c.get(), false, true)); + break; + case types::ind_msg_format1: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ric_style_type: + HANDLE_CODE(unpack_unconstrained_integer(c.get(), bref, false, true)); + break; + case types::ind_msg_format1: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_ind_msg_c::types_opts::to_string() const +{ + static const char* options[] = {"ric-Style-Type", "indicationMessage-Format1"}; + return convert_enum_idx(options, 2, value, "e2_sm_kpm_ind_msg_c::types"); +} +uint8_t e2_sm_kpm_ind_msg_c::types_opts::to_number() const +{ + if (value == ind_msg_format1) { + return 1; + } + invalid_enum_number(value, "e2_sm_kpm_ind_msg_c::types"); + return 0; +} + +// RANfunction-Name ::= SEQUENCE +SRSASN_CODE ra_nfunction_name_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_function_instance_present, 1)); + + HANDLE_CODE(ran_function_short_name.pack(bref)); + HANDLE_CODE(ran_function_e2_sm_oid.pack(bref)); + HANDLE_CODE(ran_function_description.pack(bref)); + if (ran_function_instance_present) { + HANDLE_CODE(pack_unconstrained_integer(bref, ran_function_instance, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_name_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_function_instance_present, 1)); + + HANDLE_CODE(ran_function_short_name.unpack(bref)); + HANDLE_CODE(ran_function_e2_sm_oid.unpack(bref)); + HANDLE_CODE(ran_function_description.unpack(bref)); + if (ran_function_instance_present) { + HANDLE_CODE(unpack_unconstrained_integer(ran_function_instance, bref, false, true)); + } + + return SRSASN_SUCCESS; +} +void ra_nfunction_name_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ranFunction-ShortName", ran_function_short_name.to_string()); + j.write_str("ranFunction-E2SM-OID", ran_function_e2_sm_oid.to_string()); + j.write_str("ranFunction-Description", ran_function_description.to_string()); + if (ran_function_instance_present) { + j.write_int("ranFunction-Instance", ran_function_instance); + } + j.end_obj(); +} + +// RIC-EventTriggerStyle-List ::= SEQUENCE +SRSASN_CODE ric_event_trigger_style_list_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_event_trigger_style_type, false, true)); + HANDLE_CODE(ric_event_trigger_style_name.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_event_trigger_format_type, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ric_event_trigger_style_list_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_event_trigger_style_type, bref, false, true)); + HANDLE_CODE(ric_event_trigger_style_name.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(ric_event_trigger_format_type, bref, false, true)); + + return SRSASN_SUCCESS; +} +void ric_event_trigger_style_list_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-EventTriggerStyle-Type", ric_event_trigger_style_type); + j.write_str("ric-EventTriggerStyle-Name", ric_event_trigger_style_name.to_string()); + j.write_int("ric-EventTriggerFormat-Type", ric_event_trigger_format_type); + j.end_obj(); +} + +// RIC-ReportStyle-List ::= SEQUENCE +SRSASN_CODE ric_report_style_list_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_report_style_type, false, true)); + HANDLE_CODE(ric_report_style_name.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_ind_hdr_format_type, false, true)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_ind_msg_format_type, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ric_report_style_list_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_report_style_type, bref, false, true)); + HANDLE_CODE(ric_report_style_name.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(ric_ind_hdr_format_type, bref, false, true)); + HANDLE_CODE(unpack_unconstrained_integer(ric_ind_msg_format_type, bref, false, true)); + + return SRSASN_SUCCESS; +} +void ric_report_style_list_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-ReportStyle-Type", ric_report_style_type); + j.write_str("ric-ReportStyle-Name", ric_report_style_name.to_string()); + j.write_int("ric-IndicationHeaderFormat-Type", ric_ind_hdr_format_type); + j.write_int("ric-IndicationMessageFormat-Type", ric_ind_msg_format_type); + j.end_obj(); +} + +// E2SM-KPM-RANfunction-Description ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ra_nfunction_description_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ran_function_name.pack(bref)); + bref.pack(e2_sm_kpm_ra_nfunction_item.ext, 1); + HANDLE_CODE(bref.pack(e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(e2_sm_kpm_ra_nfunction_item.ric_report_style_list.size() > 0, 1)); + if (e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list, 1, 63, true)); + } + if (e2_sm_kpm_ra_nfunction_item.ric_report_style_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, e2_sm_kpm_ra_nfunction_item.ric_report_style_list, 1, 63, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ra_nfunction_description_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ran_function_name.unpack(bref)); + bref.unpack(e2_sm_kpm_ra_nfunction_item.ext, 1); + bool ric_event_trigger_style_list_present; + HANDLE_CODE(bref.unpack(ric_event_trigger_style_list_present, 1)); + bool ric_report_style_list_present; + HANDLE_CODE(bref.unpack(ric_report_style_list_present, 1)); + if (ric_event_trigger_style_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list, bref, 1, 63, true)); + } + if (ric_report_style_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(e2_sm_kpm_ra_nfunction_item.ric_report_style_list, bref, 1, 63, true)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ra_nfunction_description_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ranFunction-Name"); + ran_function_name.to_json(j); + j.write_fieldname("e2SM-KPM-RANfunction-Item"); + j.start_obj(); + if (e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list.size() > 0) { + j.start_array("ric-EventTriggerStyle-List"); + for (const auto& e1 : e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list) { + e1.to_json(j); + } + j.end_array(); + } + if (e2_sm_kpm_ra_nfunction_item.ric_report_style_list.size() > 0) { + j.start_array("ric-ReportStyle-List"); + for (const auto& e1 : e2_sm_kpm_ra_nfunction_item.ric_report_style_list) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); + j.end_obj(); +} + +// GNB-ID ::= CHOICE +void gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB-ID"}; + return convert_enum_idx(options, 1, value, "gnb_id_c::types"); +} + +// GlobalGNB-ID ::= SEQUENCE +SRSASN_CODE global_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("gNB-ID"); + gnb_id.to_json(j); + j.end_obj(); +} + +// NgENB-ID ::= CHOICE +void ng_enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_ng_enb_id: + c.destroy >(); + break; + case types::short_macro_ng_enb_id: + c.destroy >(); + break; + case types::long_macro_ng_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void ng_enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_ng_enb_id: + c.init >(); + break; + case types::short_macro_ng_enb_id: + c.init >(); + break; + case types::long_macro_ng_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c::ng_enb_id_c(const ng_enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c& ng_enb_id_c::operator=(const ng_enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& ng_enb_id_c::set_macro_ng_enb_id() +{ + set(types::macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& ng_enb_id_c::set_short_macro_ng_enb_id() +{ + set(types::short_macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& ng_enb_id_c::set_long_macro_ng_enb_id() +{ + set(types::long_macro_ng_enb_id); + return c.get >(); +} +void ng_enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_ng_enb_id: + j.write_str("macroNgENB-ID", c.get >().to_string()); + break; + case types::short_macro_ng_enb_id: + j.write_str("shortMacroNgENB-ID", c.get >().to_string()); + break; + case types::long_macro_ng_enb_id: + j.write_str("longMacroNgENB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE ng_enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ng_enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ng_enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macroNgENB-ID", "shortMacroNgENB-ID", "longMacroNgENB-ID"}; + return convert_enum_idx(options, 3, value, "ng_enb_id_c::types"); +} + +// GlobalNgENB-ID ::= SEQUENCE +SRSASN_CODE global_ng_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(ng_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ng_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(ng_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_ng_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("ngENB-ID"); + ng_enb_id.to_json(j); + j.end_obj(); +} + +// GlobalRANNodeID ::= CHOICE +void global_ran_node_id_c::destroy_() +{ + switch (type_) { + case types::global_gnb_id: + c.destroy(); + break; + case types::global_ng_enb_id: + c.destroy(); + break; + default: + break; + } +} +void global_ran_node_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_gnb_id: + c.init(); + break; + case types::global_ng_enb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c::global_ran_node_id_c(const global_ran_node_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_gnb_id: + c.init(other.c.get()); + break; + case types::global_ng_enb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c& global_ran_node_id_c::operator=(const global_ran_node_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_gnb_id: + c.set(other.c.get()); + break; + case types::global_ng_enb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + + return *this; +} +global_gnb_id_s& global_ran_node_id_c::set_global_gnb_id() +{ + set(types::global_gnb_id); + return c.get(); +} +global_ng_enb_id_s& global_ran_node_id_c::set_global_ng_enb_id() +{ + set(types::global_ng_enb_id); + return c.get(); +} +void global_ran_node_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_gnb_id: + j.write_fieldname("globalGNB-ID"); + c.get().to_json(j); + break; + case types::global_ng_enb_id: + j.write_fieldname("globalNgENB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_ran_node_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ran_node_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_ran_node_id_c::types_opts::to_string() const +{ + static const char* options[] = {"globalGNB-ID", "globalNgENB-ID"}; + return convert_enum_idx(options, 2, value, "global_ran_node_id_c::types"); +} + +// EN-GNB-ID ::= CHOICE +void en_gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("en-gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE en_gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE en_gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "en_gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* en_gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"en-gNB-ID"}; + return convert_enum_idx(options, 1, value, "en_gnb_id_c::types"); +} + +// GroupID ::= CHOICE +void group_id_c::destroy_() {} +void group_id_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +group_id_c::group_id_c(const group_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } +} +group_id_c& group_id_c::operator=(const group_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + + return *this; +} +uint16_t& group_id_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& group_id_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void group_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + j.end_obj(); +} +SRSASN_CODE group_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE group_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* group_id_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "group_id_c::types"); +} +uint8_t group_id_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "group_id_c::types"); +} + +// InterfaceID-E1 ::= SEQUENCE +SRSASN_CODE interface_id_e1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_e1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_e1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-CU-UP-ID", gnb_cu_up_id); + j.end_obj(); +} + +// InterfaceID-F1 ::= SEQUENCE +SRSASN_CODE interface_id_f1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_f1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_f1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-DU-ID", gnb_du_id); + j.end_obj(); +} + +// InterfaceID-NG ::= SEQUENCE +SRSASN_CODE interface_id_ng_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(guami.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_ng_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(guami.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_ng_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("guami"); + guami.to_json(j); + j.end_obj(); +} + +// InterfaceID-S1 ::= SEQUENCE +SRSASN_CODE interface_id_s1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(gummei.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_s1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(gummei.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_s1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + j.end_obj(); +} + +// InterfaceID-W1 ::= SEQUENCE +SRSASN_CODE interface_id_w1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_enb_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, ng_enb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_w1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + HANDLE_CODE(unpack_integer(ng_enb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_w1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-ng-eNB-ID"); + global_ng_enb_id.to_json(j); + j.write_int("ng-eNB-DU-ID", ng_enb_du_id); + j.end_obj(); +} + +// InterfaceID-X2 ::= SEQUENCE +SRSASN_CODE interface_id_x2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(node_type.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(node_type.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_x2_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("nodeType"); + node_type.to_json(j); + j.end_obj(); +} + +void interface_id_x2_s::node_type_c_::destroy_() +{ + switch (type_) { + case types::global_enb_id: + c.destroy(); + break; + case types::global_en_g_nb_id: + c.destroy(); + break; + default: + break; + } +} +void interface_id_x2_s::node_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_enb_id: + c.init(); + break; + case types::global_en_g_nb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_::node_type_c_(const interface_id_x2_s::node_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_enb_id: + c.init(other.c.get()); + break; + case types::global_en_g_nb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_& +interface_id_x2_s::node_type_c_::operator=(const interface_id_x2_s::node_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_enb_id: + c.set(other.c.get()); + break; + case types::global_en_g_nb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + + return *this; +} +global_enb_id_s& interface_id_x2_s::node_type_c_::set_global_enb_id() +{ + set(types::global_enb_id); + return c.get(); +} +globalen_gnb_id_s& interface_id_x2_s::node_type_c_::set_global_en_g_nb_id() +{ + set(types::global_en_g_nb_id); + return c.get(); +} +void interface_id_x2_s::node_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_enb_id: + j.write_fieldname("global-eNB-ID"); + c.get().to_json(j); + break; + case types::global_en_g_nb_id: + j.write_fieldname("global-en-gNB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_x2_s::node_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::node_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_x2_s::node_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"global-eNB-ID", "global-en-gNB-ID"}; + return convert_enum_idx(options, 2, value, "interface_id_x2_s::node_type_c_::types"); +} + +// InterfaceID-Xn ::= SEQUENCE +SRSASN_CODE interface_id_xn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_xn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_xn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.end_obj(); +} + +// InterfaceIdentifier ::= CHOICE +void interface_id_c::destroy_() +{ + switch (type_) { + case types::ng: + c.destroy(); + break; + case types::xn: + c.destroy(); + break; + case types::f1: + c.destroy(); + break; + case types::e1: + c.destroy(); + break; + case types::s1: + c.destroy(); + break; + case types::x2: + c.destroy(); + break; + case types::w1: + c.destroy(); + break; + default: + break; + } +} +void interface_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ng: + c.init(); + break; + case types::xn: + c.init(); + break; + case types::f1: + c.init(); + break; + case types::e1: + c.init(); + break; + case types::s1: + c.init(); + break; + case types::x2: + c.init(); + break; + case types::w1: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c::interface_id_c(const interface_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ng: + c.init(other.c.get()); + break; + case types::xn: + c.init(other.c.get()); + break; + case types::f1: + c.init(other.c.get()); + break; + case types::e1: + c.init(other.c.get()); + break; + case types::s1: + c.init(other.c.get()); + break; + case types::x2: + c.init(other.c.get()); + break; + case types::w1: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c& interface_id_c::operator=(const interface_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ng: + c.set(other.c.get()); + break; + case types::xn: + c.set(other.c.get()); + break; + case types::f1: + c.set(other.c.get()); + break; + case types::e1: + c.set(other.c.get()); + break; + case types::s1: + c.set(other.c.get()); + break; + case types::x2: + c.set(other.c.get()); + break; + case types::w1: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + + return *this; +} +interface_id_ng_s& interface_id_c::set_ng() +{ + set(types::ng); + return c.get(); +} +interface_id_xn_s& interface_id_c::set_xn() +{ + set(types::xn); + return c.get(); +} +interface_id_f1_s& interface_id_c::set_f1() +{ + set(types::f1); + return c.get(); +} +interface_id_e1_s& interface_id_c::set_e1() +{ + set(types::e1); + return c.get(); +} +interface_id_s1_s& interface_id_c::set_s1() +{ + set(types::s1); + return c.get(); +} +interface_id_x2_s& interface_id_c::set_x2() +{ + set(types::x2); + return c.get(); +} +interface_id_w1_s& interface_id_c::set_w1() +{ + set(types::w1); + return c.get(); +} +void interface_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ng: + j.write_fieldname("nG"); + c.get().to_json(j); + break; + case types::xn: + j.write_fieldname("xN"); + c.get().to_json(j); + break; + case types::f1: + j.write_fieldname("f1"); + c.get().to_json(j); + break; + case types::e1: + j.write_fieldname("e1"); + c.get().to_json(j); + break; + case types::s1: + j.write_fieldname("s1"); + c.get().to_json(j); + break; + case types::x2: + j.write_fieldname("x2"); + c.get().to_json(j); + break; + case types::w1: + j.write_fieldname("w1"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_c::types_opts::to_string() const +{ + static const char* options[] = {"nG", "xN", "f1", "e1", "s1", "x2", "w1"}; + return convert_enum_idx(options, 7, value, "interface_id_c::types"); +} + +// FreqBandNrItem ::= SEQUENCE +SRSASN_CODE freq_band_nr_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, freq_band_ind_nr, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE freq_band_nr_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(freq_band_ind_nr, bref, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +void freq_band_nr_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("freqBandIndicatorNr", freq_band_ind_nr); + j.end_obj(); +} + +// NR-ARFCN ::= SEQUENCE +SRSASN_CODE nr_arfcn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, nrarfcn, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list_nr, 1, 32, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_arfcn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(nrarfcn, bref, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(unpack_dyn_seq_of(freq_band_list_nr, bref, 1, 32, true)); + + return SRSASN_SUCCESS; +} +void nr_arfcn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("nRARFCN", nrarfcn); + j.start_array("freqBandListNr"); + for (const auto& e1 : freq_band_list_nr) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// QoSID ::= CHOICE +void qo_sid_c::destroy_() {} +void qo_sid_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +qo_sid_c::qo_sid_c(const qo_sid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } +} +qo_sid_c& qo_sid_c::operator=(const qo_sid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + + return *this; +} +uint16_t& qo_sid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& qo_sid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void qo_sid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + j.end_obj(); +} +SRSASN_CODE qo_sid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE qo_sid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* qo_sid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "qo_sid_c::types"); +} +uint8_t qo_sid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "qo_sid_c::types"); +} + +// RRCclass-LTE ::= ENUMERATED +const char* rr_cclass_lte_opts::to_string() const +{ + static const char* options[] = {"bCCH-BCH", + "bCCH-BCH-MBMS", + "bCCH-DL-SCH", + "bCCH-DL-SCH-BR", + "bCCH-DL-SCH-MBMS", + "mCCH", + "pCCH", + "dL-CCCH", + "dL-DCCH", + "uL-CCCH", + "uL-DCCH", + "sC-MCCH"}; + return convert_enum_idx(options, 12, value, "rr_cclass_lte_e"); +} + +// RRCclass-NR ::= ENUMERATED +const char* rr_cclass_nr_opts::to_string() const +{ + static const char* options[] = { + "bCCH-BCH", "bCCH-DL-SCH", "dL-CCCH", "dL-DCCH", "pCCH", "uL-CCCH", "uL-CCCH1", "uL-DCCH"}; + return convert_enum_idx(options, 8, value, "rr_cclass_nr_e"); +} +uint8_t rr_cclass_nr_opts::to_number() const +{ + if (value == ul_ccch1) { + return 1; + } + invalid_enum_number(value, "rr_cclass_nr_e"); + return 0; +} + +// RRC-MessageID ::= SEQUENCE +SRSASN_CODE rrc_msg_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(rrc_type.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, msg_id, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(rrc_type.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(msg_id, bref, false, true)); + + return SRSASN_SUCCESS; +} +void rrc_msg_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("rrcType"); + rrc_type.to_json(j); + j.write_int("messageID", msg_id); + j.end_obj(); +} + +void rrc_msg_id_s::rrc_type_c_::destroy_() {} +void rrc_msg_id_s::rrc_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +rrc_msg_id_s::rrc_type_c_::rrc_type_c_(const rrc_msg_id_s::rrc_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::lte: + c.init(other.c.get()); + break; + case types::nr: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } +} +rrc_msg_id_s::rrc_type_c_& rrc_msg_id_s::rrc_type_c_::operator=(const rrc_msg_id_s::rrc_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::lte: + c.set(other.c.get()); + break; + case types::nr: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + + return *this; +} +rr_cclass_lte_e& rrc_msg_id_s::rrc_type_c_::set_lte() +{ + set(types::lte); + return c.get(); +} +rr_cclass_nr_e& rrc_msg_id_s::rrc_type_c_::set_nr() +{ + set(types::nr); + return c.get(); +} +void rrc_msg_id_s::rrc_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::lte: + j.write_str("lTE", c.get().to_string()); + break; + case types::nr: + j.write_str("nR", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_msg_id_s::rrc_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"lTE", "nR"}; + return convert_enum_idx(options, 2, value, "rrc_msg_id_s::rrc_type_c_::types"); +} + +// S-NSSAI ::= SEQUENCE +SRSASN_CODE s_nssai_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(sd_present, 1)); + + HANDLE_CODE(sst.pack(bref)); + if (sd_present) { + HANDLE_CODE(sd.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE s_nssai_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(sd_present, 1)); + + HANDLE_CODE(sst.unpack(bref)); + if (sd_present) { + HANDLE_CODE(sd.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void s_nssai_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("sST", sst.to_string()); + if (sd_present) { + j.write_str("sD", sd.to_string()); + } + j.end_obj(); +} + +// ServingCell-ARFCN ::= CHOICE +void serving_cell_arfcn_c::destroy_() +{ + switch (type_) { + case types::nr: + c.destroy(); + break; + default: + break; + } +} +void serving_cell_arfcn_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr: + c.init(); + break; + case types::eutra: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c::serving_cell_arfcn_c(const serving_cell_arfcn_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c& serving_cell_arfcn_c::operator=(const serving_cell_arfcn_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + + return *this; +} +nr_arfcn_s& serving_cell_arfcn_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint32_t& serving_cell_arfcn_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_arfcn_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_fieldname("nR"); + c.get().to_json(j); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_arfcn_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_arfcn_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_arfcn_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_arfcn_c::types"); +} + +// ServingCell-PCI ::= CHOICE +void serving_cell_pci_c::destroy_() {} +void serving_cell_pci_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +serving_cell_pci_c::serving_cell_pci_c(const serving_cell_pci_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } +} +serving_cell_pci_c& serving_cell_pci_c::operator=(const serving_cell_pci_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + + return *this; +} +uint16_t& serving_cell_pci_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint16_t& serving_cell_pci_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_pci_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_int("nR", c.get()); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_pci_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_pci_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_pci_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_pci_c::types"); +} + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_e1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + j.end_obj(); +} + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_f1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + j.end_obj(); +} + +// UEID-EN-GNB ::= SEQUENCE +SRSASN_CODE ueid_en_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.pack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_en_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_en_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + if (gnb_cu_ue_f1_ap_id_present) { + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-ENB ::= SEQUENCE +SRSASN_CODE ueid_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(global_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, mme_ue_s1ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.pack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(global_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(mme_ue_s1ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.unpack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("mME-UE-S1AP-ID", mme_ue_s1ap_id); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + if (m_enb_ue_x2ap_id_present) { + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + } + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + if (global_enb_id_present) { + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB ::= SEQUENCE +SRSASN_CODE ueid_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_gnb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_ue_f1_ap_id_list, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool gnb_cu_ue_f1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_list_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_gnb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_ue_f1_ap_id_list, bref, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-UE-F1AP-ID-List"); + for (const auto& e1 : gnb_cu_ue_f1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_gnb_id_present) { + j.write_fieldname("globalGNB-ID"); + global_gnb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB-CU-UP ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_up_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_up_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_up_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-GNB-DU ::= SEQUENCE +SRSASN_CODE ueid_gnb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-NG-ENB ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (ng_enb_cu_ue_w1_ap_id_present) { + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_ng_enb_id_present) { + j.write_fieldname("globalNgENB-ID"); + global_ng_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-NG-ENB-DU ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + j.end_obj(); +} + +// UEID ::= CHOICE +void ueid_c::destroy_() +{ + switch (type_) { + case types::gnb_ueid: + c.destroy(); + break; + case types::gnb_du_ueid: + c.destroy(); + break; + case types::gnb_cu_up_ueid: + c.destroy(); + break; + case types::ng_enb_ueid: + c.destroy(); + break; + case types::ng_enb_du_ueid: + c.destroy(); + break; + case types::en_g_nb_ueid: + c.destroy(); + break; + case types::enb_ueid: + c.destroy(); + break; + default: + break; + } +} +void ueid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb_ueid: + c.init(); + break; + case types::gnb_du_ueid: + c.init(); + break; + case types::gnb_cu_up_ueid: + c.init(); + break; + case types::ng_enb_ueid: + c.init(); + break; + case types::ng_enb_du_ueid: + c.init(); + break; + case types::en_g_nb_ueid: + c.init(); + break; + case types::enb_ueid: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c::ueid_c(const ueid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb_ueid: + c.init(other.c.get()); + break; + case types::gnb_du_ueid: + c.init(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.init(other.c.get()); + break; + case types::en_g_nb_ueid: + c.init(other.c.get()); + break; + case types::enb_ueid: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c& ueid_c::operator=(const ueid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb_ueid: + c.set(other.c.get()); + break; + case types::gnb_du_ueid: + c.set(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.set(other.c.get()); + break; + case types::en_g_nb_ueid: + c.set(other.c.get()); + break; + case types::enb_ueid: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + + return *this; +} +ueid_gnb_s& ueid_c::set_gnb_ueid() +{ + set(types::gnb_ueid); + return c.get(); +} +ueid_gnb_du_s& ueid_c::set_gnb_du_ueid() +{ + set(types::gnb_du_ueid); + return c.get(); +} +ueid_gnb_cu_up_s& ueid_c::set_gnb_cu_up_ueid() +{ + set(types::gnb_cu_up_ueid); + return c.get(); +} +ueid_ng_enb_s& ueid_c::set_ng_enb_ueid() +{ + set(types::ng_enb_ueid); + return c.get(); +} +ueid_ng_enb_du_s& ueid_c::set_ng_enb_du_ueid() +{ + set(types::ng_enb_du_ueid); + return c.get(); +} +ueid_en_gnb_s& ueid_c::set_en_g_nb_ueid() +{ + set(types::en_g_nb_ueid); + return c.get(); +} +ueid_enb_s& ueid_c::set_enb_ueid() +{ + set(types::enb_ueid); + return c.get(); +} +void ueid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb_ueid: + j.write_fieldname("gNB-UEID"); + c.get().to_json(j); + break; + case types::gnb_du_ueid: + j.write_fieldname("gNB-DU-UEID"); + c.get().to_json(j); + break; + case types::gnb_cu_up_ueid: + j.write_fieldname("gNB-CU-UP-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_ueid: + j.write_fieldname("ng-eNB-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_du_ueid: + j.write_fieldname("ng-eNB-DU-UEID"); + c.get().to_json(j); + break; + case types::en_g_nb_ueid: + j.write_fieldname("en-gNB-UEID"); + c.get().to_json(j); + break; + case types::enb_ueid: + j.write_fieldname("eNB-UEID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + j.end_obj(); +} +SRSASN_CODE ueid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ueid_c::types_opts::to_string() const +{ + static const char* options[] = { + "gNB-UEID", "gNB-DU-UEID", "gNB-CU-UP-UEID", "ng-eNB-UEID", "ng-eNB-DU-UEID", "en-gNB-UEID", "eNB-UEID"}; + return convert_enum_idx(options, 7, value, "ueid_c::types"); +} diff --git a/srsgnb/src/stack/ric/CMakeLists.txt b/srsgnb/src/stack/ric/CMakeLists.txt index 651b588fc..001db312a 100644 --- a/srsgnb/src/stack/ric/CMakeLists.txt +++ b/srsgnb/src/stack/ric/CMakeLists.txt @@ -1,5 +1,5 @@ -set(SOURCES ric_client.cc e2ap.cc) +set(SOURCES ric_client.cc e2ap.cc e2sm_kpm.cc) add_library(srsgnb_ric STATIC ${SOURCES}) -#target_link_libraries(srsgnb_ric srsran_asn1) +target_link_libraries(srsgnb_ric srsran_asn1 ric_e2) add_subdirectory(test) From cd442e57cac3b8f8fb23d2d45ec9b6c04bcc74d9 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 4 Jan 2023 15:49:51 +0100 Subject: [PATCH 016/167] e2ap: adding e2sm_kpm class to manage creation of e2sm_kpm messages, adding proper creation of RAN function definition in E2 setup request message --- srsgnb/hdr/stack/ric/e2ap.h | 11 ++++- srsgnb/hdr/stack/ric/e2sm_kpm.h | 33 +++++++++++++ srsgnb/src/stack/ric/e2ap.cc | 32 ++++++------- srsgnb/src/stack/ric/e2sm_kpm.cc | 66 ++++++++++++++++++++++++++ srsgnb/src/stack/ric/test/e2ap_test.cc | 17 ++++++- 5 files changed, 137 insertions(+), 22 deletions(-) create mode 100644 srsgnb/hdr/stack/ric/e2sm_kpm.h create mode 100644 srsgnb/src/stack/ric/e2sm_kpm.cc diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 1dcea7b03..b47d5d227 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -11,13 +11,16 @@ * */ +#include "e2sm_kpm.h" #include "srsran/asn1/e2ap.h" +#include "srsran/asn1/e2sm_kpm.h" #include "srsran/srsran.h" #ifndef RIC_E2AP_H #define RIC_E2AP_H using namespace asn1::e2ap; +using namespace asn1::e2sm_kpm; class e2ap { @@ -34,8 +37,12 @@ public: private: srslog::basic_logger& logger; - bool setup_response_received = false; - bool pending_subscription_request = false; + e2sm_kpm e2sm_; + bool setup_response_received = false; + bool pending_subscription_request = false; + int setup_procedure_transaction_id = 0; + uint64_t plmn_id = 3617847; + uint64_t gnb_id = 381210353; }; #endif /* RIC_E2AP_H */ diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h new file mode 100644 index 000000000..9e4e32872 --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -0,0 +1,33 @@ +/** + * + * \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/asn1/e2sm.h" +#include "srsran/asn1/e2sm_kpm.h" +#include "srsran/srsran.h" + +#ifndef RIC_E2SM_KPM_H +#define RIC_E2SM_KPM_H + +class e2sm_kpm +{ +public: + e2sm_kpm(srslog::basic_logger& logger_); + bool generate_ran_function_description(srsran::unique_byte_buffer_t& buf); + bool process_ric_action_definition(); + bool generate_indication_header(); + bool generate_indication_message(); + +private: + srslog::basic_logger& logger; +}; + +#endif /*E2SM_KPM*/ diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 174850138..6dea67906 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -2,7 +2,7 @@ #include "srsgnb/hdr/stack/ric/e2ap.h" #include "stdint.h" -e2ap::e2ap(srslog::basic_logger& logger) : logger(logger) {} +e2ap::e2ap(srslog::basic_logger& logger) : logger(logger), e2sm_(logger) {} e2_ap_pdu_c e2ap::generate_setup_request() { @@ -13,13 +13,12 @@ e2_ap_pdu_c e2ap::generate_setup_request() e2setup_request_s& setup = initmsg.value.e2setup_request(); setup->transaction_id.crit = asn1::crit_opts::reject; - setup->transaction_id.value.value = 1; + 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(); - setup->global_e2node_id.crit = asn1::crit_opts::reject; - auto& gnb_id = setup->global_e2node_id.value.set_gnb(); - // gnb_id.ext = true; - gnb_id.global_g_nb_id.plmn_id.from_number(3617847); - gnb_id.global_g_nb_id.gnb_id.gnb_id().from_number(381210353); + gnb_.global_g_nb_id.plmn_id.from_number(plmn_id); + gnb_.global_g_nb_id.gnb_id.gnb_id().from_number(gnb_id); setup->ra_nfunctions_added.crit = asn1::crit_opts::reject; auto& list = setup->ra_nfunctions_added.value; @@ -28,17 +27,14 @@ e2_ap_pdu_c e2ap::generate_setup_request() 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 = 0; - // TODO use E2SM to correctly generate this message - item.value().ra_nfunction_item().ran_function_definition.from_string( - "20C04F52414E2D4532534D2D4B504D0000054F494431323305004B504D206D6F6E69746F720860283861AAE33F0060000101070050657269" - "6F646963207265706F727401051401011D004F2D4455204D6561737572656D656E7420436F6E7461696E657220666F722074686520354743" - "20636F6E6E6563746564206465706C6F796D656E74010101010001021D004F2D4455204D6561737572656D656E7420436F6E7461696E6572" - "20666F72207468652045504320636F6E6E6563746564206465706C6F796D656E74010101010001031E804F2D43552D4350204D6561737572" - "656D656E7420436F6E7461696E657220666F72207468652035474320636F6E6E6563746564206465706C6F796D656E74010101010001041E" - "804F2D43552D4350204D6561737572656D656E7420436F6E7461696E657220666F72207468652045504320636F6E6E656374656420646570" - "6C6F796D656E74010101010001051E804F2D43552D5550204D6561737572656D656E7420436F6E7461696E657220666F7220746865203547" - "4320636F6E6E6563746564206465706C6F796D656E74010101010001061E804F2D43552D5550204D6561737572656D656E7420436F6E7461" - "696E657220666F72207468652045504320636F6E6E6563746564206465706C6F796D656E7401010101"); + + // pack E2SM-KPM-PDU into ran function definition + auto& ran_func_def = item.value().ra_nfunction_item().ran_function_definition; + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + e2sm_.generate_ran_function_description(buf); + ran_func_def.resize(buf->N_bytes); + std::copy(buf->msg, buf->msg + buf->N_bytes, ran_func_def.data()); + item.value().ra_nfunction_item().ran_function_oid.resize(1); setup->ra_nfunctions_added.value.push_back(item); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc new file mode 100644 index 000000000..d52872b28 --- /dev/null +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -0,0 +1,66 @@ +#include "srsgnb/hdr/stack/ric/e2sm_kpm.h" + +e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : logger(logger_) {} + +bool e2sm_kpm::generate_ran_function_description(srsran::unique_byte_buffer_t& buf) +{ + using namespace asn1::e2sm_kpm; + e2_sm_kpm_ra_nfunction_description_s e2sm_kpm_ra_nfunction_description; + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_instance_present = true; + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_instance = 0; + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_short_name.from_string("ORAN-E2SM-KPM"); + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_e2_sm_oid.from_string("OID123"); + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_description.from_string("KPM monitor"); + + 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"); + } + + 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) { + printf("Failed to pack TX E2 PDU\n"); + return false; + } + buf->N_bytes = bref.distance_bytes(); + return true; +} diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index 12a49da74..f21d5f191 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -72,10 +72,23 @@ void test_reference_e2ap_setup_request() 0x72, 0x65, 0x73, 0x70, 0x61, 0x72, 0x74}; asn1::cbit_ref bref(&e2ap_msg_foreign[0], sizeof(e2ap_msg_foreign)); - e2_ap_pdu_c pdu, pdu2; - asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref); + e2_ap_pdu_c pdu; + asn1::SRSASN_CODE unpack_ret = pdu.unpack(bref); TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); printf("Unpacked E2AP PDU %d\n", (int)unpack_ret); + auto& ran_func_data = pdu.init_msg() + .value.e2setup_request() + ->ra_nfunctions_added.value[0] + .value() + .ra_nfunction_item() + .ran_function_definition; + srsran::byte_buffer_t ran_function_def; + asn1::cbit_ref ran_func_bref(ran_function_def.msg, ran_function_def.get_tailroom()); + std::copy(ran_func_data.data(), ran_func_data.data() + ran_func_data.size(), ran_function_def.begin()); + e2_sm_kpm_ra_nfunction_description_s e2sm_kpm_ra_nfunction_description; + asn1::SRSASN_CODE nfunc_unpack = e2sm_kpm_ra_nfunction_description.unpack(ran_func_bref); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, nfunc_unpack); + printf("Unpacked E2SM PDU (KPM RAN function description) %d\n", (int)nfunc_unpack); } void test_native_e2ap_setup_request() From 07929b74f60c8d2cedf058d12b0200262d5b6583 Mon Sep 17 00:00:00 2001 From: yagoda Date: Mon, 9 Jan 2023 22:47:06 +0100 Subject: [PATCH 017/167] e2ap: add e2 setup response processing, add RANfunction storage functionality. --- srsgnb/hdr/stack/ric/e2ap.h | 14 ++++++++++++++ srsgnb/hdr/stack/ric/e2sm_kpm.h | 11 ++++++++++- srsgnb/src/stack/ric/e2ap.cc | 33 +++++++++++++++++++++++++++++--- srsgnb/src/stack/ric/e2sm_kpm.cc | 12 +++++++----- 4 files changed, 61 insertions(+), 9 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index b47d5d227..9e9003381 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -22,6 +22,18 @@ using namespace asn1::e2ap; using namespace asn1::e2sm_kpm; +typedef struct { + uint16_t ric_id; + uint16_t plmn_id; +} global_ric_id_t; + +typedef struct { + e2node_component_interface_type_e interface_type; + std::string amf_name; + std::string request_part; + std::string response_part; +} e2_node_component_t; + class e2ap { public: @@ -43,6 +55,8 @@ private: int setup_procedure_transaction_id = 0; uint64_t plmn_id = 3617847; uint64_t gnb_id = 381210353; + global_ric_id_t global_ric_id = {}; + std::map ran_functions; }; #endif /* RIC_E2AP_H */ diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 9e4e32872..40da47c33 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -17,11 +17,20 @@ #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; +}; + class e2sm_kpm { public: e2sm_kpm(srslog::basic_logger& logger_); - bool generate_ran_function_description(srsran::unique_byte_buffer_t& buf); + bool + generate_ran_function_description(int function_id, RANfunction_description desc, srsran::unique_byte_buffer_t& buf); bool process_ric_action_definition(); bool generate_indication_header(); bool generate_indication_message(); diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 6dea67906..705462dd9 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -26,12 +26,20 @@ e2_ap_pdu_c e2ap::generate_setup_request() 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 = 0; + item.value().ra_nfunction_item().ran_function_id = 0; + item.value().ra_nfunction_item().ran_function_revision = 1; // 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_instance = 0; + ran_functions[item.value().ra_nfunction_item().ran_function_id] = add_func; + auto& ran_func_def = item.value().ra_nfunction_item().ran_function_definition; srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); - e2sm_.generate_ran_function_description(buf); + e2sm_.generate_ran_function_description(item.value().ra_nfunction_item().ran_function_id, add_func, buf); ran_func_def.resize(buf->N_bytes); std::copy(buf->msg, buf->msg + buf->N_bytes, ran_func_def.data()); @@ -71,10 +79,29 @@ e2_ap_pdu_c e2ap::generate_subscription_response() action_admit_list[0].value().ri_caction_admitted_item().ric_action_id = 1; return pdu; } + int e2ap::process_setup_response(e2setup_resp_s setup_response) { setup_response_received = true; - // TODO process setup response + if (setup_procedure_transaction_id == setup_response->transaction_id.value.value) { + setup_procedure_transaction_id++; + } else { + logger.error("Received setup response with wrong transaction id"); + } + global_ric_id.plmn_id = setup_response->global_ric_id.value.plmn_id.to_number(); + global_ric_id.ric_id = setup_response->global_ric_id.value.ric_id.to_number(); + + if (setup_response->ra_nfunctions_accepted_present) { + for (int i = 0; i < (int)setup_response->ra_nfunctions_accepted.value.size(); i++) { + uint32_t ran_func_id = setup_response->ra_nfunctions_accepted.value[i]->ra_nfunction_id_item().ran_function_id; + if (ran_functions.find(ran_func_id) == ran_functions.end()) { + logger.error("Received setup response with unknown ran function id %d", ran_func_id); + } else { + logger.info("Received setup response with ran function id %d", ran_func_id); + ran_functions[ran_func_id].accepted = true; + } + } + } return 0; } diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index d52872b28..e2f6396e4 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -2,15 +2,17 @@ e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : logger(logger_) {} -bool e2sm_kpm::generate_ran_function_description(srsran::unique_byte_buffer_t& buf) +bool e2sm_kpm::generate_ran_function_description(int function_id, + RANfunction_description desc, + srsran::unique_byte_buffer_t& buf) { using namespace asn1::e2sm_kpm; e2_sm_kpm_ra_nfunction_description_s e2sm_kpm_ra_nfunction_description; e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_instance_present = true; - e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_instance = 0; - e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_short_name.from_string("ORAN-E2SM-KPM"); - e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_e2_sm_oid.from_string("OID123"); - e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_description.from_string("KPM monitor"); + 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 = From e2aa9aba858a9c37b55c0517d305564dfddc3e0b Mon Sep 17 00:00:00 2001 From: yagoda Date: Thu, 2 Feb 2023 17:03:27 +0100 Subject: [PATCH 018/167] e2sm: fixing function definition for e2 setup request --- srsgnb/src/stack/ric/e2ap.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 705462dd9..df5f5f69d 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -34,6 +34,7 @@ e2_ap_pdu_c e2ap::generate_setup_request() RANfunction_description add_func; add_func.function_desc = "KPM monitor"; add_func.function_shortname = "ORAN-E2SM-KPM"; + add_func.function_e2_sm_oid = "OID123"; add_func.function_instance = 0; ran_functions[item.value().ra_nfunction_item().ran_function_id] = add_func; From a599234bf7fce36a75dede7b5bdc23dd7a9329dd Mon Sep 17 00:00:00 2001 From: yagoda Date: Thu, 2 Feb 2023 17:26:47 +0100 Subject: [PATCH 019/167] e2ap, main: adding metrics interface for e2, parameterizing the startup of the RIC client --- srsenb/hdr/enb.h | 9 ++++++++ srsenb/src/CMakeLists.txt | 2 +- srsenb/src/enb.cc | 31 +++++++++++++++----------- srsenb/src/main.cc | 14 ++++++++++++ srsgnb/hdr/stack/ric/e2ap.h | 5 ++++- srsgnb/hdr/stack/ric/ric_client.h | 4 +++- srsgnb/src/stack/ric/e2ap.cc | 5 ++++- srsgnb/src/stack/ric/ric_client.cc | 5 +++-- srsgnb/src/stack/ric/test/e2ap_test.cc | 12 ++++++++-- 9 files changed, 66 insertions(+), 21 deletions(-) diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 3c42bb44c..2dc511f38 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -104,6 +104,12 @@ struct general_args_t { uint32_t rlf_release_timer_ms; }; +struct ric_args_t { + bool enable; + std::string ric_ip; + uint32_t ric_port; +}; + struct all_args_t { enb_args_t enb; enb_files_t enb_files; @@ -113,6 +119,7 @@ struct all_args_t { general_args_t general; phy_args_t phy; stack_args_t stack; + ric_args_t ric_client; gnb_stack_args_t nr_stack; }; @@ -137,6 +144,8 @@ public: void print_pool(); + bool enable_ric_client(srsenb::e2_interface_metrics* e2_metrics); + // eNodeB metrics interface bool get_metrics(enb_metrics_t* m) override; diff --git a/srsenb/src/CMakeLists.txt b/srsenb/src/CMakeLists.txt index b994c3c96..6f08b627d 100644 --- a/srsenb/src/CMakeLists.txt +++ b/srsenb/src/CMakeLists.txt @@ -24,7 +24,7 @@ endif (RPATH) add_library(enb_cfg_parser STATIC parser.cc enb_cfg_parser.cc) target_link_libraries(enb_cfg_parser srsran_common srsgnb_rrc_config_utils ${LIBCONFIGPP_LIBRARIES}) -add_executable(srsenb main.cc enb.cc metrics_stdout.cc metrics_csv.cc metrics_json.cc) +add_executable(srsenb main.cc enb.cc metrics_stdout.cc metrics_csv.cc metrics_json.cc metrics_e2.cc) set(SRSENB_SOURCES srsenb_phy srsenb_stack srsenb_common srsenb_s1ap srsenb_upper srsenb_mac srsenb_rrc srslog system) set(SRSRAN_SOURCES srsran_common srsran_mac srsran_phy srsran_gtpu srsran_rlc srsran_pdcp srsran_radio rrc_asn1 s1ap_asn1 enb_cfg_parser srslog support system) diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 0d4db990b..2294e3f11 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -118,16 +118,6 @@ int enb::init(const all_args_t& args_) ret = SRSRAN_ERROR; } } - std::unique_ptr tmp_ric_client = - std::unique_ptr(new srsenb::ric_client(srslog::fetch_basic_logger("RIC", log_sink, false))); - if (tmp_ric_client == nullptr) { - srsran::console("Error creating RIC client instance.\n"); - return SRSRAN_ERROR; - } - if (tmp_ric_client->init()) { - srsran::console("Error initializing RIC client.\n"); - return SRSRAN_ERROR; - } if (tmp_eutra_stack) { eutra_stack = std::move(tmp_eutra_stack); @@ -135,9 +125,8 @@ int enb::init(const all_args_t& args_) if (tmp_nr_stack) { nr_stack = std::move(tmp_nr_stack); } - phy = std::move(tmp_phy); - radio = std::move(tmp_radio); - ric = std::move(tmp_ric_client); + phy = std::move(tmp_phy); + radio = std::move(tmp_radio); started = true; // set to true in any case to allow stopping the eNB if an error happened // Now that everything is setup, log sector start events. @@ -201,6 +190,22 @@ void enb::start_plot() phy->start_plot(); } +bool enb::enable_ric_client(srsenb::e2_interface_metrics* e2_metrics) +{ + std::unique_ptr tmp_ric_client = std::unique_ptr( + new srsenb::ric_client(srslog::fetch_basic_logger("RIC", log_sink, false), e2_metrics)); + if (tmp_ric_client == nullptr) { + srsran::console("Error creating RIC client instance.\n"); + return SRSRAN_ERROR; + } + if (tmp_ric_client->init()) { + srsran::console("Error initializing RIC client.\n"); + return SRSRAN_ERROR; + } + ric = std::move(tmp_ric_client); + return SRSRAN_SUCCESS; +} + void enb::print_pool() { srsran::byte_buffer_pool::get_instance()->print_all_buffers(); diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 662e77375..e40a3c7de 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -35,6 +35,7 @@ #include "srsenb/hdr/enb.h" #include "srsenb/hdr/metrics_csv.h" +#include "srsenb/hdr/metrics_e2.h" #include "srsenb/hdr/metrics_json.h" #include "srsenb/hdr/metrics_stdout.h" #include "srsran/common/enb_events.h" @@ -227,6 +228,10 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("cfr.auto_target_papr", bpo::value(&args->phy.cfr_args.auto_target_papr)->default_value(args->phy.cfr_args.auto_target_papr), "Signal PAPR target (in dB) in CFR auto modes") ("cfr.ema_alpha", bpo::value(&args->phy.cfr_args.ema_alpha)->default_value(args->phy.cfr_args.ema_alpha), "Alpha coefficient for the power average in auto_ema mode (0 to 1)") + /* RIC section */ + ("ric_client.enable", bpo::value(&args->ric_client.enable)->default_value(false), "Enables the RIC client") + ("ric_client.ric_ip", bpo::value(&args->ric_client.ric_ip)->default_value("127.0.0.1"), "RIC IP address") + ("ric_client.ric_port", bpo::value(&args->ric_client.ric_port)->default_value(36422), "RIC port") /* Expert section */ ("expert.metrics_period_secs", bpo::value(&args->general.metrics_period_secs)->default_value(1.0), "Periodicity for metrics in seconds.") ("expert.metrics_csv_enable", bpo::value(&args->general.metrics_csv_enable)->default_value(false), "Write metrics to CSV file.") @@ -677,6 +682,10 @@ int main(int argc, char* argv[]) if (args.general.report_json_enable) { metricshub.add_listener(&json_metrics); } + srsenb::metrics_e2 e2_metrics(enb.get()); + if (args.ric_client.enable) { + metricshub.add_listener(&e2_metrics); + } // create input thread std::thread input(&input_loop, &metrics_screen, (enb_command_interface*)enb.get()); @@ -685,6 +694,11 @@ int main(int argc, char* argv[]) if (args.gui.enable) { enb->start_plot(); } + if (args.ric_client.enable) { + if (enb->enable_ric_client(&e2_metrics)) { + srslog::fetch_basic_logger("RIC").error("Failed to enable RIC client"); + } + } } int cnt = 0; int ts_cnt = 0; diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 9e9003381..e20e83a28 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -14,6 +14,8 @@ #include "e2sm_kpm.h" #include "srsran/asn1/e2ap.h" #include "srsran/asn1/e2sm_kpm.h" +#include "srsran/interfaces/e2_metrics_interface.h" +#include "srsran/interfaces/enb_metrics_interface.h" #include "srsran/srsran.h" #ifndef RIC_E2AP_H @@ -37,7 +39,7 @@ typedef struct { class e2ap { public: - e2ap(srslog::basic_logger& logger); + e2ap(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics); e2_ap_pdu_c generate_setup_request(); int process_setup_response(e2setup_resp_s setup_response); int process_setup_failure(); @@ -57,6 +59,7 @@ private: uint64_t gnb_id = 381210353; global_ric_id_t global_ric_id = {}; std::map ran_functions; + srsenb::e2_interface_metrics* gnb_metrics = nullptr; }; #endif /* RIC_E2AP_H */ diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index 8d5f23267..69a78db0a 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -18,6 +18,7 @@ #include "srsran/common/network_utils.h" #include "srsran/common/task_scheduler.h" #include "srsran/common/threads.h" +#include "srsran/interfaces/e2_metrics_interface.h" #include "srsran/srsran.h" static const int e2ap_ppid = 70; static const int e2ap_port = 36422; @@ -26,7 +27,7 @@ namespace srsenb { class ric_client : public srsran::thread { public: - ric_client(srslog::basic_logger& logger); + ric_client(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics); bool init(); void stop(); void run_thread(); @@ -49,6 +50,7 @@ private: srslog::basic_logger& logger; struct sockaddr_in ric_addr = {}; // RIC address bool running = false; + srsenb::e2_interface_metrics* gnb_metrics = nullptr; }; } // namespace srsenb diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index df5f5f69d..46248e4b9 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -2,7 +2,10 @@ #include "srsgnb/hdr/stack/ric/e2ap.h" #include "stdint.h" -e2ap::e2ap(srslog::basic_logger& logger) : logger(logger), e2sm_(logger) {} +e2ap::e2ap(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics) : logger(logger), e2sm_(logger) +{ + gnb_metrics = _gnb_metrics; +} e2_ap_pdu_c e2ap::generate_setup_request() { diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index e376587c3..3d506450d 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -15,9 +15,10 @@ #include "stdint.h" using namespace srsenb; -ric_client::ric_client(srslog::basic_logger& logger) : - task_sched(), logger(logger), rx_sockets(), thread("RIC_CLIENT_THREAD"), e2ap_(logger) +ric_client::ric_client(srslog::basic_logger& logger, e2_interface_metrics* _gnb_metrics) : + task_sched(), logger(logger), rx_sockets(), thread("RIC_CLIENT_THREAD"), e2ap_(logger, _gnb_metrics) { + gnb_metrics = _gnb_metrics; } bool ric_client::init() { diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index f21d5f191..1504a50b4 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -1,8 +1,14 @@ #include "srsgnb/hdr/stack/ric/e2ap.h" #include "srsran/asn1/e2ap.h" #include "srsran/common/test_common.h" +#include "srsran/interfaces/e2_metrics_interface.h" +#include "srsran/interfaces/enb_metrics_interface.h" #include "srsran/srsran.h" +class dummy_metrics_interface : public srsenb::e2_interface_metrics +{ + bool pull_metrics(srsenb::enb_metrics_t* m) { return true; } +}; // function to test the encoding of the E2AP message void test_reference_e2ap_setup_request() { @@ -96,7 +102,8 @@ void test_native_e2ap_setup_request() srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); e2_ap_pdu_c pdu, pdu2; srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); - e2ap e2ap_(logger); + dummy_metrics_interface dummy_metrics; + e2ap e2ap_(logger, &dummy_metrics); pdu = e2ap_.generate_setup_request(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); @@ -131,7 +138,8 @@ void test_native_e2ap_subscription_response() srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); e2_ap_pdu_c pdu, pdu2; srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); - e2ap e2ap_(logger); + dummy_metrics_interface dummy_metrics; + e2ap e2ap_(logger, &dummy_metrics); pdu = e2ap_.generate_subscription_response(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); From e52203f739a9b148b4a06b74a87da73df16e6804 Mon Sep 17 00:00:00 2001 From: Brendan Date: Wed, 14 Dec 2022 12:29:21 +0100 Subject: [PATCH 020/167] e2ap, ric: add support for ric reset request and response --- srsgnb/hdr/stack/ric/e2ap.h | 11 ++++- srsgnb/hdr/stack/ric/ric_client.h | 15 +++++- srsgnb/src/stack/ric/e2ap.cc | 52 ++++++++++++++++++++- srsgnb/src/stack/ric/ric_client.cc | 64 ++++++++++++++++++++++---- srsgnb/src/stack/ric/test/e2ap_test.cc | 44 +++++++++++++++++- 5 files changed, 173 insertions(+), 13 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index e20e83a28..d17b4e231 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -47,6 +47,11 @@ public: e2_ap_pdu_c generate_subscription_response(); int generate_subscription_failure(); int generate_indication(); + e2_ap_pdu_c generate_reset_request(); + e2_ap_pdu_c generate_reset_response(); + int process_reset_request(reset_request_s reset_request); + int process_reset_response(reset_resp_s reset_response); + int get_reset_id(); bool has_setup_response() { return setup_response_received; } private: @@ -57,9 +62,13 @@ private: int setup_procedure_transaction_id = 0; uint64_t plmn_id = 3617847; uint64_t gnb_id = 381210353; - global_ric_id_t global_ric_id = {}; + global_ric_id_t global_ric_id = {}; std::map ran_functions; srsenb::e2_interface_metrics* gnb_metrics = nullptr; + bool reset_response_received = false; + int reset_transaction_id = 1; + cause_c reset_cause = cause_c(); + int reset_id = 1; }; #endif /* RIC_E2AP_H */ diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index 69a78db0a..e78cc34c6 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -22,24 +22,35 @@ #include "srsran/srsran.h" static const int e2ap_ppid = 70; static const int e2ap_port = 36422; -enum e2_msg_type_t { E2_SETUP_REQUEST, E2_SUB_RESPONSE, E2_INDICATION }; + +enum e2_msg_type_t { E2_SETUP_REQUEST, E2_SUB_RESPONSE, E2_INDICATION, E2_RESET, E2_RESET_RESPONSE }; + namespace srsenb { class ric_client : public srsran::thread { public: ric_client(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics); + + // Initiate and Stop bool init(); void stop(); void run_thread(); + + // Send messages to RIC bool send_sctp(srsran::unique_byte_buffer_t& buf); bool send_e2_msg(e2_msg_type_t msg_type); + bool send_reset_response(); + + // Handle messages received from RIC bool - handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); + handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); bool handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg); bool handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& successful_outcome); bool handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome); bool handle_e2_setup_response(e2setup_resp_s setup_response); bool handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request); + bool handle_reset_response(reset_resp_s& reset_response); + bool handle_reset_request(reset_request_s& reset_request); private: e2ap e2ap_; diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 46248e4b9..85d2d96f8 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -16,9 +16,13 @@ e2_ap_pdu_c e2ap::generate_setup_request() e2setup_request_s& setup = initmsg.value.e2setup_request(); setup->transaction_id.crit = asn1::crit_opts::reject; +<<<<<<< HEAD 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(); +======= + setup->transaction_id.value.value = transaction_id; +>>>>>>> 456170567 (e2ap, ric: add support for ric reset request and response) gnb_.global_g_nb_id.plmn_id.from_number(plmn_id); gnb_.global_g_nb_id.gnb_id.gnb_id().from_number(gnb_id); @@ -114,4 +118,50 @@ int e2ap::process_subscription_request(ricsubscription_request_s subscription_re pending_subscription_request = true; // TODO process subscription request return 0; -} \ No newline at end of file +} +e2_ap_pdu_c e2ap::generate_reset_request() +{ + using namespace asn1::e2ap; + e2_ap_pdu_c pdu; + init_msg_s& request = pdu.set_init_msg(); + request.load_info_obj(ASN1_E2AP_ID_RESET); + reset_request_s& reset_request = request.value.reset_request(); + reset_request->transaction_id.crit = asn1::crit_opts::reject; + reset_request->transaction_id.value.value = reset_transaction_id; + reset_request->cause.crit = asn1::crit_opts::ignore; + reset_request->cause.value.set_misc(); + return pdu; +} + +e2_ap_pdu_c e2ap::generate_reset_response() +{ + e2_ap_pdu_c pdu; + successful_outcome_s& response = pdu.set_successful_outcome(); + response.load_info_obj(ASN1_E2AP_ID_RESET); + reset_resp_s& reset_response = response.value.reset_resp(); + reset_response->transaction_id.crit = asn1::crit_opts::reject; + reset_response->transaction_id.value.value = reset_transaction_id; + return pdu; +} + +int e2ap::process_reset_request(reset_request_s reset_request) +{ + reset_id = reset_request->transaction_id.value; + + // TO DO: Parse and store the cause for future extension of the ric client + + return 0; +} + +int e2ap::process_reset_response(reset_resp_s reset_response) +{ + // TO DO process reset response from RIC + reset_response_received = true; + + return 0; +} + +int e2ap::get_reset_id() +{ + return reset_id; +} diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 3d506450d..e7f5eea89 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -20,6 +20,7 @@ ric_client::ric_client(srslog::basic_logger& logger, e2_interface_metrics* _gnb_ { gnb_metrics = _gnb_metrics; } + bool ric_client::init() { printf("RIC_CLIENT: Init\n"); @@ -35,7 +36,6 @@ bool ric_client::init() } // Bind socket - if (not ric_socket.bind_addr("172.17.0.3", 36422)) { ric_socket.close(); return false; @@ -59,13 +59,17 @@ bool ric_client::init() start(0); return SRSRAN_SUCCESS; } + void ric_client::stop() { running = false; wait_thread_finish(); } + void ric_client::run_thread() { + using namespace asn1::e2ap; + while (running) { if (!e2ap_.has_setup_response()) { send_e2_msg(E2_SETUP_REQUEST); @@ -73,9 +77,9 @@ void ric_client::run_thread() } sleep(1); task_sched.run_next_task(); - sleep(5); } } + bool ric_client::send_sctp(srsran::unique_byte_buffer_t& buf) { ssize_t ret; @@ -98,6 +102,7 @@ bool ric_client::send_sctp(srsran::unique_byte_buffer_t& buf) bool ric_client::send_e2_msg(e2_msg_type_t msg_type) { + std::string message_name; srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); if (buf == nullptr) { // logger.error("Fatal Error: Couldn't allocate buffer for %s.", procedure_name); @@ -107,13 +112,23 @@ bool ric_client::send_e2_msg(e2_msg_type_t msg_type) switch (msg_type) { case e2_msg_type_t::E2_SETUP_REQUEST: send_pdu = e2ap_.generate_setup_request(); + message_name = "E2 SETUP REQUEST"; break; case e2_msg_type_t::E2_SUB_RESPONSE: send_pdu = e2ap_.generate_subscription_response(); + message_name = "E2 SUBSCRIPTION RESPONSE"; break; case e2_msg_type_t::E2_INDICATION: // TODO create E2 INDICATION generation break; + case e2_msg_type_t::E2_RESET: + send_pdu = e2ap_.generate_reset_request(); + message_name = "E2 RESET REQUEST"; + break; + case e2_msg_type_t::E2_RESET_RESPONSE: + send_pdu = e2ap_.generate_reset_response(); + message_name = "E2 RESET RESPONSE"; + break; default: printf("Unknown E2AP message type\n"); return false; @@ -126,7 +141,7 @@ bool ric_client::send_e2_msg(e2_msg_type_t msg_type) buf->N_bytes = bref.distance_bytes(); printf("try to send %d bytes to addr %s \n", buf->N_bytes, inet_ntoa(ric_addr.sin_addr)); if (!send_sctp(buf)) { - logger.error("failed to send e2 setup request"); + logger.error("failed to send {}", message_name); return false; } return true; @@ -176,7 +191,7 @@ bool ric_client::handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg) //handle_e2conn_upd(init_msg.value.e2conn_upd()); } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::reset_request) { logger.info("Received E2AP E2 Reset Request"); - //handle_reset_request(init_msg.value.reset_request()); + handle_reset_request(init_msg.value.reset_request()); } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::e2_removal_request) { logger.info("Received E2AP E2 Removal Request"); //handle_e2_removal_request(init_msg.value.e2_removal_request()); @@ -209,9 +224,9 @@ bool ric_client::handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& e2_ap_elem_procs_o::successful_outcome_c::types_opts::ricsubscription_delete_resp) { logger.info("Received E2AP RIC Subscription Delete Response \n"); // handle_ric_subscription_delete_response(successful_outcome.value.ric_subscription_delete()); - } else if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::e2_removal_resp) { - logger.info("Received E2AP RIC Service Status Successful Outcome \n"); - // handle_e2_removal_response(successful_outcome.value.e2_removal()); + } else if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::reset_resp) { + logger.info("Received E2AP RIC Reset Response \n"); + handle_reset_response(successful_outcome.value.reset_resp()); } else { logger.info("Received E2AP Unknown Successful Outcome \n"); } @@ -221,7 +236,7 @@ bool ric_client::handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& bool ric_client::handle_e2_setup_response(e2setup_resp_s setup_response) { if (e2ap_.process_setup_response(setup_response)) { - logger.error("Failed to process E2 Setup Response"); + logger.error("Failed to process E2 Setup Response \n"); return false; } return true; @@ -245,3 +260,36 @@ bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_s // TODO handle RIC subscription request return true; } + +bool ric_client::handle_reset_request(reset_request_s& reset_request) +{ + printf("Received E2AP E2 Reset Request \n"); + // call process to handle reset request, if it fails log error and return false, else return true - success + if (e2ap_.process_reset_request(reset_request)) { + logger.error("Failed to process E2 Reset Request \n"); + return false; + } + + logger.info("Reset transaction with ID = {}", e2ap_.get_reset_id()); + + // send reset reset response + auto send_reset_resp = [this]() { send_e2_msg(E2_RESET_RESPONSE); }; + ric_rece_task_queue.push(send_reset_resp); + + return true; +} + +bool ric_client::handle_reset_response(reset_resp_s& reset_response) +{ + printf("Received E2AP E2 Reset Response \n"); + // call process to handle reset reponse, if it fails log error, else return true - success + // all processing of message will be done in process_reset_response (e2ap.cc) + if (e2ap_.process_reset_response(reset_response)) { + logger.error("Failed to process E2 Reset Response \n"); + return false; + } + + logger.info("Reset Response successfully processed \n"); + + return true; +} diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index 1504a50b4..f7d25bae2 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -142,6 +142,26 @@ void test_native_e2ap_subscription_response() e2ap e2ap_(logger, &dummy_metrics); pdu = e2ap_.generate_subscription_response(); + pdu = e2ap_.generate_subscription_response(); + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("Failed to pack TX E2 PDU\n"); + return; + } + + asn1::cbit_ref bref2(buf->msg, buf->get_tailroom()); + asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked native E2AP PDU (subscription response) %d\n", (int)unpack_ret); +} + +void test_native_e2ap_reset_request() +{ + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + e2_ap_pdu_c pdu, pdu2; + e2ap e2ap_; + + pdu = e2ap_.generate_reset_request(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) { printf("Failed to pack TX E2 PDU\n"); @@ -149,11 +169,30 @@ void test_native_e2ap_subscription_response() } asn1::cbit_ref bref2(buf->msg, buf->get_tailroom()); + asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked native E2AP PDU RESET %d\n", (int)unpack_ret); +} + +void test_native_e2ap_reset_response() +{ + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + e2_ap_pdu_c pdu, pdu2; + e2ap e2ap_; + pdu = e2ap_.generate_reset_response(); + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("Failed to pack TX E2 PDU\n"); + return; + } + + asn1::cbit_ref bref2(buf->msg, buf->get_tailroom()); asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2); TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); - printf("Unpacked native E2AP PDU (subscription response) %d\n", (int)unpack_ret); + printf("Unpacked native E2AP PDU RESET RESPONSE %d\n", (int)unpack_ret); } +// add tets for set-up request and response int main() { @@ -161,5 +200,8 @@ int main() test_native_e2ap_setup_request(); test_reference_e2ap_subscription_request(); test_native_e2ap_subscription_response(); + test_native_e2ap_reset_request(); + test_native_e2ap_reset_response(); + // call reset test functions here return 0; } \ No newline at end of file From 3015a6cd136561642d9c70dafe18d2a39db8df79 Mon Sep 17 00:00:00 2001 From: Brendan Date: Tue, 10 Jan 2023 11:20:49 +0100 Subject: [PATCH 021/167] e2ap: remove conflict artifact from source file --- srsgnb/src/stack/ric/e2ap.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 85d2d96f8..88b3ebf9a 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -16,13 +16,9 @@ e2_ap_pdu_c e2ap::generate_setup_request() e2setup_request_s& setup = initmsg.value.e2setup_request(); setup->transaction_id.crit = asn1::crit_opts::reject; -<<<<<<< HEAD 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(); -======= - setup->transaction_id.value.value = transaction_id; ->>>>>>> 456170567 (e2ap, ric: add support for ric reset request and response) gnb_.global_g_nb_id.plmn_id.from_number(plmn_id); gnb_.global_g_nb_id.gnb_id.gnb_id().from_number(gnb_id); From 1aa5c3819b98c7f8e7602206bea8dbb70a28c73a Mon Sep 17 00:00:00 2001 From: Brendan Date: Tue, 10 Jan 2023 11:21:31 +0100 Subject: [PATCH 022/167] e2ap: update reset test functions --- srsgnb/src/stack/ric/test/e2ap_test.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index f7d25bae2..0c6b349c3 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -159,7 +159,9 @@ void test_native_e2ap_reset_request() { srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); e2_ap_pdu_c pdu, pdu2; - e2ap e2ap_; + srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); + dummy_metrics_interface dummy_metrics; + e2ap e2ap_(logger, &dummy_metrics); pdu = e2ap_.generate_reset_request(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); @@ -178,7 +180,9 @@ void test_native_e2ap_reset_response() { srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); e2_ap_pdu_c pdu, pdu2; - e2ap e2ap_; + srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); + dummy_metrics_interface dummy_metrics; + e2ap e2ap_(logger, &dummy_metrics); pdu = e2ap_.generate_reset_response(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); @@ -204,4 +208,4 @@ int main() test_native_e2ap_reset_response(); // call reset test functions here return 0; -} \ No newline at end of file +} From 7d8a21cb77f3195406db1df85ca8ad35b62556ad Mon Sep 17 00:00:00 2001 From: yagoda Date: Tue, 14 Mar 2023 10:06:11 +0100 Subject: [PATCH 023/167] asn1: adding e2sm_kpm version 2.0 packing and unpacking for debugging purposes --- lib/include/srsran/asn1/e2sm_kpm_v2.h | 2834 +++++++++++ lib/src/asn1/e2sm_kpm_v2.cpp | 6574 +++++++++++++++++++++++++ 2 files changed, 9408 insertions(+) create mode 100644 lib/include/srsran/asn1/e2sm_kpm_v2.h create mode 100644 lib/src/asn1/e2sm_kpm_v2.cpp diff --git a/lib/include/srsran/asn1/e2sm_kpm_v2.h b/lib/include/srsran/asn1/e2sm_kpm_v2.h new file mode 100644 index 000000000..fce81388f --- /dev/null +++ b/lib/include/srsran/asn1/e2sm_kpm_v2.h @@ -0,0 +1,2834 @@ +/* + * + * 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. + * + */ + +/******************************************************************************* + * + * 3GPP TS ASN1 E2SM KPM v15.3.0 (2019-03) + * + ******************************************************************************/ + +#pragma once + +#include "asn1_utils.h" +#include +#include + +namespace asn1 { +namespace e2sm_kpm { +/******************************************************************************* + * Constant Definitions + ******************************************************************************/ + +#define ASN1_E2SM_KPM_MAXNOOF_CELLS 16384 +#define ASN1_E2SM_KPM_MAXNOOF_RIC_STYLES 63 +#define ASN1_E2SM_KPM_MAXNOOF_MEAS_INFO 65535 +#define ASN1_E2SM_KPM_MAXNOOF_LABEL_INFO 2147483647 +#define ASN1_E2SM_KPM_MAXNOOF_MEAS_RECORD 65535 +#define ASN1_E2SM_KPM_MAXNOOF_MEAS_VALUE 2147483647 +#define ASN1_E2SM_KPM_MAXNOOF_CONDITION_INFO 32768 +#define ASN1_E2SM_KPM_MAXNOOF_UEID 65535 +#define ASN1_E2SM_KPM_MAXNOOF_CONDITION_INFO_PER_SUB 32768 +#define ASN1_E2SM_KPM_MAXNOOF_UEID_PER_SUB 65535 +#define ASN1_E2SM_KPM_MAXNOOF_UE_MEAS_REPORT 65535 +#define ASN1_E2SM_KPM_MAXNOOF_BIN 65535 + +/******************************************************************************* + * Struct Definitions + ******************************************************************************/ +#define None std::numeric_limits::max() + +struct real_s { + SRSASN_CODE pack(bit_ref& bref) const + { + printf(" WARNING using unimplemented REAL packing function\n"); + return SRSASN_SUCCESS; + }; + SRSASN_CODE unpack(cbit_ref& bref) const + { + printf(" WARNING using unimplemented REAL unpacking function\n"); + return SRSASN_SUCCESS; + }; + void to_json(json_writer& j) const { printf(" WARNING using unimplemented REAL json function\n"); }; +}; + +// BinRangeValue ::= CHOICE +struct bin_range_value_c { + struct types_opts { + enum options { value_int, value_real, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + bin_range_value_c() = default; + bin_range_value_c(const bin_range_value_c& other); + bin_range_value_c& operator=(const bin_range_value_c& other); + ~bin_range_value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + int64_t& value_int() + { + assert_choice_type(types::value_int, type_, "BinRangeValue"); + return c.get(); + } + real_s& value_real() + { + assert_choice_type(types::value_real, type_, "BinRangeValue"); + return c.get(); + } + const int64_t& value_int() const + { + assert_choice_type(types::value_int, type_, "BinRangeValue"); + return c.get(); + } + const real_s& value_real() const + { + assert_choice_type(types::value_real, type_, "BinRangeValue"); + return c.get(); + } + int64_t& set_value_int(); + real_s& set_value_real(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// BinRangeItem ::= SEQUENCE +struct bin_range_item_s { + bool ext = false; + uint32_t bin_idx = 1; + bin_range_value_c start_value; + bin_range_value_c end_value; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// BinRangeList ::= SEQUENCE (SIZE (1..65535)) OF BinRangeItem +using bin_range_list_l = dyn_array; + +// BinRangeDefinition ::= SEQUENCE +struct bin_range_definition_s { + bool ext = false; + bin_range_list_l bin_range_list_x; + bin_range_list_l bin_range_list_y; + bin_range_list_l bin_range_list_z; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// EUTRA-CGI ::= SEQUENCE +struct eutra_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<28, false, true> eutra_cell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-CGI ::= SEQUENCE +struct nr_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<36, false, true> nrcell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CGI ::= CHOICE +struct cgi_c { + struct types_opts { + enum options { nr_cgi, eutra_cgi, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + cgi_c() = default; + cgi_c(const cgi_c& other); + cgi_c& operator=(const cgi_c& other); + ~cgi_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_cgi_s& nr_cgi() + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + eutra_cgi_s& eutra_cgi() + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + const nr_cgi_s& nr_cgi() const + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + const eutra_cgi_s& eutra_cgi() const + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + nr_cgi_s& set_nr_cgi(); + eutra_cgi_s& set_eutra_cgi(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// GUAMI ::= SEQUENCE +struct guami_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<8, false, true> amf_region_id; + fixed_bitstring<10, false, true> amf_set_id; + fixed_bitstring<6, false, true> amf_pointer; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GUMMEI ::= SEQUENCE +struct gummei_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_octstring<2, true> mme_group_id; + fixed_octstring<1, true> mme_code; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CoreCPID ::= CHOICE +struct core_cpid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + core_cpid_c() = default; + core_cpid_c(const core_cpid_c& other); + core_cpid_c& operator=(const core_cpid_c& other); + ~core_cpid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + guami_s& five_gc() + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + gummei_s& epc() + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + const guami_s& five_gc() const + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + const gummei_s& epc() const + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + guami_s& set_five_gc(); + gummei_s& set_epc(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// MeasurementType ::= CHOICE +struct meas_type_c { + struct types_opts { + enum options { meas_name, meas_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + meas_type_c() = default; + meas_type_c(const meas_type_c& other); + meas_type_c& operator=(const meas_type_c& other); + ~meas_type_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + printable_string<1, 150, true, true>& meas_name() + { + assert_choice_type(types::meas_name, type_, "MeasurementType"); + return c.get >(); + } + uint32_t& meas_id() + { + assert_choice_type(types::meas_id, type_, "MeasurementType"); + return c.get(); + } + const printable_string<1, 150, true, true>& meas_name() const + { + assert_choice_type(types::meas_name, type_, "MeasurementType"); + return c.get >(); + } + const uint32_t& meas_id() const + { + assert_choice_type(types::meas_id, type_, "MeasurementType"); + return c.get(); + } + printable_string<1, 150, true, true>& set_meas_name(); + uint32_t& set_meas_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// DistMeasurementBinRangeItem ::= SEQUENCE +struct dist_meas_bin_range_item_s { + bool ext = false; + meas_type_c meas_type; + bin_range_definition_s bin_range_def; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// DistMeasurementBinRangeList ::= SEQUENCE (SIZE (1..65535)) OF DistMeasurementBinRangeItem +using dist_meas_bin_range_list_l = dyn_array; + +// S-NSSAI ::= SEQUENCE +struct s_nssai_s { + bool ext = false; + bool sd_present = false; + fixed_octstring<1, true> sst; + fixed_octstring<3, true> sd; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TestCond-Expression ::= ENUMERATED +struct test_cond_expression_opts { + enum options { equal, greaterthan, lessthan, contains, present, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated test_cond_expression_e; + +// TestCond-Type ::= CHOICE +struct test_cond_type_c { + struct gbr_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated gbr_e_; + struct ambr_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated ambr_e_; + struct is_stat_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated is_stat_e_; + struct is_cat_m_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated is_cat_m_e_; + struct rsrp_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated rsrp_e_; + struct rsrq_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated rsrq_e_; + struct ul_r_srp_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated ul_r_srp_e_; + struct cqi_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated cqi_e_; + struct five_qi_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated five_qi_e_; + struct qci_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated qci_e_; + struct snssai_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated snssai_e_; + struct types_opts { + enum options { + gbr, + ambr, + is_stat, + is_cat_m, + rsrp, + rsrq, + /*...*/ ul_r_srp, + cqi, + five_qi, + qci, + snssai, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + test_cond_type_c() = default; + test_cond_type_c(const test_cond_type_c& other); + test_cond_type_c& operator=(const test_cond_type_c& other); + ~test_cond_type_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + gbr_e_& gbr() + { + assert_choice_type(types::gbr, type_, "TestCond-Type"); + return c.get(); + } + ambr_e_& ambr() + { + assert_choice_type(types::ambr, type_, "TestCond-Type"); + return c.get(); + } + is_stat_e_& is_stat() + { + assert_choice_type(types::is_stat, type_, "TestCond-Type"); + return c.get(); + } + is_cat_m_e_& is_cat_m() + { + assert_choice_type(types::is_cat_m, type_, "TestCond-Type"); + return c.get(); + } + rsrp_e_& rsrp() + { + assert_choice_type(types::rsrp, type_, "TestCond-Type"); + return c.get(); + } + rsrq_e_& rsrq() + { + assert_choice_type(types::rsrq, type_, "TestCond-Type"); + return c.get(); + } + ul_r_srp_e_& ul_r_srp() + { + assert_choice_type(types::ul_r_srp, type_, "TestCond-Type"); + return c.get(); + } + cqi_e_& cqi() + { + assert_choice_type(types::cqi, type_, "TestCond-Type"); + return c.get(); + } + five_qi_e_& five_qi() + { + assert_choice_type(types::five_qi, type_, "TestCond-Type"); + return c.get(); + } + qci_e_& qci() + { + assert_choice_type(types::qci, type_, "TestCond-Type"); + return c.get(); + } + snssai_e_& snssai() + { + assert_choice_type(types::snssai, type_, "TestCond-Type"); + return c.get(); + } + const gbr_e_& gbr() const + { + assert_choice_type(types::gbr, type_, "TestCond-Type"); + return c.get(); + } + const ambr_e_& ambr() const + { + assert_choice_type(types::ambr, type_, "TestCond-Type"); + return c.get(); + } + const is_stat_e_& is_stat() const + { + assert_choice_type(types::is_stat, type_, "TestCond-Type"); + return c.get(); + } + const is_cat_m_e_& is_cat_m() const + { + assert_choice_type(types::is_cat_m, type_, "TestCond-Type"); + return c.get(); + } + const rsrp_e_& rsrp() const + { + assert_choice_type(types::rsrp, type_, "TestCond-Type"); + return c.get(); + } + const rsrq_e_& rsrq() const + { + assert_choice_type(types::rsrq, type_, "TestCond-Type"); + return c.get(); + } + const ul_r_srp_e_& ul_r_srp() const + { + assert_choice_type(types::ul_r_srp, type_, "TestCond-Type"); + return c.get(); + } + const cqi_e_& cqi() const + { + assert_choice_type(types::cqi, type_, "TestCond-Type"); + return c.get(); + } + const five_qi_e_& five_qi() const + { + assert_choice_type(types::five_qi, type_, "TestCond-Type"); + return c.get(); + } + const qci_e_& qci() const + { + assert_choice_type(types::qci, type_, "TestCond-Type"); + return c.get(); + } + const snssai_e_& snssai() const + { + assert_choice_type(types::snssai, type_, "TestCond-Type"); + return c.get(); + } + gbr_e_& set_gbr(); + ambr_e_& set_ambr(); + is_stat_e_& set_is_stat(); + is_cat_m_e_& set_is_cat_m(); + rsrp_e_& set_rsrp(); + rsrq_e_& set_rsrq(); + ul_r_srp_e_& set_ul_r_srp(); + cqi_e_& set_cqi(); + five_qi_e_& set_five_qi(); + qci_e_& set_qci(); + snssai_e_& set_snssai(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// TestCond-Value ::= CHOICE +struct test_cond_value_c { + struct types_opts { + enum options { + value_int, + value_enum, + value_bool, + value_bit_s, + value_oct_s, + value_prt_s, + /*...*/ value_real, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + test_cond_value_c() = default; + test_cond_value_c(const test_cond_value_c& other); + test_cond_value_c& operator=(const test_cond_value_c& other); + ~test_cond_value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + int64_t& value_int() + { + assert_choice_type(types::value_int, type_, "TestCond-Value"); + return c.get(); + } + int64_t& value_enum() + { + assert_choice_type(types::value_enum, type_, "TestCond-Value"); + return c.get(); + } + bool& value_bool() + { + assert_choice_type(types::value_bool, type_, "TestCond-Value"); + return c.get(); + } + dyn_bitstring& value_bit_s() + { + assert_choice_type(types::value_bit_s, type_, "TestCond-Value"); + return c.get(); + } + unbounded_octstring& value_oct_s() + { + assert_choice_type(types::value_oct_s, type_, "TestCond-Value"); + return c.get >(); + } + printable_string<0, None, false, true>& value_prt_s() + { + assert_choice_type(types::value_prt_s, type_, "TestCond-Value"); + return c.get >(); + } + real_s& value_real() + { + assert_choice_type(types::value_real, type_, "TestCond-Value"); + return c.get(); + } + const int64_t& value_int() const + { + assert_choice_type(types::value_int, type_, "TestCond-Value"); + return c.get(); + } + const int64_t& value_enum() const + { + assert_choice_type(types::value_enum, type_, "TestCond-Value"); + return c.get(); + } + const bool& value_bool() const + { + assert_choice_type(types::value_bool, type_, "TestCond-Value"); + return c.get(); + } + const dyn_bitstring& value_bit_s() const + { + assert_choice_type(types::value_bit_s, type_, "TestCond-Value"); + return c.get(); + } + const unbounded_octstring& value_oct_s() const + { + assert_choice_type(types::value_oct_s, type_, "TestCond-Value"); + return c.get >(); + } + const printable_string<0, None, false, true>& value_prt_s() const + { + assert_choice_type(types::value_prt_s, type_, "TestCond-Value"); + return c.get >(); + } + const real_s& value_real() const + { + assert_choice_type(types::value_real, type_, "TestCond-Value"); + return c.get(); + } + int64_t& set_value_int(); + int64_t& set_value_enum(); + bool& set_value_bool(); + dyn_bitstring& set_value_bit_s(); + unbounded_octstring& set_value_oct_s(); + printable_string<0, None, false, true>& set_value_prt_s(); + real_s& set_value_real(); + +private: + types type_; + choice_buffer_t, real_s, unbounded_octstring > c; + + void destroy_(); +}; + +// ENB-ID ::= CHOICE +struct enb_id_c { + struct types_opts { + enum options { macro_enb_id, home_enb_id, /*...*/ short_macro_enb_id, long_macro_enb_id, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_c() = default; + enb_id_c(const enb_id_c& other); + enb_id_c& operator=(const enb_id_c& other); + ~enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_enb_id() + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<28, false, true>& home_enb_id() + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_enb_id() + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_enb_id() + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_enb_id() const + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<28, false, true>& home_enb_id() const + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_enb_id() const + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_enb_id() const + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_enb_id(); + fixed_bitstring<28, false, true>& set_home_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// GNB-ID ::= CHOICE +struct gnb_id_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// MeasurementLabel ::= SEQUENCE +struct meas_label_s { + struct no_label_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated no_label_e_; + struct sum_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated sum_e_; + struct pre_label_override_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated pre_label_override_e_; + struct start_end_ind_opts { + enum options { start, end, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated start_end_ind_e_; + struct min_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated min_e_; + struct max_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated max_e_; + struct avg_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated avg_e_; + + // member variables + bool ext = false; + bool no_label_present = false; + bool plmn_id_present = false; + bool slice_id_present = false; + bool five_qi_present = false; + bool qfi_present = false; + bool qci_present = false; + bool qcimax_present = false; + bool qcimin_present = false; + bool arpmax_present = false; + bool arpmin_present = false; + bool bitrate_range_present = false; + bool layer_mu_mimo_present = false; + bool sum_present = false; + bool dist_bin_x_present = false; + bool dist_bin_y_present = false; + bool dist_bin_z_present = false; + bool pre_label_override_present = false; + bool start_end_ind_present = false; + bool min_present = false; + bool max_present = false; + bool avg_present = false; + no_label_e_ no_label; + fixed_octstring<3, true> plmn_id; + s_nssai_s slice_id; + uint16_t five_qi = 0; + uint8_t qfi = 0; + uint16_t qci = 0; + uint16_t qcimax = 0; + uint16_t qcimin = 0; + uint8_t arpmax = 1; + uint8_t arpmin = 1; + uint32_t bitrate_range = 1; + uint32_t layer_mu_mimo = 1; + sum_e_ sum; + uint32_t dist_bin_x = 1; + uint32_t dist_bin_y = 1; + uint32_t dist_bin_z = 1; + pre_label_override_e_ pre_label_override; + start_end_ind_e_ start_end_ind; + min_e_ min; + max_e_ max; + avg_e_ avg; + // ... + bool ssb_idx_present = false; + bool non_go_b_bfmode_idx_present = false; + bool mimo_mode_idx_present = false; + uint32_t ssb_idx = 1; + uint32_t non_go_b_bfmode_idx = 1; + uint8_t mimo_mode_idx = 1; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NgENB-ID ::= CHOICE +struct ng_enb_id_c { + struct types_opts { + enum options { macro_ng_enb_id, short_macro_ng_enb_id, long_macro_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ng_enb_id_c() = default; + ng_enb_id_c(const ng_enb_id_c& other); + ng_enb_id_c& operator=(const ng_enb_id_c& other); + ~ng_enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_ng_enb_id() + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_ng_enb_id() + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_ng_enb_id() + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_ng_enb_id() const + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_ng_enb_id() const + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_ng_enb_id() const + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_ng_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_ng_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_ng_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// TestCondInfo ::= SEQUENCE +struct test_cond_info_s { + bool ext = false; + bool test_expr_present = false; + bool test_value_present = false; + test_cond_type_c test_type; + test_cond_expression_e test_expr; + test_cond_value_c test_value; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_e1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_f1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalENB-ID ::= SEQUENCE +struct global_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalGNB-ID ::= SEQUENCE +struct global_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + gnb_id_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalNgENB-ID ::= SEQUENCE +struct global_ng_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + ng_enb_id_c ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// LabelInfoItem ::= SEQUENCE +struct label_info_item_s { + bool ext = false; + meas_label_s meas_label; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// LogicalOR ::= ENUMERATED +struct lc_or_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated lc_or_e; + +// MatchingCondItem-Choice ::= CHOICE +struct matching_cond_item_choice_c { + struct types_opts { + enum options { meas_label, test_cond_info, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + matching_cond_item_choice_c() = default; + matching_cond_item_choice_c(const matching_cond_item_choice_c& other); + matching_cond_item_choice_c& operator=(const matching_cond_item_choice_c& other); + ~matching_cond_item_choice_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + meas_label_s& meas_label() + { + assert_choice_type(types::meas_label, type_, "MatchingCondItem-Choice"); + return c.get(); + } + test_cond_info_s& test_cond_info() + { + assert_choice_type(types::test_cond_info, type_, "MatchingCondItem-Choice"); + return c.get(); + } + const meas_label_s& meas_label() const + { + assert_choice_type(types::meas_label, type_, "MatchingCondItem-Choice"); + return c.get(); + } + const test_cond_info_s& test_cond_info() const + { + assert_choice_type(types::test_cond_info, type_, "MatchingCondItem-Choice"); + return c.get(); + } + meas_label_s& set_meas_label(); + test_cond_info_s& set_test_cond_info(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// UEID-GNB-CU-CP-E1AP-ID-List ::= SEQUENCE (SIZE (1..65535)) OF UEID-GNB-CU-CP-E1AP-ID-Item +using ueid_gnb_cu_cp_e1_ap_id_list_l = dyn_array; + +// UEID-GNB-CU-F1AP-ID-List ::= SEQUENCE (SIZE (1..4)) OF UEID-GNB-CU-CP-F1AP-ID-Item +using ueid_gnb_cu_f1_ap_id_list_l = dyn_array; + +// LabelInfoList ::= SEQUENCE (SIZE (1..2147483647)) OF LabelInfoItem +using label_info_list_l = dyn_array; + +// MatchingCondItem ::= SEQUENCE +struct matching_cond_item_s { + bool ext = false; + bool lc_or_present = false; + matching_cond_item_choice_c matching_cond_choice; + lc_or_e lc_or; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-EN-GNB ::= SEQUENCE +struct ueid_en_gnb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool gnb_cu_ue_f1_ap_id_present = false; + bool ran_ueid_present = false; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + uint64_t gnb_cu_ue_f1_ap_id = 0; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-ENB ::= SEQUENCE +struct ueid_enb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_present = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool global_enb_id_present = false; + uint64_t mme_ue_s1ap_id = 0; + gummei_s gummei; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB ::= SEQUENCE +struct ueid_gnb_s { + bool ext = false; + bool ran_ueid_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_gnb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + ueid_gnb_cu_f1_ap_id_list_l gnb_cu_ue_f1_ap_id_list; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_gnb_id_s global_gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-UP ::= SEQUENCE +struct ueid_gnb_cu_up_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-DU ::= SEQUENCE +struct ueid_gnb_du_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB ::= SEQUENCE +struct ueid_ng_enb_s { + bool ext = false; + bool ng_enb_cu_ue_w1_ap_id_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_ng_enb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_ng_enb_id_s global_ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB-DU ::= SEQUENCE +struct ueid_ng_enb_du_s { + bool ext = false; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingCondList ::= SEQUENCE (SIZE (1..32768)) OF MatchingCondItem +using matching_cond_list_l = dyn_array; + +// MeasurementInfoItem ::= SEQUENCE +struct meas_info_item_s { + bool ext = false; + meas_type_c meas_type; + label_info_list_l label_info_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID ::= CHOICE +struct ueid_c { + struct types_opts { + enum options { + gnb_ueid, + gnb_du_ueid, + gnb_cu_up_ueid, + ng_enb_ueid, + ng_enb_du_ueid, + en_g_nb_ueid, + enb_ueid, + // ... + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ueid_c() = default; + ueid_c(const ueid_c& other); + ueid_c& operator=(const ueid_c& other); + ~ueid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ueid_gnb_s& gnb_ueid() + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_du_s& gnb_du_ueid() + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_cu_up_s& gnb_cu_up_ueid() + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_s& ng_enb_ueid() + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_du_s& ng_enb_du_ueid() + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_en_gnb_s& en_g_nb_ueid() + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + ueid_enb_s& enb_ueid() + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_s& gnb_ueid() const + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_du_s& gnb_du_ueid() const + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_cu_up_s& gnb_cu_up_ueid() const + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_s& ng_enb_ueid() const + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_du_s& ng_enb_du_ueid() const + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_en_gnb_s& en_g_nb_ueid() const + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_enb_s& enb_ueid() const + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_s& set_gnb_ueid(); + ueid_gnb_du_s& set_gnb_du_ueid(); + ueid_gnb_cu_up_s& set_gnb_cu_up_ueid(); + ueid_ng_enb_s& set_ng_enb_ueid(); + ueid_ng_enb_du_s& set_ng_enb_du_ueid(); + ueid_en_gnb_s& set_en_g_nb_ueid(); + ueid_enb_s& set_enb_ueid(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// MatchingUEidPerSubItem ::= SEQUENCE +struct matching_ueid_per_sub_item_s { + bool ext = false; + ueid_c ue_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingUeCondPerSubItem ::= SEQUENCE +struct matching_ue_cond_per_sub_item_s { + bool ext = false; + test_cond_info_s test_cond_info; + // ... + bool lc_or_present = false; + lc_or_e lc_or; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementCondItem ::= SEQUENCE +struct meas_cond_item_s { + bool ext = false; + meas_type_c meas_type; + matching_cond_list_l matching_cond; + // ... + copy_ptr bin_range_def; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementInfoList ::= SEQUENCE (SIZE (1..65535)) OF MeasurementInfoItem +using meas_info_list_l = dyn_array; + +// E2SM-KPM-ActionDefinition-Format1 ::= SEQUENCE +struct e2_sm_kpm_action_definition_format1_s { + bool ext = false; + bool cell_global_id_present = false; + meas_info_list_l meas_info_list; + uint64_t granul_period = 1; + cgi_c cell_global_id; + // ... + copy_ptr dist_meas_bin_range_info; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingUEidPerSubList ::= SEQUENCE (SIZE (2..65535)) OF MatchingUEidPerSubItem +using matching_ueid_per_sub_list_l = dyn_array; + +// MatchingUeCondPerSubList ::= SEQUENCE (SIZE (1..32768)) OF MatchingUeCondPerSubItem +using matching_ue_cond_per_sub_list_l = dyn_array; + +// MeasurementCondList ::= SEQUENCE (SIZE (1..65535)) OF MeasurementCondItem +using meas_cond_list_l = dyn_array; + +// E2SM-KPM-ActionDefinition-Format2 ::= SEQUENCE +struct e2_sm_kpm_action_definition_format2_s { + bool ext = false; + ueid_c ue_id; + e2_sm_kpm_action_definition_format1_s subscript_info; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-ActionDefinition-Format3 ::= SEQUENCE +struct e2_sm_kpm_action_definition_format3_s { + bool ext = false; + bool cell_global_id_present = false; + meas_cond_list_l meas_cond_list; + uint64_t granul_period = 1; + cgi_c cell_global_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-ActionDefinition-Format4 ::= SEQUENCE +struct e2_sm_kpm_action_definition_format4_s { + bool ext = false; + matching_ue_cond_per_sub_list_l matching_ue_cond_list; + e2_sm_kpm_action_definition_format1_s subscription_info; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-ActionDefinition-Format5 ::= SEQUENCE +struct e2_sm_kpm_action_definition_format5_s { + bool ext = false; + matching_ueid_per_sub_list_l matching_ueid_list; + e2_sm_kpm_action_definition_format1_s subscription_info; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-ActionDefinition ::= SEQUENCE +struct e2_sm_kpm_action_definition_s { + struct action_definition_formats_c_ { + struct types_opts { + enum options { + action_definition_format1, + action_definition_format2, + action_definition_format3, + // ... + action_definition_format4, + action_definition_format5, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + action_definition_formats_c_() = default; + action_definition_formats_c_(const action_definition_formats_c_& other); + action_definition_formats_c_& operator=(const action_definition_formats_c_& other); + ~action_definition_formats_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_action_definition_format1_s& action_definition_format1() + { + assert_choice_type(types::action_definition_format1, type_, "actionDefinition-formats"); + return c.get(); + } + e2_sm_kpm_action_definition_format2_s& action_definition_format2() + { + assert_choice_type(types::action_definition_format2, type_, "actionDefinition-formats"); + return c.get(); + } + e2_sm_kpm_action_definition_format3_s& action_definition_format3() + { + assert_choice_type(types::action_definition_format3, type_, "actionDefinition-formats"); + return c.get(); + } + e2_sm_kpm_action_definition_format4_s& action_definition_format4() + { + assert_choice_type(types::action_definition_format4, type_, "actionDefinition-formats"); + return c.get(); + } + e2_sm_kpm_action_definition_format5_s& action_definition_format5() + { + assert_choice_type(types::action_definition_format5, type_, "actionDefinition-formats"); + return c.get(); + } + const e2_sm_kpm_action_definition_format1_s& action_definition_format1() const + { + assert_choice_type(types::action_definition_format1, type_, "actionDefinition-formats"); + return c.get(); + } + const e2_sm_kpm_action_definition_format2_s& action_definition_format2() const + { + assert_choice_type(types::action_definition_format2, type_, "actionDefinition-formats"); + return c.get(); + } + const e2_sm_kpm_action_definition_format3_s& action_definition_format3() const + { + assert_choice_type(types::action_definition_format3, type_, "actionDefinition-formats"); + return c.get(); + } + const e2_sm_kpm_action_definition_format4_s& action_definition_format4() const + { + assert_choice_type(types::action_definition_format4, type_, "actionDefinition-formats"); + return c.get(); + } + const e2_sm_kpm_action_definition_format5_s& action_definition_format5() const + { + assert_choice_type(types::action_definition_format5, type_, "actionDefinition-formats"); + return c.get(); + } + e2_sm_kpm_action_definition_format1_s& set_action_definition_format1(); + e2_sm_kpm_action_definition_format2_s& set_action_definition_format2(); + e2_sm_kpm_action_definition_format3_s& set_action_definition_format3(); + e2_sm_kpm_action_definition_format4_s& set_action_definition_format4(); + e2_sm_kpm_action_definition_format5_s& set_action_definition_format5(); + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + + // member variables + bool ext = false; + int64_t ric_style_type = 0; + action_definition_formats_c_ action_definition_formats; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-EventTriggerDefinition-Format1 ::= SEQUENCE +struct e2_sm_kpm_event_trigger_definition_format1_s { + bool ext = false; + uint64_t report_period = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-EventTriggerDefinition ::= SEQUENCE +struct e2_sm_kpm_event_trigger_definition_s { + struct event_definition_formats_c_ { + struct types_opts { + enum options { event_definition_format1, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::event_definition_format1; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_event_trigger_definition_format1_s& event_definition_format1() { return c; } + const e2_sm_kpm_event_trigger_definition_format1_s& event_definition_format1() const { return c; } + + private: + e2_sm_kpm_event_trigger_definition_format1_s c; + }; + + // member variables + bool ext = false; + event_definition_formats_c_ event_definition_formats; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationHeader-Format1 ::= SEQUENCE +struct e2_sm_kpm_ind_hdr_format1_s { + bool ext = false; + bool file_formatversion_present = false; + bool sender_name_present = false; + bool sender_type_present = false; + bool vendor_name_present = false; + fixed_octstring<4, true> collet_start_time; + printable_string<0, 15, false, true> file_formatversion; + printable_string<0, 400, false, true> sender_name; + printable_string<0, 8, false, true> sender_type; + printable_string<0, 32, false, true> vendor_name; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationHeader ::= SEQUENCE +struct e2_sm_kpm_ind_hdr_s { + struct ind_hdr_formats_c_ { + struct types_opts { + enum options { ind_hdr_format1, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ind_hdr_format1; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_ind_hdr_format1_s& ind_hdr_format1() { return c; } + const e2_sm_kpm_ind_hdr_format1_s& ind_hdr_format1() const { return c; } + + private: + e2_sm_kpm_ind_hdr_format1_s c; + }; + + // member variables + bool ext = false; + ind_hdr_formats_c_ ind_hdr_formats; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementRecordItem ::= CHOICE +struct meas_record_item_c { + struct types_opts { + enum options { integer, real, no_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + meas_record_item_c() = default; + meas_record_item_c(const meas_record_item_c& other); + meas_record_item_c& operator=(const meas_record_item_c& other); + ~meas_record_item_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint64_t& integer() + { + assert_choice_type(types::integer, type_, "MeasurementRecordItem"); + return c.get(); + } + real_s& real() + { + assert_choice_type(types::real, type_, "MeasurementRecordItem"); + return c.get(); + } + const uint64_t& integer() const + { + assert_choice_type(types::integer, type_, "MeasurementRecordItem"); + return c.get(); + } + const real_s& real() const + { + assert_choice_type(types::real, type_, "MeasurementRecordItem"); + return c.get(); + } + uint64_t& set_integer(); + real_s& set_real(); + void set_no_value(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// MatchingUEidItem-PerGP ::= SEQUENCE +struct matching_ueid_item_per_gp_s { + bool ext = false; + ueid_c ue_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementRecord ::= SEQUENCE (SIZE (1..2147483647)) OF MeasurementRecordItem +using meas_record_l = dyn_array; + +// MatchingUEidList-PerGP ::= SEQUENCE (SIZE (1..65535)) OF MatchingUEidItem-PerGP +using matching_ueid_list_per_gp_l = dyn_array; + +// MeasurementDataItem ::= SEQUENCE +struct meas_data_item_s { + struct incomplete_flag_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated incomplete_flag_e_; + + // member variables + bool ext = false; + bool incomplete_flag_present = false; + meas_record_l meas_record; + incomplete_flag_e_ incomplete_flag; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingUEidItem ::= SEQUENCE +struct matching_ueid_item_s { + bool ext = false; + ueid_c ue_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingUEidPerGP-Item ::= SEQUENCE +struct matching_ueid_per_gp_item_s { + struct matched_per_gp_c_ { + struct no_uematched_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated no_uematched_e_; + struct types_opts { + enum options { no_uematched, one_or_more_uematched, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + matched_per_gp_c_() = default; + matched_per_gp_c_(const matched_per_gp_c_& other); + matched_per_gp_c_& operator=(const matched_per_gp_c_& other); + ~matched_per_gp_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + no_uematched_e_& no_uematched() + { + assert_choice_type(types::no_uematched, type_, "matchedPerGP"); + return c.get(); + } + matching_ueid_list_per_gp_l& one_or_more_uematched() + { + assert_choice_type(types::one_or_more_uematched, type_, "matchedPerGP"); + return c.get(); + } + const no_uematched_e_& no_uematched() const + { + assert_choice_type(types::no_uematched, type_, "matchedPerGP"); + return c.get(); + } + const matching_ueid_list_per_gp_l& one_or_more_uematched() const + { + assert_choice_type(types::one_or_more_uematched, type_, "matchedPerGP"); + return c.get(); + } + no_uematched_e_& set_no_uematched(); + matching_ueid_list_per_gp_l& set_one_or_more_uematched(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + matched_per_gp_c_ matched_per_gp; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementData ::= SEQUENCE (SIZE (1..65535)) OF MeasurementDataItem +using meas_data_l = dyn_array; + +// E2SM-KPM-IndicationMessage-Format1 ::= SEQUENCE +struct e2_sm_kpm_ind_msg_format1_s { + bool ext = false; + bool granul_period_present = false; + meas_data_l meas_data; + meas_info_list_l meas_info_list; + uint64_t granul_period = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingUEidList ::= SEQUENCE (SIZE (1..65535)) OF MatchingUEidItem +using matching_ueid_list_l = dyn_array; + +// MatchingUEidPerGP ::= SEQUENCE (SIZE (1..65535)) OF MatchingUEidPerGP-Item +using matching_ueid_per_gp_l = dyn_array; + +// MeasurementCondUEidItem ::= SEQUENCE +struct meas_cond_ueid_item_s { + bool ext = false; + meas_type_c meas_type; + matching_cond_list_l matching_cond; + matching_ueid_list_l matching_ueid_list; + // ... + copy_ptr matching_ueid_per_gp; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEMeasurementReportItem ::= SEQUENCE +struct ue_meas_report_item_s { + bool ext = false; + ueid_c ue_id; + e2_sm_kpm_ind_msg_format1_s meas_report; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementCondUEidList ::= SEQUENCE (SIZE (1..65535)) OF MeasurementCondUEidItem +using meas_cond_ueid_list_l = dyn_array; + +// UEMeasurementReportList ::= SEQUENCE (SIZE (1..65535)) OF UEMeasurementReportItem +using ue_meas_report_list_l = dyn_array; + +// E2SM-KPM-IndicationMessage-Format2 ::= SEQUENCE +struct e2_sm_kpm_ind_msg_format2_s { + bool ext = false; + bool granul_period_present = false; + meas_data_l meas_data; + meas_cond_ueid_list_l meas_cond_ueid_list; + uint64_t granul_period = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationMessage-Format3 ::= SEQUENCE +struct e2_sm_kpm_ind_msg_format3_s { + bool ext = false; + ue_meas_report_list_l ue_meas_report_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationMessage ::= SEQUENCE +struct e2_sm_kpm_ind_msg_s { + struct ind_msg_formats_c_ { + struct types_opts { + enum options { ind_msg_format1, ind_msg_format2, /*...*/ ind_msg_format3, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + ind_msg_formats_c_() = default; + ind_msg_formats_c_(const ind_msg_formats_c_& other); + ind_msg_formats_c_& operator=(const ind_msg_formats_c_& other); + ~ind_msg_formats_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_ind_msg_format1_s& ind_msg_format1() + { + assert_choice_type(types::ind_msg_format1, type_, "indicationMessage-formats"); + return c.get(); + } + e2_sm_kpm_ind_msg_format2_s& ind_msg_format2() + { + assert_choice_type(types::ind_msg_format2, type_, "indicationMessage-formats"); + return c.get(); + } + e2_sm_kpm_ind_msg_format3_s& ind_msg_format3() + { + assert_choice_type(types::ind_msg_format3, type_, "indicationMessage-formats"); + return c.get(); + } + const e2_sm_kpm_ind_msg_format1_s& ind_msg_format1() const + { + assert_choice_type(types::ind_msg_format1, type_, "indicationMessage-formats"); + return c.get(); + } + const e2_sm_kpm_ind_msg_format2_s& ind_msg_format2() const + { + assert_choice_type(types::ind_msg_format2, type_, "indicationMessage-formats"); + return c.get(); + } + const e2_sm_kpm_ind_msg_format3_s& ind_msg_format3() const + { + assert_choice_type(types::ind_msg_format3, type_, "indicationMessage-formats"); + return c.get(); + } + e2_sm_kpm_ind_msg_format1_s& set_ind_msg_format1(); + e2_sm_kpm_ind_msg_format2_s& set_ind_msg_format2(); + e2_sm_kpm_ind_msg_format3_s& set_ind_msg_format3(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + ind_msg_formats_c_ ind_msg_formats; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementInfo-Action-Item ::= SEQUENCE +struct meas_info_action_item_s { + bool ext = false; + bool meas_id_present = false; + printable_string<1, 150, true, true> meas_name; + uint32_t meas_id = 1; + // ... + copy_ptr bin_range_def; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementInfo-Action-List ::= SEQUENCE (SIZE (1..65535)) OF MeasurementInfo-Action-Item +using meas_info_action_list_l = dyn_array; + +// RANfunction-Name ::= SEQUENCE +struct ra_nfunction_name_s { + bool ext = false; + bool ran_function_instance_present = false; + printable_string<1, 150, true, true> ran_function_short_name; + printable_string<1, 1000, true, true> ran_function_e2_sm_oid; + printable_string<1, 150, true, true> ran_function_description; + int64_t ran_function_instance = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RIC-EventTriggerStyle-Item ::= SEQUENCE +struct ric_event_trigger_style_item_s { + bool ext = false; + int64_t ric_event_trigger_style_type = 0; + printable_string<1, 150, true, true> ric_event_trigger_style_name; + int64_t ric_event_trigger_format_type = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RIC-ReportStyle-Item ::= SEQUENCE +struct ric_report_style_item_s { + bool ext = false; + int64_t ric_report_style_type = 0; + printable_string<1, 150, true, true> ric_report_style_name; + int64_t ric_action_format_type = 0; + meas_info_action_list_l meas_info_action_list; + int64_t ric_ind_hdr_format_type = 0; + int64_t ric_ind_msg_format_type = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-RANfunction-Description ::= SEQUENCE +struct e2_sm_kpm_ra_nfunction_description_s { + using ric_event_trigger_style_list_l_ = dyn_array; + using ric_report_style_list_l_ = dyn_array; + + // member variables + bool ext = false; + ra_nfunction_name_s ran_function_name; + ric_event_trigger_style_list_l_ ric_event_trigger_style_list; + ric_report_style_list_l_ ric_report_style_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalRANNodeID ::= CHOICE +struct global_ran_node_id_c { + struct types_opts { + enum options { global_gnb_id, global_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_ran_node_id_c() = default; + global_ran_node_id_c(const global_ran_node_id_c& other); + global_ran_node_id_c& operator=(const global_ran_node_id_c& other); + ~global_ran_node_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_gnb_id_s& global_gnb_id() + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_ng_enb_id_s& global_ng_enb_id() + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_gnb_id_s& global_gnb_id() const + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_ng_enb_id_s& global_ng_enb_id() const + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_gnb_id_s& set_global_gnb_id(); + global_ng_enb_id_s& set_global_ng_enb_id(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// EN-GNB-ID ::= CHOICE +struct en_gnb_id_c { + struct types_opts { + enum options { en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::en_g_nb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& en_g_nb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& en_g_nb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalenGNB-ID ::= SEQUENCE +struct globalen_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + en_gnb_id_c en_g_nb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GroupID ::= CHOICE +struct group_id_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + group_id_c() = default; + group_id_c(const group_id_c& other); + group_id_c& operator=(const group_id_c& other); + ~group_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// InterfaceID-E1 ::= SEQUENCE +struct interface_id_e1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_cu_up_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-F1 ::= SEQUENCE +struct interface_id_f1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-NG ::= SEQUENCE +struct interface_id_ng_s { + bool ext = false; + guami_s guami; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-S1 ::= SEQUENCE +struct interface_id_s1_s { + bool ext = false; + gummei_s gummei; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-W1 ::= SEQUENCE +struct interface_id_w1_s { + bool ext = false; + global_ng_enb_id_s global_ng_enb_id; + uint64_t ng_enb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-X2 ::= SEQUENCE +struct interface_id_x2_s { + struct node_type_c_ { + struct types_opts { + enum options { global_enb_id, global_en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + node_type_c_() = default; + node_type_c_(const node_type_c_& other); + node_type_c_& operator=(const node_type_c_& other); + ~node_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_enb_id_s& global_enb_id() + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + globalen_gnb_id_s& global_en_g_nb_id() + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + const global_enb_id_s& global_enb_id() const + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + const globalen_gnb_id_s& global_en_g_nb_id() const + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + global_enb_id_s& set_global_enb_id(); + globalen_gnb_id_s& set_global_en_g_nb_id(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + node_type_c_ node_type; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-Xn ::= SEQUENCE +struct interface_id_xn_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceIdentifier ::= CHOICE +struct interface_id_c { + struct types_opts { + enum options { ng, xn, f1, e1, s1, x2, w1, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + interface_id_c() = default; + interface_id_c(const interface_id_c& other); + interface_id_c& operator=(const interface_id_c& other); + ~interface_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + interface_id_ng_s& ng() + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_xn_s& xn() + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_f1_s& f1() + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_e1_s& e1() + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_s1_s& s1() + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_x2_s& x2() + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_w1_s& w1() + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_ng_s& ng() const + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_xn_s& xn() const + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_f1_s& f1() const + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_e1_s& e1() const + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_s1_s& s1() const + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_x2_s& x2() const + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_w1_s& w1() const + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_ng_s& set_ng(); + interface_id_xn_s& set_xn(); + interface_id_f1_s& set_f1(); + interface_id_e1_s& set_e1(); + interface_id_s1_s& set_s1(); + interface_id_x2_s& set_x2(); + interface_id_w1_s& set_w1(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// FreqBandNrItem ::= SEQUENCE +struct freq_band_nr_item_s { + bool ext = false; + uint16_t freq_band_ind_nr = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-ARFCN ::= SEQUENCE +struct nr_arfcn_s { + using freq_band_list_nr_l_ = dyn_array; + + // member variables + bool ext = false; + uint32_t nrarfcn = 0; + freq_band_list_nr_l_ freq_band_list_nr; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// QoSID ::= CHOICE +struct qo_sid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + qo_sid_c() = default; + qo_sid_c(const qo_sid_c& other); + qo_sid_c& operator=(const qo_sid_c& other); + ~qo_sid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// RRCclass-LTE ::= ENUMERATED +struct rr_cclass_lte_opts { + enum options { + bcch_bch, + bcch_bch_mbms, + bcch_dl_sch, + bcch_dl_sch_br, + bcch_dl_sch_mbms, + mcch, + pcch, + dl_ccch, + dl_dcch, + ul_ccch, + ul_dcch, + sc_mcch, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated rr_cclass_lte_e; + +// RRCclass-NR ::= ENUMERATED +struct rr_cclass_nr_opts { + enum options { bcch_bch, bcch_dl_sch, dl_ccch, dl_dcch, pcch, ul_ccch, ul_ccch1, ul_dcch, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated rr_cclass_nr_e; + +// RRC-MessageID ::= SEQUENCE +struct rrc_msg_id_s { + struct rrc_type_c_ { + struct types_opts { + enum options { lte, nr, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + rrc_type_c_() = default; + rrc_type_c_(const rrc_type_c_& other); + rrc_type_c_& operator=(const rrc_type_c_& other); + ~rrc_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + rr_cclass_lte_e& lte() + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + rr_cclass_nr_e& nr() + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + const rr_cclass_lte_e& lte() const + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + const rr_cclass_nr_e& nr() const + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + rr_cclass_lte_e& set_lte(); + rr_cclass_nr_e& set_nr(); + + private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + rrc_type_c_ rrc_type; + int64_t msg_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ServingCell-ARFCN ::= CHOICE +struct serving_cell_arfcn_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_arfcn_c() = default; + serving_cell_arfcn_c(const serving_cell_arfcn_c& other); + serving_cell_arfcn_c& operator=(const serving_cell_arfcn_c& other); + ~serving_cell_arfcn_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_arfcn_s& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + uint32_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + const nr_arfcn_s& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + const uint32_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + nr_arfcn_s& set_nr(); + uint32_t& set_eutra(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// ServingCell-PCI ::= CHOICE +struct serving_cell_pci_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_pci_c() = default; + serving_cell_pci_c(const serving_cell_pci_c& other); + serving_cell_pci_c& operator=(const serving_cell_pci_c& other); + ~serving_cell_pci_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& set_nr(); + uint16_t& set_eutra(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +} // namespace e2sm_kpm +} // namespace asn1 diff --git a/lib/src/asn1/e2sm_kpm_v2.cpp b/lib/src/asn1/e2sm_kpm_v2.cpp new file mode 100644 index 000000000..8751cf43a --- /dev/null +++ b/lib/src/asn1/e2sm_kpm_v2.cpp @@ -0,0 +1,6574 @@ +/* + * + * 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/asn1/e2sm_kpm.h" +#include + +using namespace asn1; +using namespace asn1::e2sm_kpm; + +/******************************************************************************* + * Struct Methods + ******************************************************************************/ + +// BinRangeValue ::= CHOICE +void bin_range_value_c::destroy_() +{ + switch (type_) { + case types::value_real: + c.destroy(); + break; + default: + break; + } +} +void bin_range_value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::value_int: + break; + case types::value_real: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + } +} +bin_range_value_c::bin_range_value_c(const bin_range_value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::value_int: + c.init(other.c.get()); + break; + case types::value_real: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + } +} +bin_range_value_c& bin_range_value_c::operator=(const bin_range_value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::value_int: + c.set(other.c.get()); + break; + case types::value_real: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + } + + return *this; +} +int64_t& bin_range_value_c::set_value_int() +{ + set(types::value_int); + return c.get(); +} +real_s& bin_range_value_c::set_value_real() +{ + set(types::value_real); + return c.get(); +} +void bin_range_value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::value_int: + j.write_int("valueInt", c.get()); + break; + case types::value_real: + j.write_fieldname("valueReal"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + } + j.end_obj(); +} +SRSASN_CODE bin_range_value_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::value_int: + HANDLE_CODE(pack_unconstrained_integer(bref, c.get(), false, true)); + break; + case types::value_real: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE bin_range_value_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::value_int: + HANDLE_CODE(unpack_unconstrained_integer(c.get(), bref, false, true)); + break; + case types::value_real: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* bin_range_value_c::types_opts::to_string() const +{ + static const char* options[] = {"valueInt", "valueReal"}; + return convert_enum_idx(options, 2, value, "bin_range_value_c::types"); +} + +// BinRangeItem ::= SEQUENCE +SRSASN_CODE bin_range_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, bin_idx, (uint32_t)1u, (uint32_t)65535u, true, true)); + HANDLE_CODE(start_value.pack(bref)); + HANDLE_CODE(end_value.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE bin_range_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(bin_idx, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + HANDLE_CODE(start_value.unpack(bref)); + HANDLE_CODE(end_value.unpack(bref)); + + return SRSASN_SUCCESS; +} +void bin_range_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("binIndex", bin_idx); + j.write_fieldname("startValue"); + start_value.to_json(j); + j.write_fieldname("endValue"); + end_value.to_json(j); + j.end_obj(); +} + +// BinRangeDefinition ::= SEQUENCE +SRSASN_CODE bin_range_definition_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(bin_range_list_y.size() > 0, 1)); + HANDLE_CODE(bref.pack(bin_range_list_z.size() > 0, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, bin_range_list_x, 1, 65535, true)); + if (bin_range_list_y.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, bin_range_list_y, 1, 65535, true)); + } + if (bin_range_list_z.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, bin_range_list_z, 1, 65535, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE bin_range_definition_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool bin_range_list_y_present; + HANDLE_CODE(bref.unpack(bin_range_list_y_present, 1)); + bool bin_range_list_z_present; + HANDLE_CODE(bref.unpack(bin_range_list_z_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(bin_range_list_x, bref, 1, 65535, true)); + if (bin_range_list_y_present) { + HANDLE_CODE(unpack_dyn_seq_of(bin_range_list_y, bref, 1, 65535, true)); + } + if (bin_range_list_z_present) { + HANDLE_CODE(unpack_dyn_seq_of(bin_range_list_z, bref, 1, 65535, true)); + } + + return SRSASN_SUCCESS; +} +void bin_range_definition_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("binRangeListX"); + for (const auto& e1 : bin_range_list_x) { + e1.to_json(j); + } + j.end_array(); + if (bin_range_list_y.size() > 0) { + j.start_array("binRangeListY"); + for (const auto& e1 : bin_range_list_y) { + e1.to_json(j); + } + j.end_array(); + } + if (bin_range_list_z.size() > 0) { + j.start_array("binRangeListZ"); + for (const auto& e1 : bin_range_list_z) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// EUTRA-CGI ::= SEQUENCE +SRSASN_CODE eutra_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(eutra_cell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE eutra_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(eutra_cell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void eutra_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("eUTRACellIdentity", eutra_cell_id.to_string()); + j.end_obj(); +} + +// NR-CGI ::= SEQUENCE +SRSASN_CODE nr_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(nrcell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(nrcell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void nr_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("nRCellIdentity", nrcell_id.to_string()); + j.end_obj(); +} + +// CGI ::= CHOICE +void cgi_c::destroy_() +{ + switch (type_) { + case types::nr_cgi: + c.destroy(); + break; + case types::eutra_cgi: + c.destroy(); + break; + default: + break; + } +} +void cgi_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr_cgi: + c.init(); + break; + case types::eutra_cgi: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c::cgi_c(const cgi_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr_cgi: + c.init(other.c.get()); + break; + case types::eutra_cgi: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c& cgi_c::operator=(const cgi_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr_cgi: + c.set(other.c.get()); + break; + case types::eutra_cgi: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + + return *this; +} +nr_cgi_s& cgi_c::set_nr_cgi() +{ + set(types::nr_cgi); + return c.get(); +} +eutra_cgi_s& cgi_c::set_eutra_cgi() +{ + set(types::eutra_cgi); + return c.get(); +} +void cgi_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr_cgi: + j.write_fieldname("nR-CGI"); + c.get().to_json(j); + break; + case types::eutra_cgi: + j.write_fieldname("eUTRA-CGI"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + j.end_obj(); +} +SRSASN_CODE cgi_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE cgi_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* cgi_c::types_opts::to_string() const +{ + static const char* options[] = {"nR-CGI", "eUTRA-CGI"}; + return convert_enum_idx(options, 2, value, "cgi_c::types"); +} + +// GUAMI ::= SEQUENCE +SRSASN_CODE guami_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(amf_region_id.pack(bref)); + HANDLE_CODE(amf_set_id.pack(bref)); + HANDLE_CODE(amf_pointer.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE guami_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(amf_region_id.unpack(bref)); + HANDLE_CODE(amf_set_id.unpack(bref)); + HANDLE_CODE(amf_pointer.unpack(bref)); + + return SRSASN_SUCCESS; +} +void guami_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("aMFRegionID", amf_region_id.to_string()); + j.write_str("aMFSetID", amf_set_id.to_string()); + j.write_str("aMFPointer", amf_pointer.to_string()); + j.end_obj(); +} + +// GUMMEI ::= SEQUENCE +SRSASN_CODE gummei_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(mme_group_id.pack(bref)); + HANDLE_CODE(mme_code.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE gummei_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(mme_group_id.unpack(bref)); + HANDLE_CODE(mme_code.unpack(bref)); + + return SRSASN_SUCCESS; +} +void gummei_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_str("mME-Group-ID", mme_group_id.to_string()); + j.write_str("mME-Code", mme_code.to_string()); + j.end_obj(); +} + +// CoreCPID ::= CHOICE +void core_cpid_c::destroy_() +{ + switch (type_) { + case types::five_gc: + c.destroy(); + break; + case types::epc: + c.destroy(); + break; + default: + break; + } +} +void core_cpid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::five_gc: + c.init(); + break; + case types::epc: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c::core_cpid_c(const core_cpid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c& core_cpid_c::operator=(const core_cpid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + + return *this; +} +guami_s& core_cpid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +gummei_s& core_cpid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void core_cpid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_fieldname("fiveGC"); + c.get().to_json(j); + break; + case types::epc: + j.write_fieldname("ePC"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + j.end_obj(); +} +SRSASN_CODE core_cpid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE core_cpid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* core_cpid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "core_cpid_c::types"); +} +uint8_t core_cpid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "core_cpid_c::types"); +} + +// MeasurementType ::= CHOICE +void meas_type_c::destroy_() +{ + switch (type_) { + case types::meas_name: + c.destroy >(); + break; + default: + break; + } +} +void meas_type_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::meas_name: + c.init >(); + break; + case types::meas_id: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + } +} +meas_type_c::meas_type_c(const meas_type_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::meas_name: + c.init(other.c.get >()); + break; + case types::meas_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + } +} +meas_type_c& meas_type_c::operator=(const meas_type_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::meas_name: + c.set(other.c.get >()); + break; + case types::meas_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + } + + return *this; +} +printable_string<1, 150, true, true>& meas_type_c::set_meas_name() +{ + set(types::meas_name); + return c.get >(); +} +uint32_t& meas_type_c::set_meas_id() +{ + set(types::meas_id); + return c.get(); +} +void meas_type_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::meas_name: + j.write_str("measName", c.get >().to_string()); + break; + case types::meas_id: + j.write_int("measID", c.get()); + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + } + j.end_obj(); +} +SRSASN_CODE meas_type_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::meas_name: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::meas_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)1u, (uint32_t)65536u, true, true)); + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_type_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::meas_name: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::meas_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)1u, (uint32_t)65536u, true, true)); + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* meas_type_c::types_opts::to_string() const +{ + static const char* options[] = {"measName", "measID"}; + return convert_enum_idx(options, 2, value, "meas_type_c::types"); +} + +// DistMeasurementBinRangeItem ::= SEQUENCE +SRSASN_CODE dist_meas_bin_range_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(meas_type.pack(bref)); + HANDLE_CODE(bin_range_def.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE dist_meas_bin_range_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(meas_type.unpack(bref)); + HANDLE_CODE(bin_range_def.unpack(bref)); + + return SRSASN_SUCCESS; +} +void dist_meas_bin_range_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measType"); + meas_type.to_json(j); + j.write_fieldname("binRangeDef"); + bin_range_def.to_json(j); + j.end_obj(); +} + +// S-NSSAI ::= SEQUENCE +SRSASN_CODE s_nssai_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(sd_present, 1)); + + HANDLE_CODE(sst.pack(bref)); + if (sd_present) { + HANDLE_CODE(sd.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE s_nssai_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(sd_present, 1)); + + HANDLE_CODE(sst.unpack(bref)); + if (sd_present) { + HANDLE_CODE(sd.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void s_nssai_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("sST", sst.to_string()); + if (sd_present) { + j.write_str("sD", sd.to_string()); + } + j.end_obj(); +} + +// TestCond-Expression ::= ENUMERATED +const char* test_cond_expression_opts::to_string() const +{ + static const char* options[] = {"equal", "greaterthan", "lessthan", "contains", "present"}; + return convert_enum_idx(options, 5, value, "test_cond_expression_e"); +} + +// TestCond-Type ::= CHOICE +void test_cond_type_c::destroy_() {} +void test_cond_type_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +test_cond_type_c::test_cond_type_c(const test_cond_type_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gbr: + c.init(other.c.get()); + break; + case types::ambr: + c.init(other.c.get()); + break; + case types::is_stat: + c.init(other.c.get()); + break; + case types::is_cat_m: + c.init(other.c.get()); + break; + case types::rsrp: + c.init(other.c.get()); + break; + case types::rsrq: + c.init(other.c.get()); + break; + case types::ul_r_srp: + c.init(other.c.get()); + break; + case types::cqi: + c.init(other.c.get()); + break; + case types::five_qi: + c.init(other.c.get()); + break; + case types::qci: + c.init(other.c.get()); + break; + case types::snssai: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "test_cond_type_c"); + } +} +test_cond_type_c& test_cond_type_c::operator=(const test_cond_type_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gbr: + c.set(other.c.get()); + break; + case types::ambr: + c.set(other.c.get()); + break; + case types::is_stat: + c.set(other.c.get()); + break; + case types::is_cat_m: + c.set(other.c.get()); + break; + case types::rsrp: + c.set(other.c.get()); + break; + case types::rsrq: + c.set(other.c.get()); + break; + case types::ul_r_srp: + c.set(other.c.get()); + break; + case types::cqi: + c.set(other.c.get()); + break; + case types::five_qi: + c.set(other.c.get()); + break; + case types::qci: + c.set(other.c.get()); + break; + case types::snssai: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "test_cond_type_c"); + } + + return *this; +} +test_cond_type_c::gbr_e_& test_cond_type_c::set_gbr() +{ + set(types::gbr); + return c.get(); +} +test_cond_type_c::ambr_e_& test_cond_type_c::set_ambr() +{ + set(types::ambr); + return c.get(); +} +test_cond_type_c::is_stat_e_& test_cond_type_c::set_is_stat() +{ + set(types::is_stat); + return c.get(); +} +test_cond_type_c::is_cat_m_e_& test_cond_type_c::set_is_cat_m() +{ + set(types::is_cat_m); + return c.get(); +} +test_cond_type_c::rsrp_e_& test_cond_type_c::set_rsrp() +{ + set(types::rsrp); + return c.get(); +} +test_cond_type_c::rsrq_e_& test_cond_type_c::set_rsrq() +{ + set(types::rsrq); + return c.get(); +} +test_cond_type_c::ul_r_srp_e_& test_cond_type_c::set_ul_r_srp() +{ + set(types::ul_r_srp); + return c.get(); +} +test_cond_type_c::cqi_e_& test_cond_type_c::set_cqi() +{ + set(types::cqi); + return c.get(); +} +test_cond_type_c::five_qi_e_& test_cond_type_c::set_five_qi() +{ + set(types::five_qi); + return c.get(); +} +test_cond_type_c::qci_e_& test_cond_type_c::set_qci() +{ + set(types::qci); + return c.get(); +} +test_cond_type_c::snssai_e_& test_cond_type_c::set_snssai() +{ + set(types::snssai); + return c.get(); +} +void test_cond_type_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gbr: + j.write_str("gBR", "true"); + break; + case types::ambr: + j.write_str("aMBR", "true"); + break; + case types::is_stat: + j.write_str("isStat", "true"); + break; + case types::is_cat_m: + j.write_str("isCatM", "true"); + break; + case types::rsrp: + j.write_str("rSRP", "true"); + break; + case types::rsrq: + j.write_str("rSRQ", "true"); + break; + case types::ul_r_srp: + j.write_str("ul-rSRP", "true"); + break; + case types::cqi: + j.write_str("cQI", "true"); + break; + case types::five_qi: + j.write_str("fiveQI", "true"); + break; + case types::qci: + j.write_str("qCI", "true"); + break; + case types::snssai: + j.write_str("sNSSAI", "true"); + break; + default: + log_invalid_choice_id(type_, "test_cond_type_c"); + } + j.end_obj(); +} +SRSASN_CODE test_cond_type_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gbr: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ambr: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::is_stat: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::is_cat_m: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::rsrp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::rsrq: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ul_r_srp: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::cqi: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::five_qi: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::qci: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::snssai: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + default: + log_invalid_choice_id(type_, "test_cond_type_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE test_cond_type_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gbr: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ambr: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::is_stat: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::is_cat_m: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::rsrp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::rsrq: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ul_r_srp: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::cqi: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::five_qi: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::qci: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::snssai: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + default: + log_invalid_choice_id(type_, "test_cond_type_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* test_cond_type_c::gbr_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::gbr_e_"); +} + +const char* test_cond_type_c::ambr_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::ambr_e_"); +} + +const char* test_cond_type_c::is_stat_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::is_stat_e_"); +} + +const char* test_cond_type_c::is_cat_m_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::is_cat_m_e_"); +} + +const char* test_cond_type_c::rsrp_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::rsrp_e_"); +} + +const char* test_cond_type_c::rsrq_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::rsrq_e_"); +} + +const char* test_cond_type_c::ul_r_srp_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::ul_r_srp_e_"); +} + +const char* test_cond_type_c::cqi_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::cqi_e_"); +} + +const char* test_cond_type_c::five_qi_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::five_qi_e_"); +} + +const char* test_cond_type_c::qci_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::qci_e_"); +} + +const char* test_cond_type_c::snssai_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::snssai_e_"); +} + +const char* test_cond_type_c::types_opts::to_string() const +{ + static const char* options[] = { + "gBR", "aMBR", "isStat", "isCatM", "rSRP", "rSRQ", "ul-rSRP", "cQI", "fiveQI", "qCI", "sNSSAI"}; + return convert_enum_idx(options, 11, value, "test_cond_type_c::types"); +} +uint8_t test_cond_type_c::types_opts::to_number() const +{ + if (value == five_qi) { + return 5; + } + invalid_enum_number(value, "test_cond_type_c::types"); + return 0; +} + +// TestCond-Value ::= CHOICE +void test_cond_value_c::destroy_() +{ + switch (type_) { + case types::value_bool: + c.destroy(); + break; + case types::value_bit_s: + c.destroy(); + break; + case types::value_oct_s: + c.destroy >(); + break; + case types::value_prt_s: + c.destroy >(); + break; + case types::value_real: + c.destroy(); + break; + default: + break; + } +} +void test_cond_value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::value_int: + break; + case types::value_enum: + break; + case types::value_bool: + c.init(); + break; + case types::value_bit_s: + c.init(); + break; + case types::value_oct_s: + c.init >(); + break; + case types::value_prt_s: + c.init >(); + break; + case types::value_real: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + } +} +test_cond_value_c::test_cond_value_c(const test_cond_value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::value_int: + c.init(other.c.get()); + break; + case types::value_enum: + c.init(other.c.get()); + break; + case types::value_bool: + c.init(other.c.get()); + break; + case types::value_bit_s: + c.init(other.c.get()); + break; + case types::value_oct_s: + c.init(other.c.get >()); + break; + case types::value_prt_s: + c.init(other.c.get >()); + break; + case types::value_real: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + } +} +test_cond_value_c& test_cond_value_c::operator=(const test_cond_value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::value_int: + c.set(other.c.get()); + break; + case types::value_enum: + c.set(other.c.get()); + break; + case types::value_bool: + c.set(other.c.get()); + break; + case types::value_bit_s: + c.set(other.c.get()); + break; + case types::value_oct_s: + c.set(other.c.get >()); + break; + case types::value_prt_s: + c.set(other.c.get >()); + break; + case types::value_real: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + } + + return *this; +} +int64_t& test_cond_value_c::set_value_int() +{ + set(types::value_int); + return c.get(); +} +int64_t& test_cond_value_c::set_value_enum() +{ + set(types::value_enum); + return c.get(); +} +bool& test_cond_value_c::set_value_bool() +{ + set(types::value_bool); + return c.get(); +} +dyn_bitstring& test_cond_value_c::set_value_bit_s() +{ + set(types::value_bit_s); + return c.get(); +} +unbounded_octstring& test_cond_value_c::set_value_oct_s() +{ + set(types::value_oct_s); + return c.get >(); +} +printable_string<0, None, false, true>& test_cond_value_c::set_value_prt_s() +{ + set(types::value_prt_s); + return c.get >(); +} +real_s& test_cond_value_c::set_value_real() +{ + set(types::value_real); + return c.get(); +} +void test_cond_value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::value_int: + j.write_int("valueInt", c.get()); + break; + case types::value_enum: + j.write_int("valueEnum", c.get()); + break; + case types::value_bool: + j.write_bool("valueBool", c.get()); + break; + case types::value_bit_s: + j.write_str("valueBitS", c.get().to_string()); + break; + case types::value_oct_s: + j.write_str("valueOctS", c.get >().to_string()); + break; + case types::value_prt_s: + j.write_str("valuePrtS", c.get >().to_string()); + break; + case types::value_real: + j.write_fieldname("valueReal"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + } + j.end_obj(); +} +SRSASN_CODE test_cond_value_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::value_int: + HANDLE_CODE(pack_unconstrained_integer(bref, c.get(), false, true)); + break; + case types::value_enum: + HANDLE_CODE(pack_unconstrained_integer(bref, c.get(), false, true)); + break; + case types::value_bool: + HANDLE_CODE(bref.pack(c.get(), 1)); + break; + case types::value_bit_s: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::value_oct_s: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::value_prt_s: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::value_real: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE test_cond_value_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::value_int: + HANDLE_CODE(unpack_unconstrained_integer(c.get(), bref, false, true)); + break; + case types::value_enum: + HANDLE_CODE(unpack_unconstrained_integer(c.get(), bref, false, true)); + break; + case types::value_bool: + HANDLE_CODE(bref.unpack(c.get(), 1)); + break; + case types::value_bit_s: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::value_oct_s: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::value_prt_s: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::value_real: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* test_cond_value_c::types_opts::to_string() const +{ + static const char* options[] = { + "valueInt", "valueEnum", "valueBool", "valueBitS", "valueOctS", "valuePrtS", "valueReal"}; + return convert_enum_idx(options, 7, value, "test_cond_value_c::types"); +} + +// ENB-ID ::= CHOICE +void enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_enb_id: + c.destroy >(); + break; + case types::home_enb_id: + c.destroy >(); + break; + case types::short_macro_enb_id: + c.destroy >(); + break; + case types::long_macro_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_enb_id: + c.init >(); + break; + case types::home_enb_id: + c.init >(); + break; + case types::short_macro_enb_id: + c.init >(); + break; + case types::long_macro_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c::enb_id_c(const enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_enb_id: + c.init(other.c.get >()); + break; + case types::home_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c& enb_id_c::operator=(const enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_enb_id: + c.set(other.c.get >()); + break; + case types::home_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_c::set_macro_enb_id() +{ + set(types::macro_enb_id); + return c.get >(); +} +fixed_bitstring<28, false, true>& enb_id_c::set_home_enb_id() +{ + set(types::home_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_c::set_short_macro_enb_id() +{ + set(types::short_macro_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_c::set_long_macro_enb_id() +{ + set(types::long_macro_enb_id); + return c.get >(); +} +void enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_enb_id: + j.write_str("macro-eNB-ID", c.get >().to_string()); + break; + case types::home_enb_id: + j.write_str("home-eNB-ID", c.get >().to_string()); + break; + case types::short_macro_enb_id: + j.write_str("short-Macro-eNB-ID", c.get >().to_string()); + break; + case types::long_macro_enb_id: + j.write_str("long-Macro-eNB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macro-eNB-ID", "home-eNB-ID", "short-Macro-eNB-ID", "long-Macro-eNB-ID"}; + return convert_enum_idx(options, 4, value, "enb_id_c::types"); +} + +// GNB-ID ::= CHOICE +void gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB-ID"}; + return convert_enum_idx(options, 1, value, "gnb_id_c::types"); +} + +// MeasurementLabel ::= SEQUENCE +SRSASN_CODE meas_label_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(no_label_present, 1)); + HANDLE_CODE(bref.pack(plmn_id_present, 1)); + HANDLE_CODE(bref.pack(slice_id_present, 1)); + HANDLE_CODE(bref.pack(five_qi_present, 1)); + HANDLE_CODE(bref.pack(qfi_present, 1)); + HANDLE_CODE(bref.pack(qci_present, 1)); + HANDLE_CODE(bref.pack(qcimax_present, 1)); + HANDLE_CODE(bref.pack(qcimin_present, 1)); + HANDLE_CODE(bref.pack(arpmax_present, 1)); + HANDLE_CODE(bref.pack(arpmin_present, 1)); + HANDLE_CODE(bref.pack(bitrate_range_present, 1)); + HANDLE_CODE(bref.pack(layer_mu_mimo_present, 1)); + HANDLE_CODE(bref.pack(sum_present, 1)); + HANDLE_CODE(bref.pack(dist_bin_x_present, 1)); + HANDLE_CODE(bref.pack(dist_bin_y_present, 1)); + HANDLE_CODE(bref.pack(dist_bin_z_present, 1)); + HANDLE_CODE(bref.pack(pre_label_override_present, 1)); + HANDLE_CODE(bref.pack(start_end_ind_present, 1)); + HANDLE_CODE(bref.pack(min_present, 1)); + HANDLE_CODE(bref.pack(max_present, 1)); + HANDLE_CODE(bref.pack(avg_present, 1)); + + if (no_label_present) { + HANDLE_CODE(no_label.pack(bref)); + } + if (plmn_id_present) { + HANDLE_CODE(plmn_id.pack(bref)); + } + if (slice_id_present) { + HANDLE_CODE(slice_id.pack(bref)); + } + if (five_qi_present) { + HANDLE_CODE(pack_integer(bref, five_qi, (uint16_t)0u, (uint16_t)255u, true, true)); + } + if (qfi_present) { + HANDLE_CODE(pack_integer(bref, qfi, (uint8_t)0u, (uint8_t)63u, true, true)); + } + if (qci_present) { + HANDLE_CODE(pack_integer(bref, qci, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qcimax_present) { + HANDLE_CODE(pack_integer(bref, qcimax, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qcimin_present) { + HANDLE_CODE(pack_integer(bref, qcimin, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (arpmax_present) { + HANDLE_CODE(pack_integer(bref, arpmax, (uint8_t)1u, (uint8_t)15u, true, true)); + } + if (arpmin_present) { + HANDLE_CODE(pack_integer(bref, arpmin, (uint8_t)1u, (uint8_t)15u, true, true)); + } + if (bitrate_range_present) { + HANDLE_CODE(pack_integer(bref, bitrate_range, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (layer_mu_mimo_present) { + HANDLE_CODE(pack_integer(bref, layer_mu_mimo, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (sum_present) { + HANDLE_CODE(sum.pack(bref)); + } + if (dist_bin_x_present) { + HANDLE_CODE(pack_integer(bref, dist_bin_x, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (dist_bin_y_present) { + HANDLE_CODE(pack_integer(bref, dist_bin_y, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (dist_bin_z_present) { + HANDLE_CODE(pack_integer(bref, dist_bin_z, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (pre_label_override_present) { + HANDLE_CODE(pre_label_override.pack(bref)); + } + if (start_end_ind_present) { + HANDLE_CODE(start_end_ind.pack(bref)); + } + if (min_present) { + HANDLE_CODE(min.pack(bref)); + } + if (max_present) { + HANDLE_CODE(max.pack(bref)); + } + if (avg_present) { + HANDLE_CODE(avg.pack(bref)); + } + + if (ext) { + HANDLE_CODE(bref.pack(ssb_idx_present, 1)); + HANDLE_CODE(bref.pack(non_go_b_bfmode_idx_present, 1)); + HANDLE_CODE(bref.pack(mimo_mode_idx_present, 1)); + + if (ssb_idx_present) { + HANDLE_CODE(pack_integer(bref, ssb_idx, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (non_go_b_bfmode_idx_present) { + HANDLE_CODE(pack_integer(bref, non_go_b_bfmode_idx, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (mimo_mode_idx_present) { + HANDLE_CODE(pack_integer(bref, mimo_mode_idx, (uint8_t)1u, (uint8_t)2u, true, true)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_label_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(no_label_present, 1)); + HANDLE_CODE(bref.unpack(plmn_id_present, 1)); + HANDLE_CODE(bref.unpack(slice_id_present, 1)); + HANDLE_CODE(bref.unpack(five_qi_present, 1)); + HANDLE_CODE(bref.unpack(qfi_present, 1)); + HANDLE_CODE(bref.unpack(qci_present, 1)); + HANDLE_CODE(bref.unpack(qcimax_present, 1)); + HANDLE_CODE(bref.unpack(qcimin_present, 1)); + HANDLE_CODE(bref.unpack(arpmax_present, 1)); + HANDLE_CODE(bref.unpack(arpmin_present, 1)); + HANDLE_CODE(bref.unpack(bitrate_range_present, 1)); + HANDLE_CODE(bref.unpack(layer_mu_mimo_present, 1)); + HANDLE_CODE(bref.unpack(sum_present, 1)); + HANDLE_CODE(bref.unpack(dist_bin_x_present, 1)); + HANDLE_CODE(bref.unpack(dist_bin_y_present, 1)); + HANDLE_CODE(bref.unpack(dist_bin_z_present, 1)); + HANDLE_CODE(bref.unpack(pre_label_override_present, 1)); + HANDLE_CODE(bref.unpack(start_end_ind_present, 1)); + HANDLE_CODE(bref.unpack(min_present, 1)); + HANDLE_CODE(bref.unpack(max_present, 1)); + HANDLE_CODE(bref.unpack(avg_present, 1)); + + if (no_label_present) { + HANDLE_CODE(no_label.unpack(bref)); + } + if (plmn_id_present) { + HANDLE_CODE(plmn_id.unpack(bref)); + } + if (slice_id_present) { + HANDLE_CODE(slice_id.unpack(bref)); + } + if (five_qi_present) { + HANDLE_CODE(unpack_integer(five_qi, bref, (uint16_t)0u, (uint16_t)255u, true, true)); + } + if (qfi_present) { + HANDLE_CODE(unpack_integer(qfi, bref, (uint8_t)0u, (uint8_t)63u, true, true)); + } + if (qci_present) { + HANDLE_CODE(unpack_integer(qci, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qcimax_present) { + HANDLE_CODE(unpack_integer(qcimax, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qcimin_present) { + HANDLE_CODE(unpack_integer(qcimin, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (arpmax_present) { + HANDLE_CODE(unpack_integer(arpmax, bref, (uint8_t)1u, (uint8_t)15u, true, true)); + } + if (arpmin_present) { + HANDLE_CODE(unpack_integer(arpmin, bref, (uint8_t)1u, (uint8_t)15u, true, true)); + } + if (bitrate_range_present) { + HANDLE_CODE(unpack_integer(bitrate_range, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (layer_mu_mimo_present) { + HANDLE_CODE(unpack_integer(layer_mu_mimo, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (sum_present) { + HANDLE_CODE(sum.unpack(bref)); + } + if (dist_bin_x_present) { + HANDLE_CODE(unpack_integer(dist_bin_x, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (dist_bin_y_present) { + HANDLE_CODE(unpack_integer(dist_bin_y, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (dist_bin_z_present) { + HANDLE_CODE(unpack_integer(dist_bin_z, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (pre_label_override_present) { + HANDLE_CODE(pre_label_override.unpack(bref)); + } + if (start_end_ind_present) { + HANDLE_CODE(start_end_ind.unpack(bref)); + } + if (min_present) { + HANDLE_CODE(min.unpack(bref)); + } + if (max_present) { + HANDLE_CODE(max.unpack(bref)); + } + if (avg_present) { + HANDLE_CODE(avg.unpack(bref)); + } + + if (ext) { + HANDLE_CODE(bref.unpack(ssb_idx_present, 1)); + HANDLE_CODE(bref.unpack(non_go_b_bfmode_idx_present, 1)); + HANDLE_CODE(bref.unpack(mimo_mode_idx_present, 1)); + + if (ssb_idx_present) { + HANDLE_CODE(unpack_integer(ssb_idx, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (non_go_b_bfmode_idx_present) { + HANDLE_CODE(unpack_integer(non_go_b_bfmode_idx, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (mimo_mode_idx_present) { + HANDLE_CODE(unpack_integer(mimo_mode_idx, bref, (uint8_t)1u, (uint8_t)2u, true, true)); + } + } + return SRSASN_SUCCESS; +} +void meas_label_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (no_label_present) { + j.write_str("noLabel", "true"); + } + if (plmn_id_present) { + j.write_str("plmnID", plmn_id.to_string()); + } + if (slice_id_present) { + j.write_fieldname("sliceID"); + slice_id.to_json(j); + } + if (five_qi_present) { + j.write_int("fiveQI", five_qi); + } + if (qfi_present) { + j.write_int("qFI", qfi); + } + if (qci_present) { + j.write_int("qCI", qci); + } + if (qcimax_present) { + j.write_int("qCImax", qcimax); + } + if (qcimin_present) { + j.write_int("qCImin", qcimin); + } + if (arpmax_present) { + j.write_int("aRPmax", arpmax); + } + if (arpmin_present) { + j.write_int("aRPmin", arpmin); + } + if (bitrate_range_present) { + j.write_int("bitrateRange", bitrate_range); + } + if (layer_mu_mimo_present) { + j.write_int("layerMU-MIMO", layer_mu_mimo); + } + if (sum_present) { + j.write_str("sUM", "true"); + } + if (dist_bin_x_present) { + j.write_int("distBinX", dist_bin_x); + } + if (dist_bin_y_present) { + j.write_int("distBinY", dist_bin_y); + } + if (dist_bin_z_present) { + j.write_int("distBinZ", dist_bin_z); + } + if (pre_label_override_present) { + j.write_str("preLabelOverride", "true"); + } + if (start_end_ind_present) { + j.write_str("startEndInd", start_end_ind.to_string()); + } + if (min_present) { + j.write_str("min", "true"); + } + if (max_present) { + j.write_str("max", "true"); + } + if (avg_present) { + j.write_str("avg", "true"); + } + if (ext) { + if (ssb_idx_present) { + j.write_int("ssbIndex", ssb_idx); + } + if (non_go_b_bfmode_idx_present) { + j.write_int("nonGoB-BFmode-Index", non_go_b_bfmode_idx); + } + if (mimo_mode_idx_present) { + j.write_int("mIMO-mode-Index", mimo_mode_idx); + } + } + j.end_obj(); +} + +const char* meas_label_s::no_label_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::no_label_e_"); +} + +const char* meas_label_s::sum_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::sum_e_"); +} + +const char* meas_label_s::pre_label_override_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::pre_label_override_e_"); +} + +const char* meas_label_s::start_end_ind_opts::to_string() const +{ + static const char* options[] = {"start", "end"}; + return convert_enum_idx(options, 2, value, "meas_label_s::start_end_ind_e_"); +} + +const char* meas_label_s::min_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::min_e_"); +} + +const char* meas_label_s::max_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::max_e_"); +} + +const char* meas_label_s::avg_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::avg_e_"); +} + +// NgENB-ID ::= CHOICE +void ng_enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_ng_enb_id: + c.destroy >(); + break; + case types::short_macro_ng_enb_id: + c.destroy >(); + break; + case types::long_macro_ng_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void ng_enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_ng_enb_id: + c.init >(); + break; + case types::short_macro_ng_enb_id: + c.init >(); + break; + case types::long_macro_ng_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c::ng_enb_id_c(const ng_enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c& ng_enb_id_c::operator=(const ng_enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& ng_enb_id_c::set_macro_ng_enb_id() +{ + set(types::macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& ng_enb_id_c::set_short_macro_ng_enb_id() +{ + set(types::short_macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& ng_enb_id_c::set_long_macro_ng_enb_id() +{ + set(types::long_macro_ng_enb_id); + return c.get >(); +} +void ng_enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_ng_enb_id: + j.write_str("macroNgENB-ID", c.get >().to_string()); + break; + case types::short_macro_ng_enb_id: + j.write_str("shortMacroNgENB-ID", c.get >().to_string()); + break; + case types::long_macro_ng_enb_id: + j.write_str("longMacroNgENB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE ng_enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ng_enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ng_enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macroNgENB-ID", "shortMacroNgENB-ID", "longMacroNgENB-ID"}; + return convert_enum_idx(options, 3, value, "ng_enb_id_c::types"); +} + +// TestCondInfo ::= SEQUENCE +SRSASN_CODE test_cond_info_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(test_expr_present, 1)); + HANDLE_CODE(bref.pack(test_value_present, 1)); + + HANDLE_CODE(test_type.pack(bref)); + if (test_expr_present) { + HANDLE_CODE(test_expr.pack(bref)); + } + if (test_value_present) { + HANDLE_CODE(test_value.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE test_cond_info_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(test_expr_present, 1)); + HANDLE_CODE(bref.unpack(test_value_present, 1)); + + HANDLE_CODE(test_type.unpack(bref)); + if (test_expr_present) { + HANDLE_CODE(test_expr.unpack(bref)); + } + if (test_value_present) { + HANDLE_CODE(test_value.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void test_cond_info_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("testType"); + test_type.to_json(j); + if (test_expr_present) { + j.write_str("testExpr", test_expr.to_string()); + } + if (test_value_present) { + j.write_fieldname("testValue"); + test_value.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_e1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + j.end_obj(); +} + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_f1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + j.end_obj(); +} + +// GlobalENB-ID ::= SEQUENCE +SRSASN_CODE global_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("eNB-ID"); + enb_id.to_json(j); + j.end_obj(); +} + +// GlobalGNB-ID ::= SEQUENCE +SRSASN_CODE global_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("gNB-ID"); + gnb_id.to_json(j); + j.end_obj(); +} + +// GlobalNgENB-ID ::= SEQUENCE +SRSASN_CODE global_ng_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(ng_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ng_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(ng_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_ng_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("ngENB-ID"); + ng_enb_id.to_json(j); + j.end_obj(); +} + +// LabelInfoItem ::= SEQUENCE +SRSASN_CODE label_info_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(meas_label.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE label_info_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(meas_label.unpack(bref)); + + return SRSASN_SUCCESS; +} +void label_info_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measLabel"); + meas_label.to_json(j); + j.end_obj(); +} + +// LogicalOR ::= ENUMERATED +const char* lc_or_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "lc_or_e"); +} + +// MatchingCondItem-Choice ::= CHOICE +void matching_cond_item_choice_c::destroy_() +{ + switch (type_) { + case types::meas_label: + c.destroy(); + break; + case types::test_cond_info: + c.destroy(); + break; + default: + break; + } +} +void matching_cond_item_choice_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::meas_label: + c.init(); + break; + case types::test_cond_info: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + } +} +matching_cond_item_choice_c::matching_cond_item_choice_c(const matching_cond_item_choice_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::meas_label: + c.init(other.c.get()); + break; + case types::test_cond_info: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + } +} +matching_cond_item_choice_c& matching_cond_item_choice_c::operator=(const matching_cond_item_choice_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::meas_label: + c.set(other.c.get()); + break; + case types::test_cond_info: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + } + + return *this; +} +meas_label_s& matching_cond_item_choice_c::set_meas_label() +{ + set(types::meas_label); + return c.get(); +} +test_cond_info_s& matching_cond_item_choice_c::set_test_cond_info() +{ + set(types::test_cond_info); + return c.get(); +} +void matching_cond_item_choice_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::meas_label: + j.write_fieldname("measLabel"); + c.get().to_json(j); + break; + case types::test_cond_info: + j.write_fieldname("testCondInfo"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + } + j.end_obj(); +} +SRSASN_CODE matching_cond_item_choice_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::meas_label: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::test_cond_info: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_cond_item_choice_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::meas_label: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::test_cond_info: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* matching_cond_item_choice_c::types_opts::to_string() const +{ + static const char* options[] = {"measLabel", "testCondInfo"}; + return convert_enum_idx(options, 2, value, "matching_cond_item_choice_c::types"); +} + +// MatchingCondItem ::= SEQUENCE +SRSASN_CODE matching_cond_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(lc_or_present, 1)); + + HANDLE_CODE(matching_cond_choice.pack(bref)); + if (lc_or_present) { + HANDLE_CODE(lc_or.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_cond_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(lc_or_present, 1)); + + HANDLE_CODE(matching_cond_choice.unpack(bref)); + if (lc_or_present) { + HANDLE_CODE(lc_or.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void matching_cond_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("matchingCondChoice"); + matching_cond_choice.to_json(j); + if (lc_or_present) { + j.write_str("logicalOR", "true"); + } + j.end_obj(); +} + +// UEID-EN-GNB ::= SEQUENCE +SRSASN_CODE ueid_en_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.pack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_en_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_en_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + if (gnb_cu_ue_f1_ap_id_present) { + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-ENB ::= SEQUENCE +SRSASN_CODE ueid_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(global_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, mme_ue_s1ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.pack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(global_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(mme_ue_s1ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.unpack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("mME-UE-S1AP-ID", mme_ue_s1ap_id); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + if (m_enb_ue_x2ap_id_present) { + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + } + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + if (global_enb_id_present) { + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB ::= SEQUENCE +SRSASN_CODE ueid_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_gnb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_ue_f1_ap_id_list, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool gnb_cu_ue_f1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_list_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_gnb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_ue_f1_ap_id_list, bref, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-UE-F1AP-ID-List"); + for (const auto& e1 : gnb_cu_ue_f1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_gnb_id_present) { + j.write_fieldname("globalGNB-ID"); + global_gnb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB-CU-UP ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_up_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_up_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_up_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-GNB-DU ::= SEQUENCE +SRSASN_CODE ueid_gnb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-NG-ENB ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (ng_enb_cu_ue_w1_ap_id_present) { + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_ng_enb_id_present) { + j.write_fieldname("globalNgENB-ID"); + global_ng_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-NG-ENB-DU ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + j.end_obj(); +} + +// MeasurementInfoItem ::= SEQUENCE +SRSASN_CODE meas_info_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(meas_type.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, label_info_list, 1, 2147483647, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_info_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(meas_type.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(label_info_list, bref, 1, 2147483647, true)); + + return SRSASN_SUCCESS; +} +void meas_info_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measType"); + meas_type.to_json(j); + j.start_array("labelInfoList"); + for (const auto& e1 : label_info_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// UEID ::= CHOICE +void ueid_c::destroy_() +{ + switch (type_) { + case types::gnb_ueid: + c.destroy(); + break; + case types::gnb_du_ueid: + c.destroy(); + break; + case types::gnb_cu_up_ueid: + c.destroy(); + break; + case types::ng_enb_ueid: + c.destroy(); + break; + case types::ng_enb_du_ueid: + c.destroy(); + break; + case types::en_g_nb_ueid: + c.destroy(); + break; + case types::enb_ueid: + c.destroy(); + break; + default: + break; + } +} +void ueid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb_ueid: + c.init(); + break; + case types::gnb_du_ueid: + c.init(); + break; + case types::gnb_cu_up_ueid: + c.init(); + break; + case types::ng_enb_ueid: + c.init(); + break; + case types::ng_enb_du_ueid: + c.init(); + break; + case types::en_g_nb_ueid: + c.init(); + break; + case types::enb_ueid: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c::ueid_c(const ueid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb_ueid: + c.init(other.c.get()); + break; + case types::gnb_du_ueid: + c.init(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.init(other.c.get()); + break; + case types::en_g_nb_ueid: + c.init(other.c.get()); + break; + case types::enb_ueid: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c& ueid_c::operator=(const ueid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb_ueid: + c.set(other.c.get()); + break; + case types::gnb_du_ueid: + c.set(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.set(other.c.get()); + break; + case types::en_g_nb_ueid: + c.set(other.c.get()); + break; + case types::enb_ueid: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + + return *this; +} +ueid_gnb_s& ueid_c::set_gnb_ueid() +{ + set(types::gnb_ueid); + return c.get(); +} +ueid_gnb_du_s& ueid_c::set_gnb_du_ueid() +{ + set(types::gnb_du_ueid); + return c.get(); +} +ueid_gnb_cu_up_s& ueid_c::set_gnb_cu_up_ueid() +{ + set(types::gnb_cu_up_ueid); + return c.get(); +} +ueid_ng_enb_s& ueid_c::set_ng_enb_ueid() +{ + set(types::ng_enb_ueid); + return c.get(); +} +ueid_ng_enb_du_s& ueid_c::set_ng_enb_du_ueid() +{ + set(types::ng_enb_du_ueid); + return c.get(); +} +ueid_en_gnb_s& ueid_c::set_en_g_nb_ueid() +{ + set(types::en_g_nb_ueid); + return c.get(); +} +ueid_enb_s& ueid_c::set_enb_ueid() +{ + set(types::enb_ueid); + return c.get(); +} +void ueid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb_ueid: + j.write_fieldname("gNB-UEID"); + c.get().to_json(j); + break; + case types::gnb_du_ueid: + j.write_fieldname("gNB-DU-UEID"); + c.get().to_json(j); + break; + case types::gnb_cu_up_ueid: + j.write_fieldname("gNB-CU-UP-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_ueid: + j.write_fieldname("ng-eNB-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_du_ueid: + j.write_fieldname("ng-eNB-DU-UEID"); + c.get().to_json(j); + break; + case types::en_g_nb_ueid: + j.write_fieldname("en-gNB-UEID"); + c.get().to_json(j); + break; + case types::enb_ueid: + j.write_fieldname("eNB-UEID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + j.end_obj(); +} +SRSASN_CODE ueid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ueid_c::types_opts::to_string() const +{ + static const char* options[] = { + "gNB-UEID", "gNB-DU-UEID", "gNB-CU-UP-UEID", "ng-eNB-UEID", "ng-eNB-DU-UEID", "en-gNB-UEID", "eNB-UEID"}; + return convert_enum_idx(options, 7, value, "ueid_c::types"); +} + +// MatchingUEidPerSubItem ::= SEQUENCE +SRSASN_CODE matching_ueid_per_sub_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ue_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ueid_per_sub_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ue_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void matching_ueid_per_sub_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ueID"); + ue_id.to_json(j); + j.end_obj(); +} + +// MatchingUeCondPerSubItem ::= SEQUENCE +SRSASN_CODE matching_ue_cond_per_sub_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(test_cond_info.pack(bref)); + + if (ext) { + HANDLE_CODE(bref.pack(lc_or_present, 1)); + + if (lc_or_present) { + HANDLE_CODE(lc_or.pack(bref)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ue_cond_per_sub_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(test_cond_info.unpack(bref)); + + if (ext) { + HANDLE_CODE(bref.unpack(lc_or_present, 1)); + + if (lc_or_present) { + HANDLE_CODE(lc_or.unpack(bref)); + } + } + return SRSASN_SUCCESS; +} +void matching_ue_cond_per_sub_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("testCondInfo"); + test_cond_info.to_json(j); + if (ext) { + if (lc_or_present) { + j.write_str("logicalOR", "true"); + } + } + j.end_obj(); +} + +// MeasurementCondItem ::= SEQUENCE +SRSASN_CODE meas_cond_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(meas_type.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, matching_cond, 1, 32768, true)); + + if (ext) { + HANDLE_CODE(bref.pack(bin_range_def.is_present(), 1)); + + if (bin_range_def.is_present()) { + HANDLE_CODE(bin_range_def->pack(bref)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_cond_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(meas_type.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(matching_cond, bref, 1, 32768, true)); + + if (ext) { + bool bin_range_def_present; + HANDLE_CODE(bref.unpack(bin_range_def_present, 1)); + bin_range_def.set_present(bin_range_def_present); + + if (bin_range_def.is_present()) { + HANDLE_CODE(bin_range_def->unpack(bref)); + } + } + return SRSASN_SUCCESS; +} +void meas_cond_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measType"); + meas_type.to_json(j); + j.start_array("matchingCond"); + for (const auto& e1 : matching_cond) { + e1.to_json(j); + } + j.end_array(); + if (ext) { + if (bin_range_def.is_present()) { + j.write_fieldname("binRangeDef"); + bin_range_def->to_json(j); + } + } + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(cell_global_id_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, meas_info_list, 1, 65535, true)); + HANDLE_CODE(pack_integer(bref, granul_period, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + if (cell_global_id_present) { + HANDLE_CODE(cell_global_id.pack(bref)); + } + + if (ext) { + HANDLE_CODE(bref.pack(dist_meas_bin_range_info.is_present(), 1)); + + if (dist_meas_bin_range_info.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *dist_meas_bin_range_info, 1, 65535, true)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(cell_global_id_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(meas_info_list, bref, 1, 65535, true)); + HANDLE_CODE(unpack_integer(granul_period, bref, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + if (cell_global_id_present) { + HANDLE_CODE(cell_global_id.unpack(bref)); + } + + if (ext) { + bool dist_meas_bin_range_info_present; + HANDLE_CODE(bref.unpack(dist_meas_bin_range_info_present, 1)); + dist_meas_bin_range_info.set_present(dist_meas_bin_range_info_present); + + if (dist_meas_bin_range_info.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*dist_meas_bin_range_info, bref, 1, 65535, true)); + } + } + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_format1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("measInfoList"); + for (const auto& e1 : meas_info_list) { + e1.to_json(j); + } + j.end_array(); + j.write_int("granulPeriod", granul_period); + if (cell_global_id_present) { + j.write_fieldname("cellGlobalID"); + cell_global_id.to_json(j); + } + if (ext) { + if (dist_meas_bin_range_info.is_present()) { + j.start_array("distMeasBinRangeInfo"); + for (const auto& e1 : *dist_meas_bin_range_info) { + e1.to_json(j); + } + j.end_array(); + } + } + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition-Format2 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_format2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ue_id.pack(bref)); + HANDLE_CODE(subscript_info.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_format2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ue_id.unpack(bref)); + HANDLE_CODE(subscript_info.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_format2_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ueID"); + ue_id.to_json(j); + j.write_fieldname("subscriptInfo"); + subscript_info.to_json(j); + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition-Format3 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_format3_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(cell_global_id_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, meas_cond_list, 1, 65535, true)); + HANDLE_CODE(pack_integer(bref, granul_period, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + if (cell_global_id_present) { + HANDLE_CODE(cell_global_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_format3_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(cell_global_id_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(meas_cond_list, bref, 1, 65535, true)); + HANDLE_CODE(unpack_integer(granul_period, bref, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + if (cell_global_id_present) { + HANDLE_CODE(cell_global_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_format3_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("measCondList"); + for (const auto& e1 : meas_cond_list) { + e1.to_json(j); + } + j.end_array(); + j.write_int("granulPeriod", granul_period); + if (cell_global_id_present) { + j.write_fieldname("cellGlobalID"); + cell_global_id.to_json(j); + } + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition-Format4 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_format4_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, matching_ue_cond_list, 1, 32768, true)); + HANDLE_CODE(subscription_info.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_format4_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(matching_ue_cond_list, bref, 1, 32768, true)); + HANDLE_CODE(subscription_info.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_format4_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("matchingUeCondList"); + for (const auto& e1 : matching_ue_cond_list) { + e1.to_json(j); + } + j.end_array(); + j.write_fieldname("subscriptionInfo"); + subscription_info.to_json(j); + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition-Format5 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_format5_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, matching_ueid_list, 2, 65535, true)); + HANDLE_CODE(subscription_info.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_format5_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(matching_ueid_list, bref, 2, 65535, true)); + HANDLE_CODE(subscription_info.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_format5_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("matchingUEidList"); + for (const auto& e1 : matching_ueid_list) { + e1.to_json(j); + } + j.end_array(); + j.write_fieldname("subscriptionInfo"); + subscription_info.to_json(j); + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_style_type, false, true)); + HANDLE_CODE(action_definition_formats.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_style_type, bref, false, true)); + HANDLE_CODE(action_definition_formats.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-Style-Type", ric_style_type); + j.write_fieldname("actionDefinition-formats"); + action_definition_formats.to_json(j); + j.end_obj(); +} + +void e2_sm_kpm_action_definition_s::action_definition_formats_c_::destroy_() +{ + switch (type_) { + case types::action_definition_format1: + c.destroy(); + break; + case types::action_definition_format2: + c.destroy(); + break; + case types::action_definition_format3: + c.destroy(); + break; + case types::action_definition_format4: + c.destroy(); + break; + case types::action_definition_format5: + c.destroy(); + break; + default: + break; + } +} +void e2_sm_kpm_action_definition_s::action_definition_formats_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::action_definition_format1: + c.init(); + break; + case types::action_definition_format2: + c.init(); + break; + case types::action_definition_format3: + c.init(); + break; + case types::action_definition_format4: + c.init(); + break; + case types::action_definition_format5: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + } +} +e2_sm_kpm_action_definition_s::action_definition_formats_c_::action_definition_formats_c_( + const e2_sm_kpm_action_definition_s::action_definition_formats_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::action_definition_format1: + c.init(other.c.get()); + break; + case types::action_definition_format2: + c.init(other.c.get()); + break; + case types::action_definition_format3: + c.init(other.c.get()); + break; + case types::action_definition_format4: + c.init(other.c.get()); + break; + case types::action_definition_format5: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + } +} +e2_sm_kpm_action_definition_s::action_definition_formats_c_& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::operator=( + const e2_sm_kpm_action_definition_s::action_definition_formats_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::action_definition_format1: + c.set(other.c.get()); + break; + case types::action_definition_format2: + c.set(other.c.get()); + break; + case types::action_definition_format3: + c.set(other.c.get()); + break; + case types::action_definition_format4: + c.set(other.c.get()); + break; + case types::action_definition_format5: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + } + + return *this; +} +e2_sm_kpm_action_definition_format1_s& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::set_action_definition_format1() +{ + set(types::action_definition_format1); + return c.get(); +} +e2_sm_kpm_action_definition_format2_s& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::set_action_definition_format2() +{ + set(types::action_definition_format2); + return c.get(); +} +e2_sm_kpm_action_definition_format3_s& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::set_action_definition_format3() +{ + set(types::action_definition_format3); + return c.get(); +} +e2_sm_kpm_action_definition_format4_s& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::set_action_definition_format4() +{ + set(types::action_definition_format4); + return c.get(); +} +e2_sm_kpm_action_definition_format5_s& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::set_action_definition_format5() +{ + set(types::action_definition_format5); + return c.get(); +} +void e2_sm_kpm_action_definition_s::action_definition_formats_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::action_definition_format1: + j.write_fieldname("actionDefinition-Format1"); + c.get().to_json(j); + break; + case types::action_definition_format2: + j.write_fieldname("actionDefinition-Format2"); + c.get().to_json(j); + break; + case types::action_definition_format3: + j.write_fieldname("actionDefinition-Format3"); + c.get().to_json(j); + break; + case types::action_definition_format4: + j.write_fieldname("actionDefinition-Format4"); + c.get().to_json(j); + break; + case types::action_definition_format5: + j.write_fieldname("actionDefinition-Format5"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + } + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_action_definition_s::action_definition_formats_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::action_definition_format1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::action_definition_format2: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::action_definition_format3: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::action_definition_format4: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::action_definition_format5: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_s::action_definition_formats_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::action_definition_format1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::action_definition_format2: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::action_definition_format3: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::action_definition_format4: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::action_definition_format5: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_action_definition_s::action_definition_formats_c_::types_opts::to_string() const +{ + static const char* options[] = {"actionDefinition-Format1", + "actionDefinition-Format2", + "actionDefinition-Format3", + "actionDefinition-Format4", + "actionDefinition-Format5"}; + return convert_enum_idx(options, 5, value, "e2_sm_kpm_action_definition_s::action_definition_formats_c_::types"); +} +uint8_t e2_sm_kpm_action_definition_s::action_definition_formats_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3, 4, 5}; + return map_enum_number(options, 5, value, "e2_sm_kpm_action_definition_s::action_definition_formats_c_::types"); +} + +// E2SM-KPM-EventTriggerDefinition-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_event_trigger_definition_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, report_period, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(report_period, bref, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_event_trigger_definition_format1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("reportingPeriod", report_period); + j.end_obj(); +} + +// E2SM-KPM-EventTriggerDefinition ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_event_trigger_definition_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(event_definition_formats.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(event_definition_formats.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_event_trigger_definition_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("eventDefinition-formats"); + event_definition_formats.to_json(j); + j.end_obj(); +} + +void e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("eventDefinition-Format1"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::types_opts::to_string() const +{ + static const char* options[] = {"eventDefinition-Format1"}; + return convert_enum_idx( + options, 1, value, "e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::types"); +} +uint8_t e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::types"); +} + +// E2SM-KPM-IndicationHeader-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_hdr_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(file_formatversion_present, 1)); + HANDLE_CODE(bref.pack(sender_name_present, 1)); + HANDLE_CODE(bref.pack(sender_type_present, 1)); + HANDLE_CODE(bref.pack(vendor_name_present, 1)); + + HANDLE_CODE(collet_start_time.pack(bref)); + if (file_formatversion_present) { + HANDLE_CODE(file_formatversion.pack(bref)); + } + if (sender_name_present) { + HANDLE_CODE(sender_name.pack(bref)); + } + if (sender_type_present) { + HANDLE_CODE(sender_type.pack(bref)); + } + if (vendor_name_present) { + HANDLE_CODE(vendor_name.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_hdr_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(file_formatversion_present, 1)); + HANDLE_CODE(bref.unpack(sender_name_present, 1)); + HANDLE_CODE(bref.unpack(sender_type_present, 1)); + HANDLE_CODE(bref.unpack(vendor_name_present, 1)); + + HANDLE_CODE(collet_start_time.unpack(bref)); + if (file_formatversion_present) { + HANDLE_CODE(file_formatversion.unpack(bref)); + } + if (sender_name_present) { + HANDLE_CODE(sender_name.unpack(bref)); + } + if (sender_type_present) { + HANDLE_CODE(sender_type.unpack(bref)); + } + if (vendor_name_present) { + HANDLE_CODE(vendor_name.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_hdr_format1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("colletStartTime", collet_start_time.to_string()); + if (file_formatversion_present) { + j.write_str("fileFormatversion", file_formatversion.to_string()); + } + if (sender_name_present) { + j.write_str("senderName", sender_name.to_string()); + } + if (sender_type_present) { + j.write_str("senderType", sender_type.to_string()); + } + if (vendor_name_present) { + j.write_str("vendorName", vendor_name.to_string()); + } + j.end_obj(); +} + +// E2SM-KPM-IndicationHeader ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_hdr_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ind_hdr_formats.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_hdr_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ind_hdr_formats.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_hdr_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("indicationHeader-formats"); + ind_hdr_formats.to_json(j); + j.end_obj(); +} + +void e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("indicationHeader-Format1"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::types_opts::to_string() const +{ + static const char* options[] = {"indicationHeader-Format1"}; + return convert_enum_idx(options, 1, value, "e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::types"); +} +uint8_t e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::types"); +} + +// MeasurementRecordItem ::= CHOICE +void meas_record_item_c::destroy_() +{ + switch (type_) { + case types::real: + c.destroy(); + break; + default: + break; + } +} +void meas_record_item_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::integer: + break; + case types::real: + c.init(); + break; + case types::no_value: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + } +} +meas_record_item_c::meas_record_item_c(const meas_record_item_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::integer: + c.init(other.c.get()); + break; + case types::real: + c.init(other.c.get()); + break; + case types::no_value: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + } +} +meas_record_item_c& meas_record_item_c::operator=(const meas_record_item_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::integer: + c.set(other.c.get()); + break; + case types::real: + c.set(other.c.get()); + break; + case types::no_value: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + } + + return *this; +} +uint64_t& meas_record_item_c::set_integer() +{ + set(types::integer); + return c.get(); +} +real_s& meas_record_item_c::set_real() +{ + set(types::real); + return c.get(); +} +void meas_record_item_c::set_no_value() +{ + set(types::no_value); +} +void meas_record_item_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::integer: + j.write_int("integer", c.get()); + break; + case types::real: + j.write_fieldname("real"); + c.get().to_json(j); + break; + case types::no_value: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + } + j.end_obj(); +} +SRSASN_CODE meas_record_item_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::integer: + HANDLE_CODE(pack_integer(bref, c.get(), (uint64_t)0u, (uint64_t)4294967295u, false, true)); + break; + case types::real: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::no_value: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_record_item_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::integer: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + break; + case types::real: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::no_value: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* meas_record_item_c::types_opts::to_string() const +{ + static const char* options[] = {"integer", "real", "noValue"}; + return convert_enum_idx(options, 3, value, "meas_record_item_c::types"); +} + +// MatchingUEidItem-PerGP ::= SEQUENCE +SRSASN_CODE matching_ueid_item_per_gp_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ue_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ueid_item_per_gp_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ue_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void matching_ueid_item_per_gp_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ueID"); + ue_id.to_json(j); + j.end_obj(); +} + +// MeasurementDataItem ::= SEQUENCE +SRSASN_CODE meas_data_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(incomplete_flag_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, meas_record, 1, 2147483647, true)); + if (incomplete_flag_present) { + HANDLE_CODE(incomplete_flag.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_data_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(incomplete_flag_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(meas_record, bref, 1, 2147483647, true)); + if (incomplete_flag_present) { + HANDLE_CODE(incomplete_flag.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void meas_data_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("measRecord"); + for (const auto& e1 : meas_record) { + e1.to_json(j); + } + j.end_array(); + if (incomplete_flag_present) { + j.write_str("incompleteFlag", "true"); + } + j.end_obj(); +} + +const char* meas_data_item_s::incomplete_flag_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_data_item_s::incomplete_flag_e_"); +} + +// MatchingUEidItem ::= SEQUENCE +SRSASN_CODE matching_ueid_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ue_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ueid_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ue_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void matching_ueid_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ueID"); + ue_id.to_json(j); + j.end_obj(); +} + +// MatchingUEidPerGP-Item ::= SEQUENCE +SRSASN_CODE matching_ueid_per_gp_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(matched_per_gp.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ueid_per_gp_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(matched_per_gp.unpack(bref)); + + return SRSASN_SUCCESS; +} +void matching_ueid_per_gp_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("matchedPerGP"); + matched_per_gp.to_json(j); + j.end_obj(); +} + +void matching_ueid_per_gp_item_s::matched_per_gp_c_::destroy_() +{ + switch (type_) { + case types::one_or_more_uematched: + c.destroy(); + break; + default: + break; + } +} +void matching_ueid_per_gp_item_s::matched_per_gp_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::no_uematched: + break; + case types::one_or_more_uematched: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + } +} +matching_ueid_per_gp_item_s::matched_per_gp_c_::matched_per_gp_c_( + const matching_ueid_per_gp_item_s::matched_per_gp_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::no_uematched: + c.init(other.c.get()); + break; + case types::one_or_more_uematched: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + } +} +matching_ueid_per_gp_item_s::matched_per_gp_c_& +matching_ueid_per_gp_item_s::matched_per_gp_c_::operator=(const matching_ueid_per_gp_item_s::matched_per_gp_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::no_uematched: + c.set(other.c.get()); + break; + case types::one_or_more_uematched: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + } + + return *this; +} +matching_ueid_per_gp_item_s::matched_per_gp_c_::no_uematched_e_& +matching_ueid_per_gp_item_s::matched_per_gp_c_::set_no_uematched() +{ + set(types::no_uematched); + return c.get(); +} +matching_ueid_list_per_gp_l& matching_ueid_per_gp_item_s::matched_per_gp_c_::set_one_or_more_uematched() +{ + set(types::one_or_more_uematched); + return c.get(); +} +void matching_ueid_per_gp_item_s::matched_per_gp_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::no_uematched: + j.write_str("noUEmatched", "true"); + break; + case types::one_or_more_uematched: + j.start_array("oneOrMoreUEmatched"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + } + j.end_obj(); +} +SRSASN_CODE matching_ueid_per_gp_item_s::matched_per_gp_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::no_uematched: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::one_or_more_uematched: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 65535, true)); + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ueid_per_gp_item_s::matched_per_gp_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::no_uematched: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::one_or_more_uematched: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 65535, true)); + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* matching_ueid_per_gp_item_s::matched_per_gp_c_::no_uematched_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "matching_ueid_per_gp_item_s::matched_per_gp_c_::no_uematched_e_"); +} + +const char* matching_ueid_per_gp_item_s::matched_per_gp_c_::types_opts::to_string() const +{ + static const char* options[] = {"noUEmatched", "oneOrMoreUEmatched"}; + return convert_enum_idx(options, 2, value, "matching_ueid_per_gp_item_s::matched_per_gp_c_::types"); +} +uint8_t matching_ueid_per_gp_item_s::matched_per_gp_c_::types_opts::to_number() const +{ + if (value == one_or_more_uematched) { + return 1; + } + invalid_enum_number(value, "matching_ueid_per_gp_item_s::matched_per_gp_c_::types"); + return 0; +} + +// E2SM-KPM-IndicationMessage-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_msg_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(meas_info_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(granul_period_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, meas_data, 1, 65535, true)); + if (meas_info_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_info_list, 1, 65535, true)); + } + if (granul_period_present) { + HANDLE_CODE(pack_integer(bref, granul_period, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + } + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool meas_info_list_present; + HANDLE_CODE(bref.unpack(meas_info_list_present, 1)); + HANDLE_CODE(bref.unpack(granul_period_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(meas_data, bref, 1, 65535, true)); + if (meas_info_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_info_list, bref, 1, 65535, true)); + } + if (granul_period_present) { + HANDLE_CODE(unpack_integer(granul_period, bref, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + } + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_msg_format1_s::to_json(json_writer& j) const +{ + j.start_array(); + j.start_obj(); + j.start_obj("E2SM-KPM-IndicationMessage-Format1"); + j.start_array("measData"); + for (const auto& e1 : meas_data) { + e1.to_json(j); + } + j.end_array(); + if (meas_info_list.size() > 0) { + j.start_array("measInfoList"); + for (const auto& e1 : meas_info_list) { + e1.to_json(j); + } + j.end_array(); + } + if (granul_period_present) { + j.write_int("granulPeriod", granul_period); + } + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +// MeasurementCondUEidItem ::= SEQUENCE +SRSASN_CODE meas_cond_ueid_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(matching_ueid_list.size() > 0, 1)); + + HANDLE_CODE(meas_type.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, matching_cond, 1, 32768, true)); + if (matching_ueid_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, matching_ueid_list, 1, 65535, true)); + } + + if (ext) { + HANDLE_CODE(bref.pack(matching_ueid_per_gp.is_present(), 1)); + + if (matching_ueid_per_gp.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *matching_ueid_per_gp, 1, 65535, true)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_cond_ueid_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool matching_ueid_list_present; + HANDLE_CODE(bref.unpack(matching_ueid_list_present, 1)); + + HANDLE_CODE(meas_type.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(matching_cond, bref, 1, 32768, true)); + if (matching_ueid_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(matching_ueid_list, bref, 1, 65535, true)); + } + + if (ext) { + bool matching_ueid_per_gp_present; + HANDLE_CODE(bref.unpack(matching_ueid_per_gp_present, 1)); + matching_ueid_per_gp.set_present(matching_ueid_per_gp_present); + + if (matching_ueid_per_gp.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*matching_ueid_per_gp, bref, 1, 65535, true)); + } + } + return SRSASN_SUCCESS; +} +void meas_cond_ueid_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measType"); + meas_type.to_json(j); + j.start_array("matchingCond"); + for (const auto& e1 : matching_cond) { + e1.to_json(j); + } + j.end_array(); + if (matching_ueid_list.size() > 0) { + j.start_array("matchingUEidList"); + for (const auto& e1 : matching_ueid_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ext) { + if (matching_ueid_per_gp.is_present()) { + j.start_array("matchingUEidPerGP"); + for (const auto& e1 : *matching_ueid_per_gp) { + e1.to_json(j); + } + j.end_array(); + } + } + j.end_obj(); +} + +// UEMeasurementReportItem ::= SEQUENCE +SRSASN_CODE ue_meas_report_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ue_id.pack(bref)); + HANDLE_CODE(meas_report.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_meas_report_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ue_id.unpack(bref)); + HANDLE_CODE(meas_report.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ue_meas_report_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ueID"); + ue_id.to_json(j); + j.write_fieldname("measReport"); + meas_report.to_json(j); + j.end_obj(); +} + +// E2SM-KPM-IndicationMessage-Format2 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_msg_format2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(granul_period_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, meas_data, 1, 65535, true)); + HANDLE_CODE(pack_dyn_seq_of(bref, meas_cond_ueid_list, 1, 65535, true)); + if (granul_period_present) { + HANDLE_CODE(pack_integer(bref, granul_period, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + } + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_format2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(granul_period_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(meas_data, bref, 1, 65535, true)); + HANDLE_CODE(unpack_dyn_seq_of(meas_cond_ueid_list, bref, 1, 65535, true)); + if (granul_period_present) { + HANDLE_CODE(unpack_integer(granul_period, bref, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + } + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_msg_format2_s::to_json(json_writer& j) const +{ + j.start_array(); + j.start_obj(); + j.start_obj("E2SM-KPM-IndicationMessage-Format2"); + j.start_array("measData"); + for (const auto& e1 : meas_data) { + e1.to_json(j); + } + j.end_array(); + j.start_array("measCondUEidList"); + for (const auto& e1 : meas_cond_ueid_list) { + e1.to_json(j); + } + j.end_array(); + if (granul_period_present) { + j.write_int("granulPeriod", granul_period); + } + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +// E2SM-KPM-IndicationMessage-Format3 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_msg_format3_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, ue_meas_report_list, 1, 65535, true)); + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_format3_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(ue_meas_report_list, bref, 1, 65535, true)); + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_msg_format3_s::to_json(json_writer& j) const +{ + j.start_array(); + j.start_obj(); + j.start_obj("E2SM-KPM-IndicationMessage-Format3"); + j.start_array("ueMeasReportList"); + for (const auto& e1 : ue_meas_report_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +// E2SM-KPM-IndicationMessage ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_msg_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ind_msg_formats.pack(bref)); + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ind_msg_formats.unpack(bref)); + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_msg_s::to_json(json_writer& j) const +{ + j.start_array(); + j.start_obj(); + j.start_obj("E2SM-KPM-IndicationMessage"); + j.write_fieldname("indicationMessage-formats"); + ind_msg_formats.to_json(j); + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +void e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::destroy_() +{ + switch (type_) { + case types::ind_msg_format1: + c.destroy(); + break; + case types::ind_msg_format2: + c.destroy(); + break; + case types::ind_msg_format3: + c.destroy(); + break; + default: + break; + } +} +void e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ind_msg_format1: + c.init(); + break; + case types::ind_msg_format2: + c.init(); + break; + case types::ind_msg_format3: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + } +} +e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::ind_msg_formats_c_(const e2_sm_kpm_ind_msg_s::ind_msg_formats_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::ind_msg_format1: + c.init(other.c.get()); + break; + case types::ind_msg_format2: + c.init(other.c.get()); + break; + case types::ind_msg_format3: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + } +} +e2_sm_kpm_ind_msg_s::ind_msg_formats_c_& +e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::operator=(const e2_sm_kpm_ind_msg_s::ind_msg_formats_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ind_msg_format1: + c.set(other.c.get()); + break; + case types::ind_msg_format2: + c.set(other.c.get()); + break; + case types::ind_msg_format3: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + } + + return *this; +} +e2_sm_kpm_ind_msg_format1_s& e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::set_ind_msg_format1() +{ + set(types::ind_msg_format1); + return c.get(); +} +e2_sm_kpm_ind_msg_format2_s& e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::set_ind_msg_format2() +{ + set(types::ind_msg_format2); + return c.get(); +} +e2_sm_kpm_ind_msg_format3_s& e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::set_ind_msg_format3() +{ + set(types::ind_msg_format3); + return c.get(); +} +void e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ind_msg_format1: + j.write_fieldname("indicationMessage-Format1"); + c.get().to_json(j); + break; + case types::ind_msg_format2: + j.write_fieldname("indicationMessage-Format2"); + c.get().to_json(j); + break; + case types::ind_msg_format3: + j.write_fieldname("indicationMessage-Format3"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + } + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ind_msg_format1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ind_msg_format2: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ind_msg_format3: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ind_msg_format1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ind_msg_format2: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ind_msg_format3: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::to_string() const +{ + static const char* options[] = { + "indicationMessage-Format1", "indicationMessage-Format2", "indicationMessage-Format3"}; + return convert_enum_idx(options, 3, value, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types"); +} +uint8_t e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3}; + return map_enum_number(options, 3, value, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types"); +} + +// MeasurementInfo-Action-Item ::= SEQUENCE +SRSASN_CODE meas_info_action_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(meas_id_present, 1)); + + HANDLE_CODE(meas_name.pack(bref)); + if (meas_id_present) { + HANDLE_CODE(pack_integer(bref, meas_id, (uint32_t)1u, (uint32_t)65536u, true, true)); + } + + if (ext) { + HANDLE_CODE(bref.pack(bin_range_def.is_present(), 1)); + + if (bin_range_def.is_present()) { + HANDLE_CODE(bin_range_def->pack(bref)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_info_action_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(meas_id_present, 1)); + + HANDLE_CODE(meas_name.unpack(bref)); + if (meas_id_present) { + HANDLE_CODE(unpack_integer(meas_id, bref, (uint32_t)1u, (uint32_t)65536u, true, true)); + } + + if (ext) { + bool bin_range_def_present; + HANDLE_CODE(bref.unpack(bin_range_def_present, 1)); + bin_range_def.set_present(bin_range_def_present); + + if (bin_range_def.is_present()) { + HANDLE_CODE(bin_range_def->unpack(bref)); + } + } + return SRSASN_SUCCESS; +} +void meas_info_action_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("measName", meas_name.to_string()); + if (meas_id_present) { + j.write_int("measID", meas_id); + } + if (ext) { + if (bin_range_def.is_present()) { + j.write_fieldname("binRangeDef"); + bin_range_def->to_json(j); + } + } + j.end_obj(); +} + +// RANfunction-Name ::= SEQUENCE +SRSASN_CODE ra_nfunction_name_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_function_instance_present, 1)); + + HANDLE_CODE(ran_function_short_name.pack(bref)); + HANDLE_CODE(ran_function_e2_sm_oid.pack(bref)); + HANDLE_CODE(ran_function_description.pack(bref)); + if (ran_function_instance_present) { + HANDLE_CODE(pack_unconstrained_integer(bref, ran_function_instance, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_name_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_function_instance_present, 1)); + + HANDLE_CODE(ran_function_short_name.unpack(bref)); + HANDLE_CODE(ran_function_e2_sm_oid.unpack(bref)); + HANDLE_CODE(ran_function_description.unpack(bref)); + if (ran_function_instance_present) { + HANDLE_CODE(unpack_unconstrained_integer(ran_function_instance, bref, false, true)); + } + + return SRSASN_SUCCESS; +} +void ra_nfunction_name_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ranFunction-ShortName", ran_function_short_name.to_string()); + j.write_str("ranFunction-E2SM-OID", ran_function_e2_sm_oid.to_string()); + j.write_str("ranFunction-Description", ran_function_description.to_string()); + if (ran_function_instance_present) { + j.write_int("ranFunction-Instance", ran_function_instance); + } + j.end_obj(); +} + +// RIC-EventTriggerStyle-Item ::= SEQUENCE +SRSASN_CODE ric_event_trigger_style_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_event_trigger_style_type, false, true)); + HANDLE_CODE(ric_event_trigger_style_name.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_event_trigger_format_type, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ric_event_trigger_style_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_event_trigger_style_type, bref, false, true)); + HANDLE_CODE(ric_event_trigger_style_name.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(ric_event_trigger_format_type, bref, false, true)); + + return SRSASN_SUCCESS; +} +void ric_event_trigger_style_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-EventTriggerStyle-Type", ric_event_trigger_style_type); + j.write_str("ric-EventTriggerStyle-Name", ric_event_trigger_style_name.to_string()); + j.write_int("ric-EventTriggerFormat-Type", ric_event_trigger_format_type); + j.end_obj(); +} + +// RIC-ReportStyle-Item ::= SEQUENCE +SRSASN_CODE ric_report_style_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_report_style_type, false, true)); + HANDLE_CODE(ric_report_style_name.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_action_format_type, false, true)); + HANDLE_CODE(pack_dyn_seq_of(bref, meas_info_action_list, 1, 65535, true)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_ind_hdr_format_type, false, true)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_ind_msg_format_type, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ric_report_style_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_report_style_type, bref, false, true)); + HANDLE_CODE(ric_report_style_name.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(ric_action_format_type, bref, false, true)); + HANDLE_CODE(unpack_dyn_seq_of(meas_info_action_list, bref, 1, 65535, true)); + HANDLE_CODE(unpack_unconstrained_integer(ric_ind_hdr_format_type, bref, false, true)); + HANDLE_CODE(unpack_unconstrained_integer(ric_ind_msg_format_type, bref, false, true)); + + return SRSASN_SUCCESS; +} +void ric_report_style_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-ReportStyle-Type", ric_report_style_type); + j.write_str("ric-ReportStyle-Name", ric_report_style_name.to_string()); + j.write_int("ric-ActionFormat-Type", ric_action_format_type); + j.start_array("measInfo-Action-List"); + for (const auto& e1 : meas_info_action_list) { + e1.to_json(j); + } + j.end_array(); + j.write_int("ric-IndicationHeaderFormat-Type", ric_ind_hdr_format_type); + j.write_int("ric-IndicationMessageFormat-Type", ric_ind_msg_format_type); + j.end_obj(); +} + +// E2SM-KPM-RANfunction-Description ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ra_nfunction_description_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ric_event_trigger_style_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ric_report_style_list.size() > 0, 1)); + + HANDLE_CODE(ran_function_name.pack(bref)); + if (ric_event_trigger_style_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, ric_event_trigger_style_list, 1, 63, true)); + } + if (ric_report_style_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, ric_report_style_list, 1, 63, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ra_nfunction_description_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool ric_event_trigger_style_list_present; + HANDLE_CODE(bref.unpack(ric_event_trigger_style_list_present, 1)); + bool ric_report_style_list_present; + HANDLE_CODE(bref.unpack(ric_report_style_list_present, 1)); + + HANDLE_CODE(ran_function_name.unpack(bref)); + if (ric_event_trigger_style_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(ric_event_trigger_style_list, bref, 1, 63, true)); + } + if (ric_report_style_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(ric_report_style_list, bref, 1, 63, true)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ra_nfunction_description_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ranFunction-Name"); + ran_function_name.to_json(j); + if (ric_event_trigger_style_list.size() > 0) { + j.start_array("ric-EventTriggerStyle-List"); + for (const auto& e1 : ric_event_trigger_style_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ric_report_style_list.size() > 0) { + j.start_array("ric-ReportStyle-List"); + for (const auto& e1 : ric_report_style_list) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// GlobalRANNodeID ::= CHOICE +void global_ran_node_id_c::destroy_() +{ + switch (type_) { + case types::global_gnb_id: + c.destroy(); + break; + case types::global_ng_enb_id: + c.destroy(); + break; + default: + break; + } +} +void global_ran_node_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_gnb_id: + c.init(); + break; + case types::global_ng_enb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c::global_ran_node_id_c(const global_ran_node_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_gnb_id: + c.init(other.c.get()); + break; + case types::global_ng_enb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c& global_ran_node_id_c::operator=(const global_ran_node_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_gnb_id: + c.set(other.c.get()); + break; + case types::global_ng_enb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + + return *this; +} +global_gnb_id_s& global_ran_node_id_c::set_global_gnb_id() +{ + set(types::global_gnb_id); + return c.get(); +} +global_ng_enb_id_s& global_ran_node_id_c::set_global_ng_enb_id() +{ + set(types::global_ng_enb_id); + return c.get(); +} +void global_ran_node_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_gnb_id: + j.write_fieldname("globalGNB-ID"); + c.get().to_json(j); + break; + case types::global_ng_enb_id: + j.write_fieldname("globalNgENB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_ran_node_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ran_node_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_ran_node_id_c::types_opts::to_string() const +{ + static const char* options[] = {"globalGNB-ID", "globalNgENB-ID"}; + return convert_enum_idx(options, 2, value, "global_ran_node_id_c::types"); +} + +// EN-GNB-ID ::= CHOICE +void en_gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("en-gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE en_gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE en_gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "en_gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* en_gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"en-gNB-ID"}; + return convert_enum_idx(options, 1, value, "en_gnb_id_c::types"); +} + +// GlobalenGNB-ID ::= SEQUENCE +SRSASN_CODE globalen_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(en_g_nb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalen_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(en_g_nb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalen_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("en-gNB-ID"); + en_g_nb_id.to_json(j); + j.end_obj(); +} + +// GroupID ::= CHOICE +void group_id_c::destroy_() {} +void group_id_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +group_id_c::group_id_c(const group_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } +} +group_id_c& group_id_c::operator=(const group_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + + return *this; +} +uint16_t& group_id_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& group_id_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void group_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + j.end_obj(); +} +SRSASN_CODE group_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE group_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* group_id_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "group_id_c::types"); +} +uint8_t group_id_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "group_id_c::types"); +} + +// InterfaceID-E1 ::= SEQUENCE +SRSASN_CODE interface_id_e1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_e1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_e1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-CU-UP-ID", gnb_cu_up_id); + j.end_obj(); +} + +// InterfaceID-F1 ::= SEQUENCE +SRSASN_CODE interface_id_f1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_f1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_f1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-DU-ID", gnb_du_id); + j.end_obj(); +} + +// InterfaceID-NG ::= SEQUENCE +SRSASN_CODE interface_id_ng_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(guami.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_ng_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(guami.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_ng_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("guami"); + guami.to_json(j); + j.end_obj(); +} + +// InterfaceID-S1 ::= SEQUENCE +SRSASN_CODE interface_id_s1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(gummei.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_s1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(gummei.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_s1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + j.end_obj(); +} + +// InterfaceID-W1 ::= SEQUENCE +SRSASN_CODE interface_id_w1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_enb_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, ng_enb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_w1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + HANDLE_CODE(unpack_integer(ng_enb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_w1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-ng-eNB-ID"); + global_ng_enb_id.to_json(j); + j.write_int("ng-eNB-DU-ID", ng_enb_du_id); + j.end_obj(); +} + +// InterfaceID-X2 ::= SEQUENCE +SRSASN_CODE interface_id_x2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(node_type.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(node_type.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_x2_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("nodeType"); + node_type.to_json(j); + j.end_obj(); +} + +void interface_id_x2_s::node_type_c_::destroy_() +{ + switch (type_) { + case types::global_enb_id: + c.destroy(); + break; + case types::global_en_g_nb_id: + c.destroy(); + break; + default: + break; + } +} +void interface_id_x2_s::node_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_enb_id: + c.init(); + break; + case types::global_en_g_nb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_::node_type_c_(const interface_id_x2_s::node_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_enb_id: + c.init(other.c.get()); + break; + case types::global_en_g_nb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_& +interface_id_x2_s::node_type_c_::operator=(const interface_id_x2_s::node_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_enb_id: + c.set(other.c.get()); + break; + case types::global_en_g_nb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + + return *this; +} +global_enb_id_s& interface_id_x2_s::node_type_c_::set_global_enb_id() +{ + set(types::global_enb_id); + return c.get(); +} +globalen_gnb_id_s& interface_id_x2_s::node_type_c_::set_global_en_g_nb_id() +{ + set(types::global_en_g_nb_id); + return c.get(); +} +void interface_id_x2_s::node_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_enb_id: + j.write_fieldname("global-eNB-ID"); + c.get().to_json(j); + break; + case types::global_en_g_nb_id: + j.write_fieldname("global-en-gNB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_x2_s::node_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::node_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_x2_s::node_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"global-eNB-ID", "global-en-gNB-ID"}; + return convert_enum_idx(options, 2, value, "interface_id_x2_s::node_type_c_::types"); +} + +// InterfaceID-Xn ::= SEQUENCE +SRSASN_CODE interface_id_xn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_xn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_xn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.end_obj(); +} + +// InterfaceIdentifier ::= CHOICE +void interface_id_c::destroy_() +{ + switch (type_) { + case types::ng: + c.destroy(); + break; + case types::xn: + c.destroy(); + break; + case types::f1: + c.destroy(); + break; + case types::e1: + c.destroy(); + break; + case types::s1: + c.destroy(); + break; + case types::x2: + c.destroy(); + break; + case types::w1: + c.destroy(); + break; + default: + break; + } +} +void interface_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ng: + c.init(); + break; + case types::xn: + c.init(); + break; + case types::f1: + c.init(); + break; + case types::e1: + c.init(); + break; + case types::s1: + c.init(); + break; + case types::x2: + c.init(); + break; + case types::w1: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c::interface_id_c(const interface_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ng: + c.init(other.c.get()); + break; + case types::xn: + c.init(other.c.get()); + break; + case types::f1: + c.init(other.c.get()); + break; + case types::e1: + c.init(other.c.get()); + break; + case types::s1: + c.init(other.c.get()); + break; + case types::x2: + c.init(other.c.get()); + break; + case types::w1: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c& interface_id_c::operator=(const interface_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ng: + c.set(other.c.get()); + break; + case types::xn: + c.set(other.c.get()); + break; + case types::f1: + c.set(other.c.get()); + break; + case types::e1: + c.set(other.c.get()); + break; + case types::s1: + c.set(other.c.get()); + break; + case types::x2: + c.set(other.c.get()); + break; + case types::w1: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + + return *this; +} +interface_id_ng_s& interface_id_c::set_ng() +{ + set(types::ng); + return c.get(); +} +interface_id_xn_s& interface_id_c::set_xn() +{ + set(types::xn); + return c.get(); +} +interface_id_f1_s& interface_id_c::set_f1() +{ + set(types::f1); + return c.get(); +} +interface_id_e1_s& interface_id_c::set_e1() +{ + set(types::e1); + return c.get(); +} +interface_id_s1_s& interface_id_c::set_s1() +{ + set(types::s1); + return c.get(); +} +interface_id_x2_s& interface_id_c::set_x2() +{ + set(types::x2); + return c.get(); +} +interface_id_w1_s& interface_id_c::set_w1() +{ + set(types::w1); + return c.get(); +} +void interface_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ng: + j.write_fieldname("nG"); + c.get().to_json(j); + break; + case types::xn: + j.write_fieldname("xN"); + c.get().to_json(j); + break; + case types::f1: + j.write_fieldname("f1"); + c.get().to_json(j); + break; + case types::e1: + j.write_fieldname("e1"); + c.get().to_json(j); + break; + case types::s1: + j.write_fieldname("s1"); + c.get().to_json(j); + break; + case types::x2: + j.write_fieldname("x2"); + c.get().to_json(j); + break; + case types::w1: + j.write_fieldname("w1"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_c::types_opts::to_string() const +{ + static const char* options[] = {"nG", "xN", "f1", "e1", "s1", "x2", "w1"}; + return convert_enum_idx(options, 7, value, "interface_id_c::types"); +} + +// FreqBandNrItem ::= SEQUENCE +SRSASN_CODE freq_band_nr_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, freq_band_ind_nr, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE freq_band_nr_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(freq_band_ind_nr, bref, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +void freq_band_nr_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("freqBandIndicatorNr", freq_band_ind_nr); + j.end_obj(); +} + +// NR-ARFCN ::= SEQUENCE +SRSASN_CODE nr_arfcn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, nrarfcn, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list_nr, 1, 32, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_arfcn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(nrarfcn, bref, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(unpack_dyn_seq_of(freq_band_list_nr, bref, 1, 32, true)); + + return SRSASN_SUCCESS; +} +void nr_arfcn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("nRARFCN", nrarfcn); + j.start_array("freqBandListNr"); + for (const auto& e1 : freq_band_list_nr) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// QoSID ::= CHOICE +void qo_sid_c::destroy_() {} +void qo_sid_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +qo_sid_c::qo_sid_c(const qo_sid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } +} +qo_sid_c& qo_sid_c::operator=(const qo_sid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + + return *this; +} +uint16_t& qo_sid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& qo_sid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void qo_sid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + j.end_obj(); +} +SRSASN_CODE qo_sid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE qo_sid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* qo_sid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "qo_sid_c::types"); +} +uint8_t qo_sid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "qo_sid_c::types"); +} + +// RRCclass-LTE ::= ENUMERATED +const char* rr_cclass_lte_opts::to_string() const +{ + static const char* options[] = {"bCCH-BCH", + "bCCH-BCH-MBMS", + "bCCH-DL-SCH", + "bCCH-DL-SCH-BR", + "bCCH-DL-SCH-MBMS", + "mCCH", + "pCCH", + "dL-CCCH", + "dL-DCCH", + "uL-CCCH", + "uL-DCCH", + "sC-MCCH"}; + return convert_enum_idx(options, 12, value, "rr_cclass_lte_e"); +} + +// RRCclass-NR ::= ENUMERATED +const char* rr_cclass_nr_opts::to_string() const +{ + static const char* options[] = { + "bCCH-BCH", "bCCH-DL-SCH", "dL-CCCH", "dL-DCCH", "pCCH", "uL-CCCH", "uL-CCCH1", "uL-DCCH"}; + return convert_enum_idx(options, 8, value, "rr_cclass_nr_e"); +} +uint8_t rr_cclass_nr_opts::to_number() const +{ + if (value == ul_ccch1) { + return 1; + } + invalid_enum_number(value, "rr_cclass_nr_e"); + return 0; +} + +// RRC-MessageID ::= SEQUENCE +SRSASN_CODE rrc_msg_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(rrc_type.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, msg_id, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(rrc_type.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(msg_id, bref, false, true)); + + return SRSASN_SUCCESS; +} +void rrc_msg_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("rrcType"); + rrc_type.to_json(j); + j.write_int("messageID", msg_id); + j.end_obj(); +} + +void rrc_msg_id_s::rrc_type_c_::destroy_() {} +void rrc_msg_id_s::rrc_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +rrc_msg_id_s::rrc_type_c_::rrc_type_c_(const rrc_msg_id_s::rrc_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::lte: + c.init(other.c.get()); + break; + case types::nr: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } +} +rrc_msg_id_s::rrc_type_c_& rrc_msg_id_s::rrc_type_c_::operator=(const rrc_msg_id_s::rrc_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::lte: + c.set(other.c.get()); + break; + case types::nr: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + + return *this; +} +rr_cclass_lte_e& rrc_msg_id_s::rrc_type_c_::set_lte() +{ + set(types::lte); + return c.get(); +} +rr_cclass_nr_e& rrc_msg_id_s::rrc_type_c_::set_nr() +{ + set(types::nr); + return c.get(); +} +void rrc_msg_id_s::rrc_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::lte: + j.write_str("lTE", c.get().to_string()); + break; + case types::nr: + j.write_str("nR", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_msg_id_s::rrc_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"lTE", "nR"}; + return convert_enum_idx(options, 2, value, "rrc_msg_id_s::rrc_type_c_::types"); +} + +// ServingCell-ARFCN ::= CHOICE +void serving_cell_arfcn_c::destroy_() +{ + switch (type_) { + case types::nr: + c.destroy(); + break; + default: + break; + } +} +void serving_cell_arfcn_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr: + c.init(); + break; + case types::eutra: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c::serving_cell_arfcn_c(const serving_cell_arfcn_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c& serving_cell_arfcn_c::operator=(const serving_cell_arfcn_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + + return *this; +} +nr_arfcn_s& serving_cell_arfcn_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint32_t& serving_cell_arfcn_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_arfcn_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_fieldname("nR"); + c.get().to_json(j); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_arfcn_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_arfcn_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_arfcn_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_arfcn_c::types"); +} + +// ServingCell-PCI ::= CHOICE +void serving_cell_pci_c::destroy_() {} +void serving_cell_pci_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +serving_cell_pci_c::serving_cell_pci_c(const serving_cell_pci_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } +} +serving_cell_pci_c& serving_cell_pci_c::operator=(const serving_cell_pci_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + + return *this; +} +uint16_t& serving_cell_pci_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint16_t& serving_cell_pci_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_pci_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_int("nR", c.get()); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_pci_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_pci_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_pci_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_pci_c::types"); +} From 4bf162cbf1fcb8aacfc114ae21b4682ab478f04c Mon Sep 17 00:00:00 2001 From: yagoda Date: Thu, 16 Mar 2023 10:48:04 +0100 Subject: [PATCH 024/167] e2ap: adding e2 metrics interface files --- .../srsran/interfaces/e2_metrics_interface.h | 31 ++++++++++++ srsenb/hdr/metrics_e2.h | 48 +++++++++++++++++++ srsenb/src/metrics_e2.cc | 38 +++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 lib/include/srsran/interfaces/e2_metrics_interface.h create mode 100644 srsenb/hdr/metrics_e2.h create mode 100644 srsenb/src/metrics_e2.cc diff --git a/lib/include/srsran/interfaces/e2_metrics_interface.h b/lib/include/srsran/interfaces/e2_metrics_interface.h new file mode 100644 index 000000000..0328c56d8 --- /dev/null +++ b/lib/include/srsran/interfaces/e2_metrics_interface.h @@ -0,0 +1,31 @@ +/** + * + * \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 "srsran/common/common.h" +#include "srsran/common/interfaces_common.h" +#include "srsran/interfaces/enb_metrics_interface.h" +#include "srsran/srsran.h" + +#ifndef SRSRAN_E2_INTERFACES_H +#define SRSRAN_E2_INTERFACES_H + +namespace srsenb { + +class e2_interface_metrics +{ +public: + virtual bool pull_metrics(enb_metrics_t* m) = 0; +}; + +} // namespace srsenb + +#endif // SRSRAN_ENB_INTERFACES_H diff --git a/srsenb/hdr/metrics_e2.h b/srsenb/hdr/metrics_e2.h new file mode 100644 index 000000000..63aea1842 --- /dev/null +++ b/srsenb/hdr/metrics_e2.h @@ -0,0 +1,48 @@ +/** + * + * \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. + * + */ + +/****************************************************************************** + * File: metrics_stdout.h + * Description: Metrics class printing to stdout. + *****************************************************************************/ + +#ifndef SRSENB_METRICS_E2_H +#define SRSENB_METRICS_E2_H + +#include "srsran/interfaces/e2_metrics_interface.h" +#include "srsran/interfaces/enb_metrics_interface.h" +#include +#include +#include +#include + +#define METRICS_BUFFER_SIZE 20 +namespace srsenb { + +class metrics_e2 : public srsran::metrics_listener, public e2_interface_metrics +{ +public: + metrics_e2(enb_metrics_interface* enb_) : do_print(false) {} + void set_metrics(const enb_metrics_t& m, const uint32_t period_usec); + bool pull_metrics(enb_metrics_t* m) override; + void stop(){}; + +private: + std::atomic do_print = {false}; + uint8_t n_reports = 0; + std::queue metrics_queue; + enb_metrics_interface* enb = nullptr; +}; + +} // namespace srsenb + +#endif // SRSENB_METRICS_STDOUT_H diff --git a/srsenb/src/metrics_e2.cc b/srsenb/src/metrics_e2.cc new file mode 100644 index 000000000..ffc0f897f --- /dev/null +++ b/srsenb/src/metrics_e2.cc @@ -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. + * + */ + +#include "srsenb/hdr/metrics_e2.h" +#include "srsran/phy/utils/vector.h" + +using namespace srsenb; + +void metrics_e2::set_metrics(const enb_metrics_t& m, const uint32_t period_usec) +{ + if (metrics_queue.size() > METRICS_BUFFER_SIZE) { + metrics_queue.pop(); + metrics_queue.push(m); + } else { + metrics_queue.push(m); + } +} + +bool metrics_e2::pull_metrics(enb_metrics_t* m) +{ + if (enb != nullptr) { + if (!metrics_queue.empty()) { + *m = metrics_queue.front(); + metrics_queue.pop(); + return true; + } + } + return false; +} From 2de3c199cbf9b1206f645916f6509c11a15ad82a Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 17 Mar 2023 14:01:06 +0100 Subject: [PATCH 025/167] change e2ap_port port --- srsgnb/hdr/stack/ric/ric_client.h | 2 +- srsgnb/src/stack/ric/ric_client.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index e78cc34c6..adc1f6520 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -21,7 +21,7 @@ #include "srsran/interfaces/e2_metrics_interface.h" #include "srsran/srsran.h" static const int e2ap_ppid = 70; -static const int e2ap_port = 36422; +static const int e2ap_port = 36421; enum e2_msg_type_t { E2_SETUP_REQUEST, E2_SUB_RESPONSE, E2_INDICATION, E2_RESET, E2_RESET_RESPONSE }; diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index e7f5eea89..490a5e35c 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -36,13 +36,13 @@ bool ric_client::init() } // Bind socket - if (not ric_socket.bind_addr("172.17.0.3", 36422)) { + if (not ric_socket.bind_addr("127.0.0.1", 36425)) { ric_socket.close(); return false; } // Connect to the AMF address - if (not ric_socket.connect_to("10.104.149.217", e2ap_port, &ric_addr)) { + if (not ric_socket.connect_to("127.0.0.1", e2ap_port, &ric_addr)) { return false; } // Assign a handler to rx RIC packets From 315727e612d394e62d316e2ea4223ef0b323cd2d Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 17 Mar 2023 14:16:46 +0100 Subject: [PATCH 026/167] enable connection with flexric --- srsgnb/hdr/stack/ric/e2ap.h | 8 ++++---- srsgnb/src/stack/ric/e2ap.cc | 33 ++++++++++++++++++++++-------- srsgnb/src/stack/ric/e2sm_kpm.cc | 7 ++++--- srsgnb/src/stack/ric/ric_client.cc | 4 ++-- 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index d17b4e231..4e0612650 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -58,10 +58,10 @@ private: srslog::basic_logger& logger; e2sm_kpm e2sm_; bool setup_response_received = false; - bool pending_subscription_request = false; - int setup_procedure_transaction_id = 0; - uint64_t plmn_id = 3617847; - uint64_t gnb_id = 381210353; + bool pending_subscription_request = false; + int setup_procedure_transaction_id = 0; + uint64_t plmn_id = 0x05f510; + uint64_t gnb_id = 1; global_ric_id_t global_ric_id = {}; std::map ran_functions; srsenb::e2_interface_metrics* gnb_metrics = nullptr; diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 88b3ebf9a..9f2f34cb7 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -21,7 +21,7 @@ e2_ap_pdu_c e2ap::generate_setup_request() 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); + gnb_.global_g_nb_id.gnb_id.gnb_id().from_number(gnb_id, 28); // TODO: to keep flexric happy, provide them feedback setup->ra_nfunctions_added.crit = asn1::crit_opts::reject; auto& list = setup->ra_nfunctions_added.value; @@ -29,15 +29,15 @@ e2_ap_pdu_c e2ap::generate_setup_request() 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 = 0; - item.value().ra_nfunction_item().ran_function_revision = 1; + item.value().ra_nfunction_item().ran_function_id = 147; + item.value().ra_nfunction_item().ran_function_revision = 0; // 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 = "OID123"; + 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; @@ -45,9 +45,13 @@ e2_ap_pdu_c e2ap::generate_setup_request() 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); 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()); - item.value().ra_nfunction_item().ran_function_oid.resize(1); + 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; @@ -67,20 +71,33 @@ e2_ap_pdu_c e2ap::generate_subscription_response() e2_ap_pdu_c pdu; successful_outcome_s& success = pdu.set_successful_outcome(); success.load_info_obj(ASN1_E2AP_ID_RICSUBSCRIPTION); + success.crit = asn1::crit_opts::reject; ricsubscription_resp_s& sub_resp = success.value.ricsubscription_resp(); sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; sub_resp->ri_crequest_id.id = ASN1_E2AP_ID_RI_CREQUEST_ID; - sub_resp->ri_crequest_id.value.ric_requestor_id = 123; - sub_resp->ri_crequest_id.value.ric_instance_id = 21; + sub_resp->ri_crequest_id.value.ric_requestor_id = 1021; + sub_resp->ri_crequest_id.value.ric_instance_id = 0; sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; sub_resp->ra_nfunction_id.id = ASN1_E2AP_ID_RA_NFUNCTION_ID; + sub_resp->ra_nfunction_id->value = 147; + sub_resp->ri_cactions_admitted.crit = asn1::crit_opts::reject; auto& action_admit_list = sub_resp->ri_cactions_admitted.value; action_admit_list.resize(1); action_admit_list[0].load_info_obj(ASN1_E2AP_ID_RI_CACTION_ADMITTED_ITEM); - action_admit_list[0].value().ri_caction_admitted_item().ric_action_id = 1; + ri_caction_admitted_item_s& a_item = action_admit_list[0]->ri_caction_admitted_item(); + a_item.ric_action_id = 0; + + sub_resp->ri_cactions_not_admitted.crit = asn1::crit_opts::reject; + auto& action_not_admit_list = sub_resp->ri_cactions_not_admitted.value; + action_not_admit_list.resize(1); + action_not_admit_list[0].load_info_obj(ASN1_E2AP_ID_RI_CACTION_NOT_ADMITTED_ITEM); + ri_caction_not_admitted_item_s& not_a_item = action_not_admit_list[0]->ri_caction_not_admitted_item(); + not_a_item.ric_action_id = 10; + not_a_item.cause.misc(); + return pdu; } diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index e2f6396e4..46b898174 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -8,12 +8,13 @@ bool e2sm_kpm::generate_ran_function_description(int f { using namespace asn1::e2sm_kpm; e2_sm_kpm_ra_nfunction_description_s e2sm_kpm_ra_nfunction_description; - 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; + 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]; @@ -56,7 +57,7 @@ bool e2sm_kpm::generate_ran_function_description(int f }; ric_report_style_list_item.ric_report_style_name.from_string("Periodic report"); } - + */ 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) { diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 490a5e35c..af2478e33 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -54,7 +54,7 @@ bool ric_client::init() rx_sockets.add_socket_handler(ric_socket.fd(), srsran::make_sctp_sdu_handler(logger, ric_rece_task_queue, rx_callback)); - printf("SCTP socket connected with RIC. fd=%d", ric_socket.fd()); + printf("SCTP socket connected with RIC. fd=%d \n", ric_socket.fd()); running = true; start(0); return SRSRAN_SUCCESS; @@ -135,7 +135,7 @@ bool ric_client::send_e2_msg(e2_msg_type_t msg_type) } asn1::bit_ref bref(buf->msg, buf->get_tailroom()); if (send_pdu.pack(bref) != asn1::SRSASN_SUCCESS) { - logger.error("Failed to pack TX E2 PDU"); + logger.error("Failed to pack TX E2 PDU: %s", message_name); return false; } buf->N_bytes = bref.distance_bytes(); From 03d3bd4fb0ae39bf6809208f681e67f99a31773c Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 17 Mar 2023 14:19:02 +0100 Subject: [PATCH 027/167] switch to e2sm_kpm_v2 --- lib/src/asn1/CMakeLists.txt | 2 +- lib/src/asn1/e2sm_kpm_v2.cpp | 2 +- srsgnb/hdr/stack/ric/e2ap.h | 2 +- srsgnb/hdr/stack/ric/e2sm_kpm.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/asn1/CMakeLists.txt b/lib/src/asn1/CMakeLists.txt index 566ed56c8..f358a97af 100644 --- a/lib/src/asn1/CMakeLists.txt +++ b/lib/src/asn1/CMakeLists.txt @@ -67,7 +67,7 @@ target_compile_options(nas_5g_msg PRIVATE "-Os") target_link_libraries(nas_5g_msg asn1_utils srsran_common) install(TARGETS nas_5g_msg DESTINATION ${LIBRARY_DIR} OPTIONAL) ## ORAN E2 RIC -add_library(ric_e2 STATIC e2sm_kpm.cpp e2ap.cpp e2sm.cpp) +add_library(ric_e2 STATIC e2sm_kpm_v2.cpp e2ap.cpp e2sm.cpp) target_compile_options(ric_e2 PRIVATE "-Os") target_link_libraries(ric_e2 asn1_utils srsran_common) install(TARGETS ric_e2 DESTINATION ${LIBRARY_DIR} OPTIONAL) diff --git a/lib/src/asn1/e2sm_kpm_v2.cpp b/lib/src/asn1/e2sm_kpm_v2.cpp index 8751cf43a..387b5448d 100644 --- a/lib/src/asn1/e2sm_kpm_v2.cpp +++ b/lib/src/asn1/e2sm_kpm_v2.cpp @@ -8,7 +8,7 @@ * */ -#include "srsran/asn1/e2sm_kpm.h" +#include "srsran/asn1/e2sm_kpm_v2.h" #include using namespace asn1; diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 4e0612650..a6b73091f 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -13,7 +13,7 @@ #include "e2sm_kpm.h" #include "srsran/asn1/e2ap.h" -#include "srsran/asn1/e2sm_kpm.h" +#include "srsran/asn1/e2sm_kpm_v2.h" #include "srsran/interfaces/e2_metrics_interface.h" #include "srsran/interfaces/enb_metrics_interface.h" #include "srsran/srsran.h" diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 40da47c33..c2c5c6b2b 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -11,7 +11,7 @@ * */ #include "srsran/asn1/e2sm.h" -#include "srsran/asn1/e2sm_kpm.h" +#include "srsran/asn1/e2sm_kpm_v2.h" #include "srsran/srsran.h" #ifndef RIC_E2SM_KPM_H From 02d1fc53369a8872eb4b2e3e2f8cd643784c51b5 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 17 Mar 2023 14:26:38 +0100 Subject: [PATCH 028/167] generate E2 indication --- srsgnb/hdr/stack/ric/e2ap.h | 2 +- srsgnb/hdr/stack/ric/e2sm_kpm.h | 6 ++-- srsgnb/src/stack/ric/e2ap.cc | 49 ++++++++++++++++++++++++- srsgnb/src/stack/ric/e2sm_kpm.cc | 58 ++++++++++++++++++++++++++++++ srsgnb/src/stack/ric/ric_client.cc | 27 +++++++++----- 5 files changed, 128 insertions(+), 14 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index a6b73091f..a47156802 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -46,7 +46,7 @@ public: int process_subscription_request(ricsubscription_request_s subscription_request); e2_ap_pdu_c generate_subscription_response(); int generate_subscription_failure(); - int generate_indication(); + e2_ap_pdu_c generate_indication(); e2_ap_pdu_c generate_reset_request(); e2_ap_pdu_c generate_reset_response(); int process_reset_request(reset_request_s reset_request); diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index c2c5c6b2b..fb1823c33 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -31,9 +31,9 @@ public: e2sm_kpm(srslog::basic_logger& logger_); bool generate_ran_function_description(int function_id, RANfunction_description desc, srsran::unique_byte_buffer_t& buf); - bool process_ric_action_definition(); - bool generate_indication_header(); - bool generate_indication_message(); + int process_ric_action_definition(); + bool generate_indication_header(srsran::unique_byte_buffer_t& buf); + bool generate_indication_message(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 9f2f34cb7..75136d614 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -129,9 +129,56 @@ int e2ap::process_setup_response(e2setup_resp_s setup_response) int e2ap::process_subscription_request(ricsubscription_request_s subscription_request) { pending_subscription_request = true; - // TODO process subscription request + + uint16_t ran_func_id = subscription_request->ra_nfunction_id->value; + if (ran_functions.count(ran_func_id)) { + // TODO handle RIC subscription request + } + + // TODO handle RIC subscription request + return 0; } + +e2_ap_pdu_c e2ap::generate_indication() +{ + using namespace asn1::e2ap; + e2_ap_pdu_c pdu; + + init_msg_s& initmsg = pdu.set_init_msg(); + initmsg.load_info_obj(ASN1_E2AP_ID_RI_CIND); + initmsg.crit = asn1::crit_opts::reject; + + ri_cind_s& indication = initmsg.value.ri_cind(); + + indication->ri_crequest_id.crit = asn1::crit_opts::reject; + indication->ri_crequest_id.value.ric_requestor_id = 1021; + indication->ri_crequest_id.value.ric_instance_id = 0; + + indication->ra_nfunction_id.crit = asn1::crit_opts::reject; + indication->ra_nfunction_id.value = 147; + + indication->ri_caction_id.crit = asn1::crit_opts::reject; + indication->ri_caction_id.value = 0; + + indication->ri_cind_type.crit = asn1::crit_opts::reject; + indication->ri_cind_type.value = ri_cind_type_opts::report; + + indication->ri_cind_hdr.crit = asn1::crit_opts::reject; + srsran::unique_byte_buffer_t header_buf = srsran::make_byte_buffer(); + e2sm_.generate_indication_header(header_buf); + indication->ri_cind_hdr->resize(header_buf->N_bytes); + std::copy(header_buf->msg, header_buf->msg + header_buf->N_bytes, indication->ri_cind_hdr->data()); + + indication->ri_cind_msg.crit = asn1::crit_opts::reject; + srsran::unique_byte_buffer_t msg_buf = srsran::make_byte_buffer(); + e2sm_.generate_indication_message(msg_buf); + indication->ri_cind_msg->resize(msg_buf->N_bytes); + std::copy(msg_buf->msg, msg_buf->msg + msg_buf->N_bytes, indication->ri_cind_msg->data()); + + return pdu; +} + e2_ap_pdu_c e2ap::generate_reset_request() { using namespace asn1::e2ap; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 46b898174..7aea87cd4 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -67,3 +67,61 @@ bool e2sm_kpm::generate_ran_function_description(int f buf->N_bytes = bref.distance_bytes(); return true; } + +int e2sm_kpm::process_ric_action_definition() +{ + return 0; +} + +bool e2sm_kpm::generate_indication_header(srsran::unique_byte_buffer_t& buf) +{ + using namespace asn1::e2sm_kpm; + e2_sm_kpm_ind_hdr_s e2_sm_kpm_ind_hdr; + e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().collet_start_time.from_string("43f51164"); + + logger.info("Generating E2-SM-KPM Indication Header"); + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (e2_sm_kpm_ind_hdr.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("IND HEADER: Failed to pack TX E2 PDU\n"); + return false; + } + buf->N_bytes = bref.distance_bytes(); + + return true; +} + +bool e2sm_kpm::generate_indication_message(srsran::unique_byte_buffer_t& buf) +{ + using namespace asn1::e2sm_kpm; + e2_sm_kpm_ind_msg_s e2_sm_kpm_ind_msg; + e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format1(); + + auto& meas_data_list = e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_data; + meas_data_list.resize(1); + meas_data_list[0].meas_record.resize(11); + for (uint32_t i = 0; i < meas_data_list[0].meas_record.size(); i++) { + meas_data_list[0].meas_record[i].set_integer() = i * 1000; + } + + auto& meas_info_list = e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_info_list; + meas_info_list.resize(2); + meas_info_list[0].meas_type.set_meas_name().from_string("PrbDlUsage"); + meas_info_list[0].label_info_list.resize(1); + meas_info_list[0].label_info_list[0].meas_label.no_label_present = true; + meas_info_list[0].label_info_list[0].meas_label.no_label = asn1::e2sm_kpm::meas_label_s::no_label_opts::true_value; + + meas_info_list[1].meas_type.set_meas_id() = 1; + meas_info_list[1].label_info_list.resize(1); + meas_info_list[1].label_info_list[0].meas_label.no_label_present = true; + meas_info_list[1].label_info_list[0].meas_label.no_label = asn1::e2sm_kpm::meas_label_s::no_label_opts::true_value; + + logger.info("Generating E2-SM-KPM Indication Message"); + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (e2_sm_kpm_ind_msg.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("IND MSG: Failed to pack TX E2 PDU\n"); + return false; + } + buf->N_bytes = bref.distance_bytes(); + + return true; +} diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index af2478e33..e2dbff5a6 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -111,15 +111,16 @@ bool ric_client::send_e2_msg(e2_msg_type_t msg_type) e2_ap_pdu_c send_pdu; switch (msg_type) { case e2_msg_type_t::E2_SETUP_REQUEST: - send_pdu = e2ap_.generate_setup_request(); + send_pdu = e2ap_.generate_setup_request(); message_name = "E2 SETUP REQUEST"; break; case e2_msg_type_t::E2_SUB_RESPONSE: - send_pdu = e2ap_.generate_subscription_response(); + send_pdu = e2ap_.generate_subscription_response(); message_name = "E2 SUBSCRIPTION RESPONSE"; break; case e2_msg_type_t::E2_INDICATION: - // TODO create E2 INDICATION generation + send_pdu = e2ap_.generate_indication(); + message_name = "E2 INDICATION"; break; case e2_msg_type_t::E2_RESET: send_pdu = e2ap_.generate_reset_request(); @@ -252,12 +253,20 @@ bool ric_client::handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request) { - auto send_sub_resp = - [this]() { - send_e2_msg(E2_SUB_RESPONSE); - }; - ric_rece_task_queue.push(send_sub_resp); - // TODO handle RIC subscription request + auto send_sub_resp = [this]() { send_e2_msg(E2_SUB_RESPONSE); }; + ric_rece_task_queue.push(send_sub_resp); + + logger.info("Received subscription request from RIC ID: %i (instance id %i) to RAN Function ID: %i \n", + ric_subscription_request->ri_crequest_id->ric_requestor_id, + ric_subscription_request->ri_crequest_id->ric_instance_id, + ric_subscription_request->ra_nfunction_id->value); + + e2ap_.process_subscription_request(ric_subscription_request); + + auto send_ind = [this]() { for(uint16_t i = 0; i < 5; i++) {send_e2_msg(E2_INDICATION); + sleep(1);}}; + ric_rece_task_queue.push(send_ind); + return true; } From e21a90336ee3b419347f5efe11c94ba3d0fac5c1 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 17 Mar 2023 14:27:07 +0100 Subject: [PATCH 029/167] generate E2 Subscription Delete Resp --- srsgnb/hdr/stack/ric/e2ap.h | 1 + srsgnb/hdr/stack/ric/ric_client.h | 10 +++++++++- srsgnb/src/stack/ric/e2ap.cc | 20 +++++++++++++++++++- srsgnb/src/stack/ric/ric_client.cc | 14 +++++++++++++- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index a47156802..3fbb1c651 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -46,6 +46,7 @@ public: int process_subscription_request(ricsubscription_request_s subscription_request); e2_ap_pdu_c generate_subscription_response(); int generate_subscription_failure(); + e2_ap_pdu_c generate_subscription_delete_response(); e2_ap_pdu_c generate_indication(); e2_ap_pdu_c generate_reset_request(); e2_ap_pdu_c generate_reset_response(); diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index adc1f6520..2d9d645c5 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -23,7 +23,14 @@ static const int e2ap_ppid = 70; static const int e2ap_port = 36421; -enum e2_msg_type_t { E2_SETUP_REQUEST, E2_SUB_RESPONSE, E2_INDICATION, E2_RESET, E2_RESET_RESPONSE }; +enum e2_msg_type_t { + E2_SETUP_REQUEST, + E2_SUB_RESPONSE, + E2_SUB_DEL_RESPONSE, + E2_INDICATION, + E2_RESET, + E2_RESET_RESPONSE +}; namespace srsenb { class ric_client : public srsran::thread @@ -49,6 +56,7 @@ public: bool handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome); bool handle_e2_setup_response(e2setup_resp_s setup_response); bool handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request); + bool handle_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request); bool handle_reset_response(reset_resp_s& reset_response); bool handle_reset_request(reset_request_s& reset_request); diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 75136d614..adc2993ee 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -96,7 +96,25 @@ e2_ap_pdu_c e2ap::generate_subscription_response() action_not_admit_list[0].load_info_obj(ASN1_E2AP_ID_RI_CACTION_NOT_ADMITTED_ITEM); ri_caction_not_admitted_item_s& not_a_item = action_not_admit_list[0]->ri_caction_not_admitted_item(); not_a_item.ric_action_id = 10; - not_a_item.cause.misc(); + not_a_item.cause.set_misc(); + + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_delete_response() +{ + e2_ap_pdu_c pdu; + successful_outcome_s& success = pdu.set_successful_outcome(); + success.load_info_obj(ASN1_E2AP_ID_RICSUBSCRIPTION_DELETE); + success.crit = asn1::crit_opts::reject; + ricsubscription_delete_resp_s& sub_resp = success.value.ricsubscription_delete_resp(); + + sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; + sub_resp->ri_crequest_id->ric_requestor_id = 1021; + sub_resp->ri_crequest_id->ric_instance_id = 0; + + sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; + sub_resp->ra_nfunction_id->value = 147; return pdu; } diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index e2dbff5a6..0bdc7f853 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -118,6 +118,10 @@ bool ric_client::send_e2_msg(e2_msg_type_t msg_type) send_pdu = e2ap_.generate_subscription_response(); message_name = "E2 SUBSCRIPTION RESPONSE"; break; + case e2_msg_type_t::E2_SUB_DEL_RESPONSE: + send_pdu = e2ap_.generate_subscription_delete_response(); + message_name = "E2 SUBSCRIPTION DELETE RESPONSE"; + break; case e2_msg_type_t::E2_INDICATION: send_pdu = e2ap_.generate_indication(); message_name = "E2 INDICATION"; @@ -183,7 +187,7 @@ bool ric_client::handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg) handle_ric_subscription_request(init_msg.value.ricsubscription_request()); } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::ricsubscription_delete_request) { logger.info("Received E2AP RIC Subscription Delete Request"); - // handle_ric_subscription_delete_request(init_msg.value.ricsubscription_delete_request()); + handle_ric_subscription_delete_request(init_msg.value.ricsubscription_delete_request()); } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::ri_cctrl_request) { logger.info("Received E2AP RIC Control Request"); // handle_ri_cctrl_request(init_msg.value.ri_cctrl_request()); @@ -270,6 +274,14 @@ bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_s return true; } +bool ric_client::handle_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request) +{ + auto send_resp = [this]() { send_e2_msg(E2_SUB_DEL_RESPONSE); }; + ric_rece_task_queue.push(send_resp); + + return true; +} + bool ric_client::handle_reset_request(reset_request_s& reset_request) { printf("Received E2AP E2 Reset Request \n"); From c3f4dfd19462f3d3f8113a840901e9c898264eff Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 17 Mar 2023 14:48:09 +0100 Subject: [PATCH 030/167] use ric_client configuration (ip, port) --- srsenb/enb.conf.example | 6 ++++++ srsenb/hdr/enb.h | 6 ------ srsenb/src/enb.cc | 2 +- srsenb/src/main.cc | 2 +- srsgnb/hdr/stack/ric/ric_client.h | 8 +++++++- srsgnb/src/stack/ric/ric_client.cc | 4 ++-- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index ba5abc8fa..e34503e16 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -370,6 +370,12 @@ enable = false #auto_target_papr = 8 #ema_alpha = 0.0143 +##################################################################### +[ric_client] +enable = true +#ric_ip = 127.0.0.1 +#ric_port = 36421 + ##################################################################### # Expert configuration options # diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 2dc511f38..8fed379aa 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -104,12 +104,6 @@ struct general_args_t { uint32_t rlf_release_timer_ms; }; -struct ric_args_t { - bool enable; - std::string ric_ip; - uint32_t ric_port; -}; - struct all_args_t { enb_args_t enb; enb_files_t enb_files; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 2294e3f11..04697a0f4 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -198,7 +198,7 @@ bool enb::enable_ric_client(srsenb::e2_interface_metrics* e2_metrics) srsran::console("Error creating RIC client instance.\n"); return SRSRAN_ERROR; } - if (tmp_ric_client->init()) { + if (tmp_ric_client->init(args.ric_client)) { srsran::console("Error initializing RIC client.\n"); return SRSRAN_ERROR; } diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index e40a3c7de..39b2f177f 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -231,7 +231,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) /* RIC section */ ("ric_client.enable", bpo::value(&args->ric_client.enable)->default_value(false), "Enables the RIC client") ("ric_client.ric_ip", bpo::value(&args->ric_client.ric_ip)->default_value("127.0.0.1"), "RIC IP address") - ("ric_client.ric_port", bpo::value(&args->ric_client.ric_port)->default_value(36422), "RIC port") + ("ric_client.ric_port", bpo::value(&args->ric_client.ric_port)->default_value(36421), "RIC port") /* Expert section */ ("expert.metrics_period_secs", bpo::value(&args->general.metrics_period_secs)->default_value(1.0), "Periodicity for metrics in seconds.") ("expert.metrics_csv_enable", bpo::value(&args->general.metrics_csv_enable)->default_value(false), "Write metrics to CSV file.") diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index 2d9d645c5..4e289f631 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -32,6 +32,12 @@ enum e2_msg_type_t { E2_RESET_RESPONSE }; +struct ric_args_t { + bool enable; + std::string ric_ip; + uint32_t ric_port; +}; + namespace srsenb { class ric_client : public srsran::thread { @@ -39,7 +45,7 @@ public: ric_client(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics); // Initiate and Stop - bool init(); + bool init(ric_args_t args); void stop(); void run_thread(); diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 0bdc7f853..8fa6c7b86 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -21,7 +21,7 @@ ric_client::ric_client(srslog::basic_logger& logger, e2_interface_metrics* _gnb_ gnb_metrics = _gnb_metrics; } -bool ric_client::init() +bool ric_client::init(ric_args_t args) { printf("RIC_CLIENT: Init\n"); using namespace srsran::net_utils; @@ -42,7 +42,7 @@ bool ric_client::init() } // Connect to the AMF address - if (not ric_socket.connect_to("127.0.0.1", e2ap_port, &ric_addr)) { + if (not ric_socket.connect_to(args.ric_ip.c_str(), args.ric_port, &ric_addr)) { return false; } // Assign a handler to rx RIC packets From faa90aebdcd1e0a113f07fe333618aa002a35baa Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 17 Mar 2023 23:33:16 +0100 Subject: [PATCH 031/167] add ric_subscription class --- srsenb/hdr/enb.h | 1 + srsenb/src/enb.cc | 5 ++ srsgnb/hdr/stack/ric/ric_client.h | 7 ++ srsgnb/hdr/stack/ric/ric_subscription.h | 51 ++++++++++++++ srsgnb/src/stack/ric/CMakeLists.txt | 2 +- srsgnb/src/stack/ric/ric_client.cc | 84 +++++++++++++++++------- srsgnb/src/stack/ric/ric_subscription.cc | 66 +++++++++++++++++++ 7 files changed, 190 insertions(+), 26 deletions(-) create mode 100644 srsgnb/hdr/stack/ric/ric_subscription.h create mode 100644 srsgnb/src/stack/ric/ric_subscription.cc diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 8fed379aa..c2defb76e 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -34,6 +34,7 @@ #include "srsenb/hdr/stack/mac/sched_interface.h" #include "srsgnb/hdr/stack/gnb_stack_nr.h" #include "srsgnb/hdr/stack/ric/ric_client.h" +#include "srsgnb/hdr/stack/ric/ric_subscription.h" #include "srsran/common/bcd_helpers.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/interfaces_common.h" diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 04697a0f4..51b727f3a 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -274,6 +274,11 @@ void enb::tti_clock() if (!started) { return; } + + if (ric) { + ric->tic(); + } + if (eutra_stack) { eutra_stack->tti_clock(); } diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index 4e289f631..909438808 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -48,10 +48,13 @@ public: bool init(ric_args_t args); void stop(); void run_thread(); + void tic(); // Send messages to RIC bool send_sctp(srsran::unique_byte_buffer_t& buf); bool send_e2_msg(e2_msg_type_t msg_type); + bool queue_send_e2ap_pdu(e2_ap_pdu_c send_pdu); + bool send_e2ap_pdu(e2_ap_pdu_c send_pdu); bool send_reset_response(); // Handle messages received from RIC @@ -66,6 +69,8 @@ public: bool handle_reset_response(reset_resp_s& reset_response); bool handle_reset_request(reset_request_s& reset_request); + class ric_subscription; + private: e2ap e2ap_; srsran::unique_socket ric_socket; @@ -76,6 +81,8 @@ private: struct sockaddr_in ric_addr = {}; // RIC address bool running = false; srsenb::e2_interface_metrics* gnb_metrics = nullptr; + + std::vector > active_subscriptions; }; } // namespace srsenb diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h new file mode 100644 index 000000000..f24e69ce1 --- /dev/null +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -0,0 +1,51 @@ +/** + * + * \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. + * + * + */ + +#ifndef SRSRAN_RIC_SUBSCRIPTION_H +#define SRSRAN_RIC_SUBSCRIPTION_H + +#include "srsgnb/hdr/stack/ric/e2ap.h" +#include "srsgnb/hdr/stack/ric/ric_client.h" +#include "srsran/common/task_scheduler.h" +#include "srsran/common/threads.h" +#include "srsran/srsran.h" + +namespace srsenb { + +class ric_client::ric_subscription +{ +public: + ric_subscription(ric_client* ric_client, ricsubscription_request_s ric_subscription_request); + virtual ~ric_subscription() = default; + + uint32_t get_ric_requestor_id() { return ric_requestor_id; }; + uint32_t get_ric_instance_id() { return ric_instance_id; }; + + void start_ric_indication_reporting(); + void stop_ric_indication_reporting(); + +private: + void send_ric_indication(); + + ric_client* parent = nullptr; + + uint32_t ric_requestor_id; + uint32_t ric_instance_id; + uint16_t ra_nfunction_id; + + uint32_t reporting_period; // ms + srsran::unique_timer reporting_timer; // for RIC indication reporting +}; + +} // namespace srsenb +#endif // SRSRAN_RIC_SUBSCRIPTION_H diff --git a/srsgnb/src/stack/ric/CMakeLists.txt b/srsgnb/src/stack/ric/CMakeLists.txt index 001db312a..17d368003 100644 --- a/srsgnb/src/stack/ric/CMakeLists.txt +++ b/srsgnb/src/stack/ric/CMakeLists.txt @@ -1,4 +1,4 @@ -set(SOURCES ric_client.cc e2ap.cc e2sm_kpm.cc) +set(SOURCES ric_client.cc ric_subscription.cc e2ap.cc e2sm_kpm.cc) add_library(srsgnb_ric STATIC ${SOURCES}) target_link_libraries(srsgnb_ric srsran_asn1 ric_e2) diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 8fa6c7b86..32a94754a 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -11,6 +11,7 @@ */ #include "srsgnb/hdr/stack/ric/ric_client.h" +#include "srsgnb/hdr/stack/ric/ric_subscription.h" #include "srsran/asn1/e2ap.h" #include "stdint.h" @@ -66,6 +67,12 @@ void ric_client::stop() wait_thread_finish(); } +void ric_client::tic() +{ + // get tick every 1ms to advance timers + task_sched.tic(); +} + void ric_client::run_thread() { using namespace asn1::e2ap; @@ -75,7 +82,6 @@ void ric_client::run_thread() send_e2_msg(E2_SETUP_REQUEST); printf("e2 setup request sent\n"); } - sleep(1); task_sched.run_next_task(); } } @@ -114,18 +120,6 @@ bool ric_client::send_e2_msg(e2_msg_type_t msg_type) send_pdu = e2ap_.generate_setup_request(); message_name = "E2 SETUP REQUEST"; break; - case e2_msg_type_t::E2_SUB_RESPONSE: - send_pdu = e2ap_.generate_subscription_response(); - message_name = "E2 SUBSCRIPTION RESPONSE"; - break; - case e2_msg_type_t::E2_SUB_DEL_RESPONSE: - send_pdu = e2ap_.generate_subscription_delete_response(); - message_name = "E2 SUBSCRIPTION DELETE RESPONSE"; - break; - case e2_msg_type_t::E2_INDICATION: - send_pdu = e2ap_.generate_indication(); - message_name = "E2 INDICATION"; - break; case e2_msg_type_t::E2_RESET: send_pdu = e2ap_.generate_reset_request(); message_name = "E2 RESET REQUEST"; @@ -152,6 +146,34 @@ bool ric_client::send_e2_msg(e2_msg_type_t msg_type) return true; } +bool ric_client::queue_send_e2ap_pdu(e2_ap_pdu_c e2ap_pdu) +{ + auto send_e2ap_pdu_task = [this, e2ap_pdu]() { send_e2ap_pdu(e2ap_pdu); }; + ric_rece_task_queue.push(send_e2ap_pdu_task); + return true; +} + +bool ric_client::send_e2ap_pdu(e2_ap_pdu_c send_pdu) +{ + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + if (buf == nullptr) { + // logger.error("Fatal Error: Couldn't allocate buffer for %s.", procedure_name); + return false; + } + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (send_pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + logger.error("Failed to pack TX E2 PDU"); + return false; + } + buf->N_bytes = bref.distance_bytes(); + printf("try to send %d bytes to addr %s \n", buf->N_bytes, inet_ntoa(ric_addr.sin_addr)); + if (!send_sctp(buf)) { + logger.error("failed to send"); + return false; + } + return true; +} + bool ric_client::handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, @@ -257,27 +279,39 @@ bool ric_client::handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request) { - auto send_sub_resp = [this]() { send_e2_msg(E2_SUB_RESPONSE); }; - ric_rece_task_queue.push(send_sub_resp); - - logger.info("Received subscription request from RIC ID: %i (instance id %i) to RAN Function ID: %i \n", + logger.info("Received RIC Subscription Request from RIC ID: %i (instance id %i) to RAN Function ID: %i", ric_subscription_request->ri_crequest_id->ric_requestor_id, ric_subscription_request->ri_crequest_id->ric_instance_id, ric_subscription_request->ra_nfunction_id->value); - e2ap_.process_subscription_request(ric_subscription_request); - - auto send_ind = [this]() { for(uint16_t i = 0; i < 5; i++) {send_e2_msg(E2_INDICATION); - sleep(1);}}; - ric_rece_task_queue.push(send_ind); - + std::unique_ptr new_ric_subs = + std::make_unique(this, ric_subscription_request); + new_ric_subs->start_ric_indication_reporting(); + active_subscriptions.push_back(std::move(new_ric_subs)); return true; } bool ric_client::handle_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request) { - auto send_resp = [this]() { send_e2_msg(E2_SUB_DEL_RESPONSE); }; - ric_rece_task_queue.push(send_resp); + logger.info("Received RIC Subscription Delete request from RIC ID: %i (instance id %i) to RAN Function ID: %i", + ricsubscription_delete_request->ri_crequest_id->ric_requestor_id, + ricsubscription_delete_request->ri_crequest_id->ric_instance_id, + ricsubscription_delete_request->ra_nfunction_id->value); + + bool ric_subs_found = false; + for (auto it = active_subscriptions.begin(); it != active_subscriptions.end(); it++) { + if ((**it).get_ric_requestor_id() == ricsubscription_delete_request->ri_crequest_id->ric_requestor_id and + (**it).get_ric_instance_id() == ricsubscription_delete_request->ri_crequest_id->ric_instance_id) { + ric_subs_found = true; + (**it).stop_ric_indication_reporting(); + active_subscriptions.erase(it); + break; + } + } + + if (not ric_subs_found) { + // TODO: send failure + } return true; } diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc new file mode 100644 index 000000000..b4417c107 --- /dev/null +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -0,0 +1,66 @@ +/** + * + * \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 "srsgnb/hdr/stack/ric/ric_subscription.h" + +namespace srsenb { + +ric_client::ric_subscription::ric_subscription(ric_client* ric_client, + ricsubscription_request_s ric_subscription_request) : + parent(ric_client), + ric_requestor_id(ric_subscription_request->ri_crequest_id->ric_requestor_id), + ric_instance_id(ric_subscription_request->ri_crequest_id->ric_instance_id), + ra_nfunction_id(ric_subscription_request->ra_nfunction_id->value) +{ + reporting_period = 1000; + reporting_timer = parent->task_sched.get_unique_timer(); + + // TODO: process request to know what to report + parent->e2ap_.process_subscription_request(ric_subscription_request); +} + +void ric_client::ric_subscription::start_ric_indication_reporting() +{ + parent->logger.debug("Send RIC Subscription Response to RIC Requestor ID: %i\n", ric_requestor_id); + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_response(); + parent->queue_send_e2ap_pdu(send_pdu); + + printf("Start sending RIC indication msgs every %i ms\n", reporting_period); + parent->logger.debug("Start sending RIC indication msgs every %i ms", reporting_period); + reporting_timer.set(reporting_period, [this](uint32_t tid) { send_ric_indication(); }); + reporting_timer.run(); +} + +void ric_client::ric_subscription::stop_ric_indication_reporting() +{ + if (reporting_timer.is_running()) { + parent->logger.debug("Stop sending RIC indication msgs"); + reporting_timer.stop(); + } + + parent->logger.debug("Send RIC Subscription Delete Response to RIC Requestor ID: %i\n", ric_requestor_id); + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_delete_response(); + parent->queue_send_e2ap_pdu(send_pdu); +} + +void ric_client::ric_subscription::send_ric_indication() +{ + printf("Sending RIC indication msg to RIC Requestor ID: %i\n", ric_requestor_id); + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(); + parent->queue_send_e2ap_pdu(send_pdu); + + // reschedule sending RIC indication + reporting_timer.run(); +} + +} // namespace srsenb \ No newline at end of file From d1ed79175b3175efa447f9b3ccacdf0c3b054c6b Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 13:59:39 +0100 Subject: [PATCH 032/167] e2ap: parametrize subscription reponse --- srsgnb/hdr/stack/ric/e2ap.h | 10 +++++- srsgnb/src/stack/ric/e2ap.cc | 42 ++++++++++++++---------- srsgnb/src/stack/ric/ric_subscription.cc | 10 +++++- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 3fbb1c651..698ecbac5 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -36,6 +36,14 @@ typedef struct { std::string response_part; } e2_node_component_t; +typedef struct { + uint32_t ric_requestor_id; + uint32_t ric_instance_id; + uint32_t ra_nfunction_id; + std::vector admitted_actions; + std::vector not_admitted_actions; +} ric_subscription_reponse_t; + class e2ap { public: @@ -44,7 +52,7 @@ public: int process_setup_response(e2setup_resp_s setup_response); int process_setup_failure(); int process_subscription_request(ricsubscription_request_s subscription_request); - e2_ap_pdu_c generate_subscription_response(); + e2_ap_pdu_c generate_subscription_response(ric_subscription_reponse_t ric_subscription_reponse); int generate_subscription_failure(); e2_ap_pdu_c generate_subscription_delete_response(); e2_ap_pdu_c generate_indication(); diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index adc2993ee..277171953 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -66,7 +66,7 @@ e2_ap_pdu_c e2ap::generate_setup_request() return pdu; } -e2_ap_pdu_c e2ap::generate_subscription_response() +e2_ap_pdu_c e2ap::generate_subscription_response(ric_subscription_reponse_t ric_subscription_reponse) { e2_ap_pdu_c pdu; successful_outcome_s& success = pdu.set_successful_outcome(); @@ -76,27 +76,33 @@ e2_ap_pdu_c e2ap::generate_subscription_response() sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; sub_resp->ri_crequest_id.id = ASN1_E2AP_ID_RI_CREQUEST_ID; - sub_resp->ri_crequest_id.value.ric_requestor_id = 1021; - sub_resp->ri_crequest_id.value.ric_instance_id = 0; + sub_resp->ri_crequest_id.value.ric_requestor_id = ric_subscription_reponse.ric_requestor_id; + sub_resp->ri_crequest_id.value.ric_instance_id = ric_subscription_reponse.ric_instance_id; - sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; - sub_resp->ra_nfunction_id.id = ASN1_E2AP_ID_RA_NFUNCTION_ID; - sub_resp->ra_nfunction_id->value = 147; + sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; + sub_resp->ra_nfunction_id.id = ASN1_E2AP_ID_RA_NFUNCTION_ID; + sub_resp->ra_nfunction_id->value = ric_subscription_reponse.ra_nfunction_id; sub_resp->ri_cactions_admitted.crit = asn1::crit_opts::reject; auto& action_admit_list = sub_resp->ri_cactions_admitted.value; - action_admit_list.resize(1); - action_admit_list[0].load_info_obj(ASN1_E2AP_ID_RI_CACTION_ADMITTED_ITEM); - ri_caction_admitted_item_s& a_item = action_admit_list[0]->ri_caction_admitted_item(); - a_item.ric_action_id = 0; - - sub_resp->ri_cactions_not_admitted.crit = asn1::crit_opts::reject; - auto& action_not_admit_list = sub_resp->ri_cactions_not_admitted.value; - action_not_admit_list.resize(1); - action_not_admit_list[0].load_info_obj(ASN1_E2AP_ID_RI_CACTION_NOT_ADMITTED_ITEM); - ri_caction_not_admitted_item_s& not_a_item = action_not_admit_list[0]->ri_caction_not_admitted_item(); - not_a_item.ric_action_id = 10; - not_a_item.cause.set_misc(); + action_admit_list.resize(ric_subscription_reponse.admitted_actions.size()); + for (uint32_t i = 0; i < ric_subscription_reponse.admitted_actions.size(); i++) { + action_admit_list[i].load_info_obj(ASN1_E2AP_ID_RI_CACTION_ADMITTED_ITEM); + ri_caction_admitted_item_s& a_item = action_admit_list[i]->ri_caction_admitted_item(); + a_item.ric_action_id = ric_subscription_reponse.admitted_actions[i]; + } + + if (ric_subscription_reponse.not_admitted_actions.size()) { + sub_resp->ri_cactions_not_admitted.crit = asn1::crit_opts::reject; + auto& action_not_admit_list = sub_resp->ri_cactions_not_admitted.value; + action_not_admit_list.resize(ric_subscription_reponse.not_admitted_actions.size()); + for (uint32_t i = 0; i < ric_subscription_reponse.not_admitted_actions.size(); i++) { + action_not_admit_list[i].load_info_obj(ASN1_E2AP_ID_RI_CACTION_NOT_ADMITTED_ITEM); + ri_caction_not_admitted_item_s& not_a_item = action_not_admit_list[i]->ri_caction_not_admitted_item(); + not_a_item.ric_action_id = ric_subscription_reponse.not_admitted_actions[i]; + not_a_item.cause.set_misc(); // TODO: support cause properly + } + } return pdu; } diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index b4417c107..ac6ffaf00 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -32,7 +32,15 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli void ric_client::ric_subscription::start_ric_indication_reporting() { parent->logger.debug("Send RIC Subscription Response to RIC Requestor ID: %i\n", ric_requestor_id); - e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_response(); + ric_subscription_reponse_t ric_subscription_reponse; + ric_subscription_reponse.ric_requestor_id = ric_requestor_id; + ric_subscription_reponse.ric_instance_id = ric_instance_id; + ric_subscription_reponse.ra_nfunction_id = ra_nfunction_id; + + ric_subscription_reponse.admitted_actions.push_back(0); + ric_subscription_reponse.not_admitted_actions.push_back(10); + + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_response(ric_subscription_reponse); parent->queue_send_e2ap_pdu(send_pdu); printf("Start sending RIC indication msgs every %i ms\n", reporting_period); From 701f26e34b25e10d5b0a45ed9b04a18cd33f5238 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 14:01:42 +0100 Subject: [PATCH 033/167] e2ap: parametrize subscription delete reponse --- srsgnb/hdr/stack/ric/e2ap.h | 3 ++- srsgnb/src/stack/ric/e2ap.cc | 10 ++++++---- srsgnb/src/stack/ric/ric_subscription.cc | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 698ecbac5..73898c73e 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -54,7 +54,8 @@ public: int process_subscription_request(ricsubscription_request_s subscription_request); e2_ap_pdu_c generate_subscription_response(ric_subscription_reponse_t ric_subscription_reponse); int generate_subscription_failure(); - e2_ap_pdu_c generate_subscription_delete_response(); + e2_ap_pdu_c + generate_subscription_delete_response(uint32_t ric_requestor_id, uint32_t ric_instance_id, uint32_t ra_nfunction_id); e2_ap_pdu_c generate_indication(); e2_ap_pdu_c generate_reset_request(); e2_ap_pdu_c generate_reset_response(); diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 277171953..64862966b 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -107,7 +107,9 @@ e2_ap_pdu_c e2ap::generate_subscription_response(ric_subscription_reponse_t ric_ return pdu; } -e2_ap_pdu_c e2ap::generate_subscription_delete_response() +e2_ap_pdu_c e2ap::generate_subscription_delete_response(uint32_t ric_requestor_id, + uint32_t ric_instance_id, + uint32_t ra_nfunction_id) { e2_ap_pdu_c pdu; successful_outcome_s& success = pdu.set_successful_outcome(); @@ -116,11 +118,11 @@ e2_ap_pdu_c e2ap::generate_subscription_delete_response() ricsubscription_delete_resp_s& sub_resp = success.value.ricsubscription_delete_resp(); sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; - sub_resp->ri_crequest_id->ric_requestor_id = 1021; - sub_resp->ri_crequest_id->ric_instance_id = 0; + sub_resp->ri_crequest_id->ric_requestor_id = ric_requestor_id; + sub_resp->ri_crequest_id->ric_instance_id = ric_instance_id; sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; - sub_resp->ra_nfunction_id->value = 147; + sub_resp->ra_nfunction_id->value = ra_nfunction_id; return pdu; } diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index ac6ffaf00..d271bf94c 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -57,7 +57,8 @@ void ric_client::ric_subscription::stop_ric_indication_reporting() } parent->logger.debug("Send RIC Subscription Delete Response to RIC Requestor ID: %i\n", ric_requestor_id); - e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_delete_response(); + e2_ap_pdu_c send_pdu = + parent->e2ap_.generate_subscription_delete_response(ric_requestor_id, ric_instance_id, ra_nfunction_id); parent->queue_send_e2ap_pdu(send_pdu); } From 9f36e4b12c9f66c3b93ecc468d77728fdca83fb8 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 14:03:06 +0100 Subject: [PATCH 034/167] e2ap: parametrize ric indication --- srsgnb/hdr/stack/ric/e2ap.h | 12 +++++- srsgnb/hdr/stack/ric/e2sm_kpm.h | 18 ++++++++- srsgnb/hdr/stack/ric/ric_subscription.h | 1 + srsgnb/src/stack/ric/e2ap.cc | 29 +++++++-------- srsgnb/src/stack/ric/e2sm_kpm.cc | 47 +++++++++++++----------- srsgnb/src/stack/ric/ric_subscription.cc | 27 +++++++++++++- 6 files changed, 93 insertions(+), 41 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 73898c73e..61037b156 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -44,6 +44,16 @@ typedef struct { std::vector not_admitted_actions; } ric_subscription_reponse_t; +typedef struct { + uint32_t ric_requestor_id; + uint32_t ric_instance_id; + uint32_t ra_nfunction_id; + uint32_t ri_caction_id; + ri_cind_type_e indication_type; + RIC_indication_header indication_header; + RIC_indication_message indication_message; +} ric_indication_t; + class e2ap { public: @@ -56,7 +66,7 @@ public: int generate_subscription_failure(); e2_ap_pdu_c generate_subscription_delete_response(uint32_t ric_requestor_id, uint32_t ric_instance_id, uint32_t ra_nfunction_id); - e2_ap_pdu_c generate_indication(); + e2_ap_pdu_c generate_indication(ric_indication_t& ric_indication); e2_ap_pdu_c generate_reset_request(); e2_ap_pdu_c generate_reset_response(); int process_reset_request(reset_request_s reset_request); diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index fb1823c33..adec8fc9a 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -23,6 +23,20 @@ struct RANfunction_description { 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; + std::string sender_name; + std::string sender_type; + std::string vendor_name; +}; + +struct RIC_indication_message { + asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types ind_msg_format; + asn1::e2sm_kpm::meas_data_l meas_data; + asn1::e2sm_kpm::meas_info_list_l meas_info_list; + uint64_t granul_period = 0; }; class e2sm_kpm @@ -32,8 +46,8 @@ public: 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(srsran::unique_byte_buffer_t& buf); - bool generate_indication_message(srsran::unique_byte_buffer_t& buf); + 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/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index f24e69ce1..0b96c52b2 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -42,6 +42,7 @@ private: uint32_t ric_requestor_id; uint32_t ric_instance_id; uint16_t ra_nfunction_id; + uint16_t ri_caction_id; uint32_t reporting_period; // ms srsran::unique_timer reporting_timer; // for RIC indication reporting diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 64862966b..a5a19a307 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -166,7 +166,7 @@ int e2ap::process_subscription_request(ricsubscription_request_s subscription_re return 0; } -e2_ap_pdu_c e2ap::generate_indication() +e2_ap_pdu_c e2ap::generate_indication(ric_indication_t& ric_indication) { using namespace asn1::e2ap; e2_ap_pdu_c pdu; @@ -175,30 +175,29 @@ e2_ap_pdu_c e2ap::generate_indication() initmsg.load_info_obj(ASN1_E2AP_ID_RI_CIND); initmsg.crit = asn1::crit_opts::reject; - ri_cind_s& indication = initmsg.value.ri_cind(); - + ri_cind_s& indication = initmsg.value.ri_cind(); indication->ri_crequest_id.crit = asn1::crit_opts::reject; - indication->ri_crequest_id.value.ric_requestor_id = 1021; - indication->ri_crequest_id.value.ric_instance_id = 0; + indication->ri_crequest_id.value.ric_requestor_id = ric_indication.ric_requestor_id; + indication->ri_crequest_id.value.ric_instance_id = ric_indication.ric_instance_id; indication->ra_nfunction_id.crit = asn1::crit_opts::reject; - indication->ra_nfunction_id.value = 147; + indication->ra_nfunction_id.value = ric_indication.ra_nfunction_id; indication->ri_caction_id.crit = asn1::crit_opts::reject; - indication->ri_caction_id.value = 0; + indication->ri_caction_id.value = ric_indication.ri_caction_id; - indication->ri_cind_type.crit = asn1::crit_opts::reject; - indication->ri_cind_type.value = ri_cind_type_opts::report; + indication->ri_cind_type.crit = asn1::crit_opts::reject; + indication->ri_cind_type.value = ric_indication.indication_type; - indication->ri_cind_hdr.crit = asn1::crit_opts::reject; - srsran::unique_byte_buffer_t header_buf = srsran::make_byte_buffer(); - e2sm_.generate_indication_header(header_buf); + indication->ri_cind_hdr.crit = asn1::crit_opts::reject; + srsran::unique_byte_buffer_t header_buf = srsran::make_byte_buffer(); + e2sm_.generate_indication_header(ric_indication.indication_header, header_buf); indication->ri_cind_hdr->resize(header_buf->N_bytes); std::copy(header_buf->msg, header_buf->msg + header_buf->N_bytes, indication->ri_cind_hdr->data()); - indication->ri_cind_msg.crit = asn1::crit_opts::reject; - srsran::unique_byte_buffer_t msg_buf = srsran::make_byte_buffer(); - e2sm_.generate_indication_message(msg_buf); + indication->ri_cind_msg.crit = asn1::crit_opts::reject; + srsran::unique_byte_buffer_t msg_buf = srsran::make_byte_buffer(); + e2sm_.generate_indication_message(ric_indication.indication_message, msg_buf); indication->ri_cind_msg->resize(msg_buf->N_bytes); std::copy(msg_buf->msg, msg_buf->msg + msg_buf->N_bytes, indication->ri_cind_msg->data()); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 7aea87cd4..e885a97c5 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -73,13 +73,16 @@ int e2sm_kpm::process_ric_action_definition() return 0; } -bool e2sm_kpm::generate_indication_header(srsran::unique_byte_buffer_t& buf) +bool e2sm_kpm::generate_indication_header(RIC_indication_header hdr, srsran::unique_byte_buffer_t& buf) { using namespace asn1::e2sm_kpm; e2_sm_kpm_ind_hdr_s e2_sm_kpm_ind_hdr; - e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().collet_start_time.from_string("43f51164"); + e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().collet_start_time.from_number(hdr.collet_start_time); + e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().file_formatversion.from_string(hdr.file_formatversion); + e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().sender_name.from_string(hdr.sender_name); + e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().sender_type.from_string(hdr.sender_type); + e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().vendor_name.from_string(hdr.vendor_name); - logger.info("Generating E2-SM-KPM Indication Header"); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); if (e2_sm_kpm_ind_hdr.pack(bref) != asn1::SRSASN_SUCCESS) { printf("IND HEADER: Failed to pack TX E2 PDU\n"); @@ -90,31 +93,31 @@ bool e2sm_kpm::generate_indication_header(srsran::unique_byte_buffer_t& buf) return true; } -bool e2sm_kpm::generate_indication_message(srsran::unique_byte_buffer_t& buf) +bool e2sm_kpm::generate_indication_message(RIC_indication_message msg, srsran::unique_byte_buffer_t& buf) { using namespace asn1::e2sm_kpm; e2_sm_kpm_ind_msg_s e2_sm_kpm_ind_msg; - e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format1(); - auto& meas_data_list = e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_data; - meas_data_list.resize(1); - meas_data_list[0].meas_record.resize(11); - for (uint32_t i = 0; i < meas_data_list[0].meas_record.size(); i++) { - meas_data_list[0].meas_record[i].set_integer() = i * 1000; + switch (msg.ind_msg_format) { + case asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format1: + e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format1(); + e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_data = msg.meas_data; + e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_info_list = msg.meas_info_list; + break; + case asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format2: + e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format2(); + // TODO: support format2 + break; + case asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format3: + e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format3(); + // TODO: support format3 + break; + case asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::nulltype: + break; + default: + log_invalid_choice_id(msg.ind_msg_format, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); } - auto& meas_info_list = e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_info_list; - meas_info_list.resize(2); - meas_info_list[0].meas_type.set_meas_name().from_string("PrbDlUsage"); - meas_info_list[0].label_info_list.resize(1); - meas_info_list[0].label_info_list[0].meas_label.no_label_present = true; - meas_info_list[0].label_info_list[0].meas_label.no_label = asn1::e2sm_kpm::meas_label_s::no_label_opts::true_value; - - meas_info_list[1].meas_type.set_meas_id() = 1; - meas_info_list[1].label_info_list.resize(1); - meas_info_list[1].label_info_list[0].meas_label.no_label_present = true; - meas_info_list[1].label_info_list[0].meas_label.no_label = asn1::e2sm_kpm::meas_label_s::no_label_opts::true_value; - logger.info("Generating E2-SM-KPM Indication Message"); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); if (e2_sm_kpm_ind_msg.pack(bref) != asn1::SRSASN_SUCCESS) { diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index d271bf94c..6ce87b54e 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -65,7 +65,32 @@ void ric_client::ric_subscription::stop_ric_indication_reporting() void ric_client::ric_subscription::send_ric_indication() { printf("Sending RIC indication msg to RIC Requestor ID: %i\n", ric_requestor_id); - e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(); + ric_indication_t ric_indication; + ric_indication.ric_requestor_id = ric_requestor_id; + ric_indication.ric_instance_id = ric_instance_id; + ric_indication.ra_nfunction_id = ra_nfunction_id; + ric_indication.ri_caction_id = ri_caction_id; + + ric_indication.indication_type = ri_cind_type_opts::report; + ric_indication.indication_header.collet_start_time = 0x12345; + + ric_indication.indication_message.ind_msg_format = + e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + + ric_indication.indication_message.meas_data.resize(1); + ric_indication.indication_message.meas_data[0].meas_record.resize(5); + for (uint32_t i = 0; i < ric_indication.indication_message.meas_data[0].meas_record.size(); i++) { + ric_indication.indication_message.meas_data[0].meas_record[i].set_integer() = i * 1000; + } + + ric_indication.indication_message.meas_info_list.resize(1); + ric_indication.indication_message.meas_info_list[0].meas_type.set_meas_name().from_string("RRU.PrbTotDl"); + ric_indication.indication_message.meas_info_list[0].label_info_list.resize(1); + ric_indication.indication_message.meas_info_list[0].label_info_list[0].meas_label.no_label_present = true; + ric_indication.indication_message.meas_info_list[0].label_info_list[0].meas_label.no_label = + asn1::e2sm_kpm::meas_label_s::no_label_opts::true_value; + + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(ric_indication); parent->queue_send_e2ap_pdu(send_pdu); // reschedule sending RIC indication From 144a8af2e4540298cefd1879f2c92493ad3a1053 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 21:03:22 +0100 Subject: [PATCH 035/167] 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) { From 0db34807851284ce03295f9f8c581bf585eee9d5 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 22:59:13 +0100 Subject: [PATCH 036/167] e2sm_kpm: seems that wireshark does not like report_style_list --- srsgnb/src/stack/ric/e2sm_kpm.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index d82d3acfb..5d015c75a 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -33,6 +33,7 @@ bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, 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); @@ -71,7 +72,7 @@ bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, 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) { From e3ae2b8f2da3677cf4cc0daee15434a1ab7cbff7 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 21:14:19 +0100 Subject: [PATCH 037/167] e2ap: clean ric_client::send_e2_msg func --- srsgnb/src/stack/ric/ric_client.cc | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 32a94754a..7d5658bee 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -108,13 +108,9 @@ bool ric_client::send_sctp(srsran::unique_byte_buffer_t& buf) bool ric_client::send_e2_msg(e2_msg_type_t msg_type) { - std::string message_name; - srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); - if (buf == nullptr) { - // logger.error("Fatal Error: Couldn't allocate buffer for %s.", procedure_name); - return false; - } + std::string message_name; e2_ap_pdu_c send_pdu; + switch (msg_type) { case e2_msg_type_t::E2_SETUP_REQUEST: send_pdu = e2ap_.generate_setup_request(); @@ -132,18 +128,8 @@ bool ric_client::send_e2_msg(e2_msg_type_t msg_type) printf("Unknown E2AP message type\n"); return false; } - asn1::bit_ref bref(buf->msg, buf->get_tailroom()); - if (send_pdu.pack(bref) != asn1::SRSASN_SUCCESS) { - logger.error("Failed to pack TX E2 PDU: %s", message_name); - return false; - } - buf->N_bytes = bref.distance_bytes(); - printf("try to send %d bytes to addr %s \n", buf->N_bytes, inet_ntoa(ric_addr.sin_addr)); - if (!send_sctp(buf)) { - logger.error("failed to send {}", message_name); - return false; - } - return true; + + return send_e2ap_pdu(send_pdu); } bool ric_client::queue_send_e2ap_pdu(e2_ap_pdu_c e2ap_pdu) From c564e18ef08574a01e5203b99dd269f607042c19 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 21:45:04 +0100 Subject: [PATCH 038/167] e2ap: change e2ap::generate_setup_request func --- srsgnb/src/stack/ric/e2ap.cc | 50 ++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index de41fa3fc..fae94590a 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -5,6 +5,14 @@ e2ap::e2ap(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics) : logger(logger), e2sm_(logger) { gnb_metrics = _gnb_metrics; + + // add SMs to map + uint32_t local_ran_function_id = 147; + RANfunction_description 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; } e2_ap_pdu_c e2ap::generate_setup_request() @@ -25,28 +33,26 @@ e2_ap_pdu_c e2ap::generate_setup_request() // add all supported e2SM functions setup->ra_nfunctions_added.crit = asn1::crit_opts::reject; auto& ra_nfunc_list = setup->ra_nfunctions_added.value; - ra_nfunc_list.resize(1); - - // 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()); - - // add function to map - RANfunction_description 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 = ran_func.ran_function_definition; - srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); - 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()); + ra_nfunc_list.resize(ran_functions.size()); + + uint32_t idx = 0; + for (auto& x : ran_functions) { + uint32_t local_ran_function_id = x.first; + e2sm* sm_ptr = x.second.sm_ptr; + + ra_nfunction_item_s& ran_func = ra_nfunc_list[idx].value().ra_nfunction_item(); + ran_func.ran_function_id = local_ran_function_id; + ran_func.ran_function_revision = sm_ptr->get_revision(); + ran_func.ran_function_oid.from_string(sm_ptr->get_oid().c_str()); + + auto& ran_func_def = ran_func.ran_function_definition; + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + sm_ptr->generate_ran_function_description(x.second, 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()); + idx++; + } setup->e2node_component_cfg_addition.crit = asn1::crit_opts::reject; auto& list1 = setup->e2node_component_cfg_addition.value; From 83e72800107026c5a7602f57f2a184151c3c96f2 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 22:42:10 +0100 Subject: [PATCH 039/167] e2ap: update RIC indication generation --- srsgnb/hdr/stack/ric/e2ap.h | 15 ++++----- srsgnb/hdr/stack/ric/e2sm_kpm.h | 8 ++--- srsgnb/src/stack/ric/e2ap.cc | 31 +++++++++++------- srsgnb/src/stack/ric/e2sm_kpm.cc | 4 +-- srsgnb/src/stack/ric/ric_subscription.cc | 40 ++++++++++++++++-------- 5 files changed, 61 insertions(+), 37 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 61037b156..c40faaac7 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -45,13 +45,13 @@ typedef struct { } ric_subscription_reponse_t; typedef struct { - uint32_t ric_requestor_id; - uint32_t ric_instance_id; - uint32_t ra_nfunction_id; - uint32_t ri_caction_id; - ri_cind_type_e indication_type; - RIC_indication_header indication_header; - RIC_indication_message indication_message; + uint32_t ric_requestor_id; + uint32_t ric_instance_id; + uint32_t ra_nfunction_id; + uint32_t ri_caction_id; + ri_cind_type_e indication_type; + srsran::unique_byte_buffer_t ri_cind_hdr; + srsran::unique_byte_buffer_t ri_cind_msg; } ric_indication_t; class e2ap @@ -73,6 +73,7 @@ public: int process_reset_response(reset_resp_s reset_response); int get_reset_id(); bool has_setup_response() { return setup_response_received; } + bool get_func_desc(uint32_t ran_func_id, RANfunction_description& fdesc); private: srslog::basic_logger& logger; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index acb6cee57..f3f6e9bdf 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -18,7 +18,7 @@ #ifndef RIC_E2SM_KPM_H #define RIC_E2SM_KPM_H -struct RIC_indication_header { +struct E2SM_KPM_RIC_ind_header { uint32_t collet_start_time; std::string file_formatversion; std::string sender_name; @@ -26,7 +26,7 @@ struct RIC_indication_header { std::string vendor_name; }; -struct RIC_indication_message { +struct E2SM_KPM_RIC_ind_message { asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types ind_msg_format; asn1::e2sm_kpm::meas_data_l meas_data; asn1::e2sm_kpm::meas_info_list_l meas_info_list; @@ -46,8 +46,8 @@ public: 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); + bool generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf); + bool generate_indication_message(E2SM_KPM_RIC_ind_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 fae94590a..b7fa254d9 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -15,6 +15,15 @@ e2ap::e2ap(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metr ran_functions[local_ran_function_id] = add_func; } +bool e2ap::get_func_desc(uint32_t ran_func_id, RANfunction_description& fdesc) +{ + if (ran_functions.count(ran_func_id)) { + fdesc = ran_functions.at(ran_func_id); + return true; + } + return false; +} + e2_ap_pdu_c e2ap::generate_setup_request() { e2_ap_pdu_c pdu; @@ -188,17 +197,17 @@ e2_ap_pdu_c e2ap::generate_indication(ric_indication_t& ric_indication) indication->ri_cind_type.crit = asn1::crit_opts::reject; indication->ri_cind_type.value = ric_indication.indication_type; - indication->ri_cind_hdr.crit = asn1::crit_opts::reject; - srsran::unique_byte_buffer_t header_buf = srsran::make_byte_buffer(); - e2sm_.generate_indication_header(ric_indication.indication_header, header_buf); - indication->ri_cind_hdr->resize(header_buf->N_bytes); - std::copy(header_buf->msg, header_buf->msg + header_buf->N_bytes, indication->ri_cind_hdr->data()); - - indication->ri_cind_msg.crit = asn1::crit_opts::reject; - srsran::unique_byte_buffer_t msg_buf = srsran::make_byte_buffer(); - e2sm_.generate_indication_message(ric_indication.indication_message, msg_buf); - indication->ri_cind_msg->resize(msg_buf->N_bytes); - std::copy(msg_buf->msg, msg_buf->msg + msg_buf->N_bytes, indication->ri_cind_msg->data()); + indication->ri_cind_hdr.crit = asn1::crit_opts::reject; + indication->ri_cind_hdr->resize(ric_indication.ri_cind_hdr->N_bytes); + std::copy(ric_indication.ri_cind_hdr->msg, + ric_indication.ri_cind_hdr->msg + ric_indication.ri_cind_hdr->N_bytes, + indication->ri_cind_hdr->data()); + + indication->ri_cind_msg.crit = asn1::crit_opts::reject; + indication->ri_cind_msg->resize(ric_indication.ri_cind_msg->N_bytes); + std::copy(ric_indication.ri_cind_msg->msg, + ric_indication.ri_cind_msg->msg + ric_indication.ri_cind_msg->N_bytes, + indication->ri_cind_msg->data()); return pdu; } diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 5d015c75a..9c2e22f65 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -88,7 +88,7 @@ int e2sm_kpm::process_ric_action_definition() return 0; } -bool e2sm_kpm::generate_indication_header(RIC_indication_header hdr, srsran::unique_byte_buffer_t& buf) +bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf) { using namespace asn1::e2sm_kpm; e2_sm_kpm_ind_hdr_s e2_sm_kpm_ind_hdr; @@ -108,7 +108,7 @@ bool e2sm_kpm::generate_indication_header(RIC_indication_header hdr, srsran::uni return true; } -bool e2sm_kpm::generate_indication_message(RIC_indication_message msg, srsran::unique_byte_buffer_t& buf) +bool e2sm_kpm::generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf) { using namespace asn1::e2sm_kpm; e2_sm_kpm_ind_msg_s e2_sm_kpm_ind_msg; diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 6ce87b54e..d4ef55bf7 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -70,26 +70,40 @@ void ric_client::ric_subscription::send_ric_indication() ric_indication.ric_instance_id = ric_instance_id; ric_indication.ra_nfunction_id = ra_nfunction_id; ric_indication.ri_caction_id = ri_caction_id; + ric_indication.indication_type = ri_cind_type_opts::report; - ric_indication.indication_type = ri_cind_type_opts::report; - ric_indication.indication_header.collet_start_time = 0x12345; + RANfunction_description ran_func_desc; + e2sm* sm_ptr = nullptr; + if (!parent->e2ap_.get_func_desc(ra_nfunction_id, ran_func_desc)) { + return; + } + + e2sm_kpm* sm_kpm_ptr = dynamic_cast(ran_func_desc.sm_ptr); - ric_indication.indication_message.ind_msg_format = - e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + E2SM_KPM_RIC_ind_header ric_ind_header; + ric_ind_header.collet_start_time = 0x12345; + ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); + sm_kpm_ptr->generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); - ric_indication.indication_message.meas_data.resize(1); - ric_indication.indication_message.meas_data[0].meas_record.resize(5); - for (uint32_t i = 0; i < ric_indication.indication_message.meas_data[0].meas_record.size(); i++) { - ric_indication.indication_message.meas_data[0].meas_record[i].set_integer() = i * 1000; + E2SM_KPM_RIC_ind_message ric_ind_message; + ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + + ric_ind_message.meas_data.resize(1); + ric_ind_message.meas_data[0].meas_record.resize(5); + for (uint32_t i = 0; i < ric_ind_message.meas_data[0].meas_record.size(); i++) { + ric_ind_message.meas_data[0].meas_record[i].set_integer() = i * 1000; } - ric_indication.indication_message.meas_info_list.resize(1); - ric_indication.indication_message.meas_info_list[0].meas_type.set_meas_name().from_string("RRU.PrbTotDl"); - ric_indication.indication_message.meas_info_list[0].label_info_list.resize(1); - ric_indication.indication_message.meas_info_list[0].label_info_list[0].meas_label.no_label_present = true; - ric_indication.indication_message.meas_info_list[0].label_info_list[0].meas_label.no_label = + ric_ind_message.meas_info_list.resize(1); + ric_ind_message.meas_info_list[0].meas_type.set_meas_name().from_string("RRU.PrbTotDl"); + ric_ind_message.meas_info_list[0].label_info_list.resize(1); + ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label_present = true; + ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label = asn1::e2sm_kpm::meas_label_s::no_label_opts::true_value; + ric_indication.ri_cind_msg = srsran::make_byte_buffer(); + sm_kpm_ptr->generate_indication_message(ric_ind_message, ric_indication.ri_cind_msg); + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(ric_indication); parent->queue_send_e2ap_pdu(send_pdu); From 30e587403faa635979b6806ceb807e2ff0be08d3 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 22:42:45 +0100 Subject: [PATCH 040/167] e2ap: fix formatting --- srsgnb/hdr/stack/ric/e2ap.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index c40faaac7..633a58bad 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -76,20 +76,20 @@ public: bool get_func_desc(uint32_t ran_func_id, RANfunction_description& fdesc); private: - srslog::basic_logger& logger; - e2sm_kpm e2sm_; - bool setup_response_received = false; + srslog::basic_logger& logger; + e2sm_kpm e2sm_; + bool setup_response_received = false; bool pending_subscription_request = false; int setup_procedure_transaction_id = 0; uint64_t plmn_id = 0x05f510; uint64_t gnb_id = 1; - global_ric_id_t global_ric_id = {}; + global_ric_id_t global_ric_id = {}; std::map ran_functions; - srsenb::e2_interface_metrics* gnb_metrics = nullptr; - bool reset_response_received = false; - int reset_transaction_id = 1; - cause_c reset_cause = cause_c(); - int reset_id = 1; + srsenb::e2_interface_metrics* gnb_metrics = nullptr; + bool reset_response_received = false; + int reset_transaction_id = 1; + cause_c reset_cause = cause_c(); + int reset_id = 1; }; #endif /* RIC_E2AP_H */ From 87d624b333a9adfcf10058888c1135621e7e29e7 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 23:05:10 +0100 Subject: [PATCH 041/167] e2sm_kpm: add granul_period --- srsgnb/src/stack/ric/e2sm_kpm.cc | 6 ++++++ srsgnb/src/stack/ric/ric_subscription.cc | 2 ++ 2 files changed, 8 insertions(+) diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 9c2e22f65..c4898eae9 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -118,6 +118,12 @@ bool e2sm_kpm::generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran: e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format1(); e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_data = msg.meas_data; e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_info_list = msg.meas_info_list; + + if (msg.granul_period) { + e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().granul_period_present = true; + e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().granul_period = msg.granul_period; + } + break; case asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format2: e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format2(); diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index d4ef55bf7..608fd31c7 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -101,6 +101,8 @@ void ric_client::ric_subscription::send_ric_indication() ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label = asn1::e2sm_kpm::meas_label_s::no_label_opts::true_value; + // ric_ind_message.granul_period = 12345; // not implemented by flexric and crashes it + ric_indication.ri_cind_msg = srsran::make_byte_buffer(); sm_kpm_ptr->generate_indication_message(ric_ind_message, ric_indication.ri_cind_msg); From 45cbf49c1a46466b1604eae65eb405c8ad26223a Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 20 Mar 2023 23:56:27 +0100 Subject: [PATCH 042/167] e2sm_kpm: decode report_period --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 8 +++++++- srsgnb/hdr/stack/ric/ric_subscription.h | 2 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 15 +++++++++++++-- srsgnb/src/stack/ric/ric_subscription.cc | 23 +++++++++++++++++------ 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index f3f6e9bdf..b03a3e796 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -11,6 +11,7 @@ * */ #include "e2sm.h" +#include "srsran/asn1/e2ap.h" #include "srsran/asn1/e2sm.h" #include "srsran/asn1/e2sm_kpm_v2.h" #include "srsran/srsran.h" @@ -18,6 +19,10 @@ #ifndef RIC_E2SM_KPM_H #define RIC_E2SM_KPM_H +struct E2SM_KPM_RIC_event_definition { + uint64_t report_period; +}; + struct E2SM_KPM_RIC_ind_header { uint32_t collet_start_time; std::string file_formatversion; @@ -45,7 +50,8 @@ public: ~e2sm_kpm() = default; virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf); - int process_ric_action_definition(); + bool process_subscription_request(asn1::e2ap::ricsubscription_request_s subscription_request, + E2SM_KPM_RIC_event_definition& event_def); bool generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf); bool generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf); diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index 0b96c52b2..34020cf1a 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -44,7 +44,7 @@ private: uint16_t ra_nfunction_id; uint16_t ri_caction_id; - uint32_t reporting_period; // ms + uint32_t reporting_period = 0; // ms srsran::unique_timer reporting_timer; // for RIC indication reporting }; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index c4898eae9..c6eff53b2 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -83,9 +83,20 @@ bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, return true; } -int e2sm_kpm::process_ric_action_definition() +bool e2sm_kpm::process_subscription_request(asn1::e2ap::ricsubscription_request_s subscription_request, + E2SM_KPM_RIC_event_definition& event_def) { - return 0; + using namespace asn1::e2sm_kpm; + e2_sm_kpm_event_trigger_definition_s trigger_def; + asn1::cbit_ref bref(subscription_request->ricsubscription_details->ric_event_trigger_definition.data(), + subscription_request->ricsubscription_details->ric_event_trigger_definition.size()); + + if (trigger_def.unpack(bref) != asn1::SRSASN_SUCCESS) { + return false; + } + + event_def.report_period = trigger_def.event_definition_formats.event_definition_format1().report_period; + return true; } bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf) diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 608fd31c7..9c044388d 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -22,11 +22,20 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli ric_instance_id(ric_subscription_request->ri_crequest_id->ric_instance_id), ra_nfunction_id(ric_subscription_request->ra_nfunction_id->value) { - reporting_period = 1000; reporting_timer = parent->task_sched.get_unique_timer(); - // TODO: process request to know what to report parent->e2ap_.process_subscription_request(ric_subscription_request); + + RANfunction_description ran_func_desc; + if (!parent->e2ap_.get_func_desc(ra_nfunction_id, ran_func_desc)) { + return; + } + + E2SM_KPM_RIC_event_definition event_def; + e2sm_kpm* sm_kpm_ptr = dynamic_cast(ran_func_desc.sm_ptr); + if (sm_kpm_ptr->process_subscription_request(ric_subscription_request, event_def)) { + reporting_period = event_def.report_period; + } } void ric_client::ric_subscription::start_ric_indication_reporting() @@ -43,10 +52,12 @@ void ric_client::ric_subscription::start_ric_indication_reporting() e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_response(ric_subscription_reponse); parent->queue_send_e2ap_pdu(send_pdu); - printf("Start sending RIC indication msgs every %i ms\n", reporting_period); - parent->logger.debug("Start sending RIC indication msgs every %i ms", reporting_period); - reporting_timer.set(reporting_period, [this](uint32_t tid) { send_ric_indication(); }); - reporting_timer.run(); + if (reporting_period) { + printf("Start sending RIC indication msgs every %i ms\n", reporting_period); + parent->logger.debug("Start sending RIC indication msgs every %i ms", reporting_period); + reporting_timer.set(reporting_period, [this](uint32_t tid) { send_ric_indication(); }); + reporting_timer.run(); + } } void ric_client::ric_subscription::stop_ric_indication_reporting() From 730947d9bbdb927f08a2abfa05ad60ccb970dea2 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 11:47:25 +0100 Subject: [PATCH 043/167] e2ap: update test --- srsgnb/src/stack/ric/test/e2ap_test.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index 0c6b349c3..08561cd52 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -140,9 +140,15 @@ void test_native_e2ap_subscription_response() srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); dummy_metrics_interface dummy_metrics; e2ap e2ap_(logger, &dummy_metrics); - pdu = e2ap_.generate_subscription_response(); - pdu = e2ap_.generate_subscription_response(); + ric_subscription_reponse_t ric_subscription_reponse; + ric_subscription_reponse.ric_requestor_id = 1021; + ric_subscription_reponse.ric_instance_id = 0; + ric_subscription_reponse.ra_nfunction_id = 147; + ric_subscription_reponse.admitted_actions.push_back(0); + + pdu = e2ap_.generate_subscription_response(ric_subscription_reponse); + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) { printf("Failed to pack TX E2 PDU\n"); From 5ab4b62313ae29868d8255b39e2791f4285a8aad Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 11:54:14 +0100 Subject: [PATCH 044/167] e2am_kpm: define supported meas types --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 3 ++- srsgnb/src/stack/ric/e2sm_kpm.cc | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index b03a3e796..5e530bff0 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -56,7 +56,8 @@ public: bool generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf); private: - srslog::basic_logger& logger; + srslog::basic_logger& logger; + std::vector supported_meas_types; }; #endif /*E2SM_KPM*/ diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index c6eff53b2..bee0b9645 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -7,6 +7,9 @@ const uint32_t e2sm_kpm::revision = 0; e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_description, revision), logger(logger_) { + supported_meas_types.push_back("RRU.PrbTotDl"); + supported_meas_types.push_back("RRU.PrbTotUl"); + supported_meas_types.push_back("test"); } bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf) From da2cb59349a76399ca0f68518f6c5c8aa7c31a8e Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 11:55:48 +0100 Subject: [PATCH 045/167] e2ap: fix reporting period to 1s for testing --- srsgnb/src/stack/ric/ric_subscription.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 9c044388d..83099a1d2 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -35,6 +35,7 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli e2sm_kpm* sm_kpm_ptr = dynamic_cast(ran_func_desc.sm_ptr); if (sm_kpm_ptr->process_subscription_request(ric_subscription_request, event_def)) { reporting_period = event_def.report_period; + reporting_period = 1000; // TODO: to remove, keep it 1s for testing } } From ff3fb050efd0ba4ef3824c776b39760dba5c41d3 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 12:21:40 +0100 Subject: [PATCH 046/167] e2sm: process RIC action definition --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 1 + srsgnb/hdr/stack/ric/ric_subscription.h | 3 + srsgnb/src/stack/ric/e2sm_kpm.cc | 81 ++++++++++++++++++++++++ srsgnb/src/stack/ric/ric_subscription.cc | 33 +++++++++- 4 files changed, 116 insertions(+), 2 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 5e530bff0..fa0652d6e 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -52,6 +52,7 @@ public: virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf); bool process_subscription_request(asn1::e2ap::ricsubscription_request_s subscription_request, E2SM_KPM_RIC_event_definition& event_def); + bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action); bool generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf); bool generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf); diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index 34020cf1a..adbec6e14 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -46,6 +46,9 @@ private: uint32_t reporting_period = 0; // ms srsran::unique_timer reporting_timer; // for RIC indication reporting + + std::vector admitted_actions; + std::vector not_admitted_actions; }; } // namespace srsenb diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index bee0b9645..2ca91ee96 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -102,6 +102,87 @@ bool e2sm_kpm::process_subscription_request(asn1::e2ap::ricsubscription_request_ return true; } +bool e2sm_kpm::process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action) +{ + using namespace asn1::e2sm_kpm; + e2_sm_kpm_action_definition_s e2sm_kpm_action_def; + asn1::cbit_ref bref(ric_action.ric_action_definition.data(), ric_action.ric_action_definition.size()); + + uint64_t granul_period; + uint64_t eutra_cell_id; + uint64_t plmn_id; + ueid_c ue_id; + meas_info_list_l meas_info_list; + + if (e2sm_kpm_action_def.unpack(bref) != asn1::SRSASN_SUCCESS) { + return false; + } + + switch (e2sm_kpm_action_def.ric_style_type) { + case 1: + granul_period = e2sm_kpm_action_def.action_definition_formats.action_definition_format1().granul_period; + + if (granul_period == 0) { + logger.debug("Action granularity period of %i is not supported -> do not admitted action %i", + granul_period, + ric_action.ric_action_id); + return false; + } + + if (e2sm_kpm_action_def.action_definition_formats.action_definition_format1().cell_global_id_present) { + if (e2sm_kpm_action_def.action_definition_formats.action_definition_format1().cell_global_id.type() == + cgi_c::types_opts::eutra_cgi) { + eutra_cell_id = e2sm_kpm_action_def.action_definition_formats.action_definition_format1() + .cell_global_id.eutra_cgi() + .eutra_cell_id.to_number(); + plmn_id = e2sm_kpm_action_def.action_definition_formats.action_definition_format1() + .cell_global_id.eutra_cgi() + .plmn_id.to_number(); + logger.debug("plmn_id 0x%x, eutra_cell_id %i", plmn_id, eutra_cell_id); + // TODO: check if E2 node has cell_id and plmn_id + } + } + + meas_info_list = e2sm_kpm_action_def.action_definition_formats.action_definition_format1().meas_info_list; + for (uint32_t i = 0; i < meas_info_list.size(); i++) { + std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); + if (std::find(supported_meas_types.begin(), supported_meas_types.end(), meas_name.c_str()) == + supported_meas_types.end()) { + printf("Unsupported measurement name: %s --> do not admit action %i \n", + meas_name.c_str(), + ric_action.ric_action_id); + return false; + } + + printf("Admitted action: measurement name: %s with the following labels: \n", meas_name.c_str()); + for (uint32_t l = 0; l < meas_info_list[i].label_info_list.size(); l++) { + if (meas_info_list[i].label_info_list[l].meas_label.no_label_present) { + printf("--- Label %i: NO LABEL\n", i); + } + if (meas_info_list[i].label_info_list[l].meas_label.min_present) { + printf("--- Label %i: MIN\n", i); + } + if (meas_info_list[i].label_info_list[l].meas_label.max_present) { + printf("--- Label %i: MAX\n", i); + } + if (meas_info_list[i].label_info_list[l].meas_label.avg_present) { + printf("--- Label %i: AVG\n", i); + } + } + } + + break; + default: + logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", + e2sm_kpm_action_def.ric_style_type, + ric_action.ric_action_id, + ric_action.ric_action_type); + return false; + } + + return true; +} + bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf) { using namespace asn1::e2sm_kpm; diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 83099a1d2..d3692f862 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -37,6 +37,30 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli reporting_period = event_def.report_period; reporting_period = 1000; // TODO: to remove, keep it 1s for testing } + + ri_cactions_to_be_setup_list_l& action_list = + ric_subscription_request->ricsubscription_details->ric_action_to_be_setup_list; + + for (uint32_t i = 0; i < action_list.size(); i++) { + ri_caction_to_be_setup_item_s action_item = action_list[i]->ri_caction_to_be_setup_item(); + + if (sm_kpm_ptr->process_ric_action_definition(action_item)) { + parent->logger.debug("Admitted action %i (type: %i)\n", action_item.ric_action_id, action_item.ric_action_type); + admitted_actions.push_back(action_item.ric_action_id); + + if (action_item.ric_subsequent_action_present) { + parent->logger.debug("--Action %i (type: %i) contains subsequent action of type %i with wait time: %i\n", + action_item.ric_action_id, + action_item.ric_action_type, + action_item.ric_subsequent_action.ric_subsequent_action_type, + action_item.ric_subsequent_action.ric_time_to_wait); + } else { + parent->logger.debug( + "Not admitted action %i (type: %i)\n", action_item.ric_action_id, action_item.ric_action_type); + not_admitted_actions.push_back(action_item.ric_action_id); + } + } + } } void ric_client::ric_subscription::start_ric_indication_reporting() @@ -47,8 +71,13 @@ void ric_client::ric_subscription::start_ric_indication_reporting() ric_subscription_reponse.ric_instance_id = ric_instance_id; ric_subscription_reponse.ra_nfunction_id = ra_nfunction_id; - ric_subscription_reponse.admitted_actions.push_back(0); - ric_subscription_reponse.not_admitted_actions.push_back(10); + for (auto& action : admitted_actions) { + ric_subscription_reponse.admitted_actions.push_back(action); + } + + for (auto& action : not_admitted_actions) { + ric_subscription_reponse.not_admitted_actions.push_back(action); + } e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_response(ric_subscription_reponse); parent->queue_send_e2ap_pdu(send_pdu); From 2b5f393ea0e5f42cbf0bf2c1884a88ec9bd76881 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 13:45:20 +0100 Subject: [PATCH 047/167] e2sm: make process_ric_event_trigger_definition() virtual --- srsgnb/hdr/stack/ric/e2sm.h | 10 ++++++++++ srsgnb/hdr/stack/ric/e2sm_kpm.h | 8 ++------ srsgnb/src/stack/ric/e2sm_kpm.cc | 5 +++-- srsgnb/src/stack/ric/ric_subscription.cc | 14 ++++++++------ 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index 6a9826a5c..19179610a 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -10,6 +10,8 @@ * * */ + +#include "srsran/asn1/e2ap.h" #include "srsran/common/byte_buffer.h" #include "srsran/srsran.h" @@ -20,6 +22,12 @@ enum e2sm_type_t { E2SM_KPM, UNKNOWN }; struct RANfunction_description; +struct RIC_event_trigger_definition { + enum e2sm_event_trigger_type_t { E2SM_REPORT, E2SM_INSERT, E2SM_POLICY, UNKNOWN_TRIGGER }; + e2sm_event_trigger_type_t type; + uint64_t report_period; +}; + class e2sm { public: @@ -34,6 +42,8 @@ public: uint32_t get_revision() { return _revision; }; virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf) = 0; + virtual bool process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_request_s subscription_request, + RIC_event_trigger_definition& event_def) = 0; private: const std::string _short_name; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index fa0652d6e..fcacc8fa4 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -19,10 +19,6 @@ #ifndef RIC_E2SM_KPM_H #define RIC_E2SM_KPM_H -struct E2SM_KPM_RIC_event_definition { - uint64_t report_period; -}; - struct E2SM_KPM_RIC_ind_header { uint32_t collet_start_time; std::string file_formatversion; @@ -50,8 +46,8 @@ public: ~e2sm_kpm() = default; virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf); - bool process_subscription_request(asn1::e2ap::ricsubscription_request_s subscription_request, - E2SM_KPM_RIC_event_definition& event_def); + virtual bool process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_request_s subscription_request, + RIC_event_trigger_definition& event_def); bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action); bool generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf); bool generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 2ca91ee96..96a47da0c 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -86,8 +86,8 @@ bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, return true; } -bool e2sm_kpm::process_subscription_request(asn1::e2ap::ricsubscription_request_s subscription_request, - E2SM_KPM_RIC_event_definition& event_def) +bool e2sm_kpm::process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_request_s subscription_request, + RIC_event_trigger_definition& event_def) { using namespace asn1::e2sm_kpm; e2_sm_kpm_event_trigger_definition_s trigger_def; @@ -98,6 +98,7 @@ bool e2sm_kpm::process_subscription_request(asn1::e2ap::ricsubscription_request_ return false; } + event_def.type = RIC_event_trigger_definition::e2sm_event_trigger_type_t::E2SM_REPORT; event_def.report_period = trigger_def.event_definition_formats.event_definition_format1().report_period; return true; } diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index d3692f862..309a31f5c 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -22,7 +22,7 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli ric_instance_id(ric_subscription_request->ri_crequest_id->ric_instance_id), ra_nfunction_id(ric_subscription_request->ra_nfunction_id->value) { - reporting_timer = parent->task_sched.get_unique_timer(); + reporting_timer = parent->task_sched.get_unique_timer(); parent->e2ap_.process_subscription_request(ric_subscription_request); @@ -31,13 +31,15 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli return; } - E2SM_KPM_RIC_event_definition event_def; - e2sm_kpm* sm_kpm_ptr = dynamic_cast(ran_func_desc.sm_ptr); - if (sm_kpm_ptr->process_subscription_request(ric_subscription_request, event_def)) { - reporting_period = event_def.report_period; - reporting_period = 1000; // TODO: to remove, keep it 1s for testing + RIC_event_trigger_definition event_trigger; + if (ran_func_desc.sm_ptr->process_ric_event_trigger_definition(ric_subscription_request, event_trigger)) { + if (event_trigger.type == RIC_event_trigger_definition::e2sm_event_trigger_type_t::E2SM_REPORT) { + reporting_period = event_trigger.report_period; + reporting_period = 1000; // TODO: to remove, keep it 1s for testing + } } + e2sm_kpm* sm_kpm_ptr = dynamic_cast(ran_func_desc.sm_ptr); ri_cactions_to_be_setup_list_l& action_list = ric_subscription_request->ricsubscription_details->ric_action_to_be_setup_list; From 7f5edd521846aa1f9c1744eaf897f1f945cfbeab Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 13:48:00 +0100 Subject: [PATCH 048/167] e2sm: make process_ric_action_definition() virtual --- srsgnb/hdr/stack/ric/e2sm.h | 1 + srsgnb/hdr/stack/ric/e2sm_kpm.h | 2 +- srsgnb/src/stack/ric/ric_subscription.cc | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index 19179610a..e98fdc642 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -44,6 +44,7 @@ public: virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf) = 0; virtual bool process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_request_s subscription_request, RIC_event_trigger_definition& event_def) = 0; + virtual bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action) = 0; private: const std::string _short_name; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index fcacc8fa4..77b85f008 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -48,7 +48,7 @@ public: virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf); virtual bool process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_request_s subscription_request, RIC_event_trigger_definition& event_def); - bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action); + virtual bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action); bool generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf); bool generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf); diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 309a31f5c..09d212783 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -39,14 +39,13 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli } } - e2sm_kpm* sm_kpm_ptr = dynamic_cast(ran_func_desc.sm_ptr); ri_cactions_to_be_setup_list_l& action_list = ric_subscription_request->ricsubscription_details->ric_action_to_be_setup_list; for (uint32_t i = 0; i < action_list.size(); i++) { ri_caction_to_be_setup_item_s action_item = action_list[i]->ri_caction_to_be_setup_item(); - if (sm_kpm_ptr->process_ric_action_definition(action_item)) { + if (ran_func_desc.sm_ptr->process_ric_action_definition(action_item)) { parent->logger.debug("Admitted action %i (type: %i)\n", action_item.ric_action_id, action_item.ric_action_type); admitted_actions.push_back(action_item.ric_action_id); From 406ca4ac12282dc052129239af1803f1e6967d45 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 13:51:30 +0100 Subject: [PATCH 049/167] e2ap: change func names --- srsgnb/hdr/stack/ric/ric_subscription.h | 4 ++-- srsgnb/src/stack/ric/ric_client.cc | 4 ++-- srsgnb/src/stack/ric/ric_subscription.cc | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index adbec6e14..1f6b55797 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -31,8 +31,8 @@ public: uint32_t get_ric_requestor_id() { return ric_requestor_id; }; uint32_t get_ric_instance_id() { return ric_instance_id; }; - void start_ric_indication_reporting(); - void stop_ric_indication_reporting(); + void start_subscription(); + void delete_subscription(); private: void send_ric_indication(); diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 7d5658bee..8765d0111 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -272,7 +272,7 @@ bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_s std::unique_ptr new_ric_subs = std::make_unique(this, ric_subscription_request); - new_ric_subs->start_ric_indication_reporting(); + new_ric_subs->start_subscription(); active_subscriptions.push_back(std::move(new_ric_subs)); return true; } @@ -289,7 +289,7 @@ bool ric_client::handle_ric_subscription_delete_request(ricsubscription_delete_r if ((**it).get_ric_requestor_id() == ricsubscription_delete_request->ri_crequest_id->ric_requestor_id and (**it).get_ric_instance_id() == ricsubscription_delete_request->ri_crequest_id->ric_instance_id) { ric_subs_found = true; - (**it).stop_ric_indication_reporting(); + (**it).delete_subscription(); active_subscriptions.erase(it); break; } diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 09d212783..0060f3ac8 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -64,7 +64,7 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli } } -void ric_client::ric_subscription::start_ric_indication_reporting() +void ric_client::ric_subscription::start_subscription() { parent->logger.debug("Send RIC Subscription Response to RIC Requestor ID: %i\n", ric_requestor_id); ric_subscription_reponse_t ric_subscription_reponse; @@ -91,7 +91,7 @@ void ric_client::ric_subscription::start_ric_indication_reporting() } } -void ric_client::ric_subscription::stop_ric_indication_reporting() +void ric_client::ric_subscription::delete_subscription() { if (reporting_timer.is_running()) { parent->logger.debug("Stop sending RIC indication msgs"); From d1ba988e27298b0307e159662d88acd7e6856ae7 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 14:20:41 +0100 Subject: [PATCH 050/167] e2ap: register actions is SM --- srsgnb/hdr/stack/ric/e2sm.h | 15 +++++++++- srsgnb/hdr/stack/ric/e2sm_kpm.h | 5 +++- srsgnb/hdr/stack/ric/ric_subscription.h | 4 +-- srsgnb/src/stack/ric/e2sm_kpm.cc | 16 +++++++++-- srsgnb/src/stack/ric/ric_subscription.cc | 35 ++++++++++++++++++++---- 5 files changed, 63 insertions(+), 12 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index e98fdc642..280a50b93 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -28,6 +28,12 @@ struct RIC_event_trigger_definition { uint64_t report_period; }; +struct E2AP_RIC_action { + uint16_t ric_action_id; + asn1::e2ap::ri_caction_type_e ric_action_type; + uint32_t sm_local_ric_action_id; +}; + class e2sm { public: @@ -44,13 +50,20 @@ public: virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf) = 0; virtual bool process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_request_s subscription_request, RIC_event_trigger_definition& event_def) = 0; - virtual bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action) = 0; + virtual bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action, + E2AP_RIC_action& action_entry) = 0; + virtual bool remove_ric_action_definition(E2AP_RIC_action& action_entry) = 0; + +protected: + uint32_t _generate_local_action_id() { return _registered_action_id_gen++; }; private: const std::string _short_name; const std::string _oid; const std::string _func_description; const uint32_t _revision; + + uint32_t _registered_action_id_gen = 1000; }; struct RANfunction_description { diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 77b85f008..4040c6406 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -48,13 +48,16 @@ public: virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf); virtual bool process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_request_s subscription_request, RIC_event_trigger_definition& event_def); - virtual bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action); + virtual bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action, + E2AP_RIC_action& action_entry); + virtual bool remove_ric_action_definition(E2AP_RIC_action& action_entry); bool generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf); bool generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf); private: srslog::basic_logger& logger; std::vector supported_meas_types; + std::map registered_actions; }; #endif /*E2SM_KPM*/ diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index 1f6b55797..701fc508e 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -45,9 +45,9 @@ private: uint16_t ri_caction_id; uint32_t reporting_period = 0; // ms - srsran::unique_timer reporting_timer; // for RIC indication reporting + srsran::unique_timer reporting_timer; // for RIC indication reporting - std::vector admitted_actions; + std::vector admitted_actions; std::vector not_admitted_actions; }; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 96a47da0c..7b783d517 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -103,7 +103,8 @@ bool e2sm_kpm::process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_ return true; } -bool e2sm_kpm::process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action) +bool e2sm_kpm::process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action, + E2AP_RIC_action& action_entry) { using namespace asn1::e2sm_kpm; e2_sm_kpm_action_definition_s e2sm_kpm_action_def; @@ -171,7 +172,9 @@ bool e2sm_kpm::process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_ } } } - + action_entry.sm_local_ric_action_id = _generate_local_action_id(); + registered_actions.insert(std::pair( + action_entry.sm_local_ric_action_id, e2sm_kpm_action_def)); break; default: logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", @@ -184,6 +187,15 @@ bool e2sm_kpm::process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_ return true; } +bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action& action_entry) +{ + if (registered_actions.count(action_entry.sm_local_ric_action_id)) { + registered_actions.erase(action_entry.sm_local_ric_action_id); + return true; + } + return false; +} + bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf) { using namespace asn1::e2sm_kpm; diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 0060f3ac8..145d1170d 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -28,6 +28,7 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli RANfunction_description ran_func_desc; if (!parent->e2ap_.get_func_desc(ra_nfunction_id, ran_func_desc)) { + parent->logger.debug("Cannot find RAN function with ID: %i\n", ra_nfunction_id); return; } @@ -45,19 +46,31 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli for (uint32_t i = 0; i < action_list.size(); i++) { ri_caction_to_be_setup_item_s action_item = action_list[i]->ri_caction_to_be_setup_item(); - if (ran_func_desc.sm_ptr->process_ric_action_definition(action_item)) { - parent->logger.debug("Admitted action %i (type: %i)\n", action_item.ric_action_id, action_item.ric_action_type); - admitted_actions.push_back(action_item.ric_action_id); + E2AP_RIC_action admitted_action; + admitted_action.ric_action_id = action_item.ric_action_id; + admitted_action.ric_action_type = action_item.ric_action_type; + + if (ran_func_desc.sm_ptr->process_ric_action_definition(action_item, admitted_action)) { + parent->logger.debug("Admitted action %i (type: %i), mapped to SM local action ID: %i", + admitted_action.ric_action_id, + admitted_action.ric_action_type, + admitted_action.sm_local_ric_action_id); + + printf("Admitted action %i, mapped to SM local action ID: %i\n", + action_item.ric_action_id, + admitted_action.sm_local_ric_action_id); + + admitted_actions.push_back(admitted_action); if (action_item.ric_subsequent_action_present) { - parent->logger.debug("--Action %i (type: %i) contains subsequent action of type %i with wait time: %i\n", + parent->logger.debug("--Action %i (type: %i) contains subsequent action of type %i with wait time: %i", action_item.ric_action_id, action_item.ric_action_type, action_item.ric_subsequent_action.ric_subsequent_action_type, action_item.ric_subsequent_action.ric_time_to_wait); } else { parent->logger.debug( - "Not admitted action %i (type: %i)\n", action_item.ric_action_id, action_item.ric_action_type); + "Not admitted action %i (type: %i)", action_item.ric_action_id, action_item.ric_action_type); not_admitted_actions.push_back(action_item.ric_action_id); } } @@ -73,7 +86,7 @@ void ric_client::ric_subscription::start_subscription() ric_subscription_reponse.ra_nfunction_id = ra_nfunction_id; for (auto& action : admitted_actions) { - ric_subscription_reponse.admitted_actions.push_back(action); + ric_subscription_reponse.admitted_actions.push_back(action.ric_action_id); } for (auto& action : not_admitted_actions) { @@ -98,6 +111,16 @@ void ric_client::ric_subscription::delete_subscription() reporting_timer.stop(); } + // remove registered actions from SM + RANfunction_description ran_func_desc; + if (!parent->e2ap_.get_func_desc(ra_nfunction_id, ran_func_desc)) { + parent->logger.debug("Cannot find RAN function with ID: %i\n", ra_nfunction_id); + return; + } + for (auto& action : admitted_actions) { + ran_func_desc.sm_ptr->remove_ric_action_definition(action); + } + parent->logger.debug("Send RIC Subscription Delete Response to RIC Requestor ID: %i\n", ric_requestor_id); e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_delete_response(ric_requestor_id, ric_instance_id, ra_nfunction_id); From 9ea0f2684a644e2801650aa29b34804a3fa80db6 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 14:28:35 +0100 Subject: [PATCH 051/167] e2ap: store sm_ptr in ric_subscription --- srsgnb/hdr/stack/ric/ric_subscription.h | 3 ++- srsgnb/src/stack/ric/ric_subscription.cc | 29 +++++++++++------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index 701fc508e..9b4c873af 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -44,11 +44,12 @@ private: uint16_t ra_nfunction_id; uint16_t ri_caction_id; + e2sm* sm_ptr = nullptr; uint32_t reporting_period = 0; // ms srsran::unique_timer reporting_timer; // for RIC indication reporting std::vector admitted_actions; - std::vector not_admitted_actions; + std::vector not_admitted_actions; }; } // namespace srsenb diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 145d1170d..f06f5aa88 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -32,8 +32,14 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli return; } + sm_ptr = ran_func_desc.sm_ptr; + if (sm_ptr == nullptr) { + parent->logger.debug("No valid pointer to SM with RAN function id: %i\n", ra_nfunction_id); + return; + } + RIC_event_trigger_definition event_trigger; - if (ran_func_desc.sm_ptr->process_ric_event_trigger_definition(ric_subscription_request, event_trigger)) { + if (sm_ptr->process_ric_event_trigger_definition(ric_subscription_request, event_trigger)) { if (event_trigger.type == RIC_event_trigger_definition::e2sm_event_trigger_type_t::E2SM_REPORT) { reporting_period = event_trigger.report_period; reporting_period = 1000; // TODO: to remove, keep it 1s for testing @@ -50,7 +56,7 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli admitted_action.ric_action_id = action_item.ric_action_id; admitted_action.ric_action_type = action_item.ric_action_type; - if (ran_func_desc.sm_ptr->process_ric_action_definition(action_item, admitted_action)) { + if (sm_ptr->process_ric_action_definition(action_item, admitted_action)) { parent->logger.debug("Admitted action %i (type: %i), mapped to SM local action ID: %i", admitted_action.ric_action_id, admitted_action.ric_action_type, @@ -112,13 +118,10 @@ void ric_client::ric_subscription::delete_subscription() } // remove registered actions from SM - RANfunction_description ran_func_desc; - if (!parent->e2ap_.get_func_desc(ra_nfunction_id, ran_func_desc)) { - parent->logger.debug("Cannot find RAN function with ID: %i\n", ra_nfunction_id); - return; - } - for (auto& action : admitted_actions) { - ran_func_desc.sm_ptr->remove_ric_action_definition(action); + if (sm_ptr) { + for (auto& action : admitted_actions) { + sm_ptr->remove_ric_action_definition(action); + } } parent->logger.debug("Send RIC Subscription Delete Response to RIC Requestor ID: %i\n", ric_requestor_id); @@ -137,13 +140,7 @@ void ric_client::ric_subscription::send_ric_indication() ric_indication.ri_caction_id = ri_caction_id; ric_indication.indication_type = ri_cind_type_opts::report; - RANfunction_description ran_func_desc; - e2sm* sm_ptr = nullptr; - if (!parent->e2ap_.get_func_desc(ra_nfunction_id, ran_func_desc)) { - return; - } - - e2sm_kpm* sm_kpm_ptr = dynamic_cast(ran_func_desc.sm_ptr); + e2sm_kpm* sm_kpm_ptr = dynamic_cast(sm_ptr); E2SM_KPM_RIC_ind_header ric_ind_header; ric_ind_header.collet_start_time = 0x12345; From 5e4e13df09c23964770801740aea0f4671293b27 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 14:29:33 +0100 Subject: [PATCH 052/167] e2ap: clean e2ap_.process_subscription_request --- srsgnb/src/stack/ric/e2ap.cc | 9 +-------- srsgnb/src/stack/ric/ric_subscription.cc | 2 -- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index b7fa254d9..7f3e0b723 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -163,14 +163,7 @@ int e2ap::process_setup_response(e2setup_resp_s setup_response) int e2ap::process_subscription_request(ricsubscription_request_s subscription_request) { pending_subscription_request = true; - - uint16_t ran_func_id = subscription_request->ra_nfunction_id->value; - if (ran_functions.count(ran_func_id)) { - // TODO handle RIC subscription request - } - - // TODO handle RIC subscription request - + // TODO: this function seems to be not needed return 0; } diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index f06f5aa88..1db857080 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -24,8 +24,6 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli { reporting_timer = parent->task_sched.get_unique_timer(); - parent->e2ap_.process_subscription_request(ric_subscription_request); - RANfunction_description ran_func_desc; if (!parent->e2ap_.get_func_desc(ra_nfunction_id, ran_func_desc)) { parent->logger.debug("Cannot find RAN function with ID: %i\n", ra_nfunction_id); From 48a7dd546ff4e621e1ddae5d0cfc52a7066e64c4 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 15:14:59 +0100 Subject: [PATCH 053/167] e2sm: move RIC content generation to SM --- srsgnb/hdr/stack/ric/e2ap.h | 11 ------ srsgnb/hdr/stack/ric/e2sm.h | 15 +++++++- srsgnb/hdr/stack/ric/e2sm_kpm.h | 2 + srsgnb/hdr/stack/ric/ric_subscription.h | 1 - srsgnb/src/stack/ric/e2sm_kpm.cc | 35 +++++++++++++++++ srsgnb/src/stack/ric/ric_subscription.cc | 48 +++++++----------------- 6 files changed, 64 insertions(+), 48 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 633a58bad..83074787b 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -13,7 +13,6 @@ #include "e2sm_kpm.h" #include "srsran/asn1/e2ap.h" -#include "srsran/asn1/e2sm_kpm_v2.h" #include "srsran/interfaces/e2_metrics_interface.h" #include "srsran/interfaces/enb_metrics_interface.h" #include "srsran/srsran.h" @@ -44,16 +43,6 @@ typedef struct { std::vector not_admitted_actions; } ric_subscription_reponse_t; -typedef struct { - uint32_t ric_requestor_id; - uint32_t ric_instance_id; - uint32_t ra_nfunction_id; - uint32_t ri_caction_id; - ri_cind_type_e indication_type; - srsran::unique_byte_buffer_t ri_cind_hdr; - srsran::unique_byte_buffer_t ri_cind_msg; -} ric_indication_t; - class e2ap { public: diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index 280a50b93..f34b9532e 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -34,6 +34,16 @@ struct E2AP_RIC_action { uint32_t sm_local_ric_action_id; }; +typedef struct { + uint32_t ric_requestor_id; + uint32_t ric_instance_id; + uint32_t ra_nfunction_id; + uint32_t ri_caction_id; + asn1::e2ap::ri_cind_type_e indication_type; + srsran::unique_byte_buffer_t ri_cind_hdr; + srsran::unique_byte_buffer_t ri_cind_msg; +} ric_indication_t; + class e2sm { public: @@ -51,8 +61,9 @@ public: virtual bool process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_request_s subscription_request, RIC_event_trigger_definition& event_def) = 0; virtual bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action, - E2AP_RIC_action& action_entry) = 0; - virtual bool remove_ric_action_definition(E2AP_RIC_action& action_entry) = 0; + E2AP_RIC_action& action_entry) = 0; + virtual bool remove_ric_action_definition(E2AP_RIC_action& action_entry) = 0; + virtual bool execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_indication_t& ric_indication) = 0; protected: uint32_t _generate_local_action_id() { return _registered_action_id_gen++; }; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 4040c6406..f62a0dd0a 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -51,6 +51,8 @@ public: virtual bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action& action_entry); virtual bool remove_ric_action_definition(E2AP_RIC_action& action_entry); + virtual bool execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_indication_t& ric_indication); + bool generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf); bool generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf); diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index 9b4c873af..49b3ea6c0 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -42,7 +42,6 @@ private: uint32_t ric_requestor_id; uint32_t ric_instance_id; uint16_t ra_nfunction_id; - uint16_t ri_caction_id; e2sm* sm_ptr = nullptr; uint32_t reporting_period = 0; // ms diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 7b783d517..acc5d6c4e 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -196,6 +196,41 @@ bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action& action_entry) return false; } +bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_indication_t& ric_indication) +{ + using namespace asn1::e2ap; + using namespace asn1::e2sm_kpm; + + ric_indication.indication_type = ri_cind_type_opts::report; + + E2SM_KPM_RIC_ind_header ric_ind_header; + ric_ind_header.collet_start_time = 0x12345; + ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); + this->generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); + + E2SM_KPM_RIC_ind_message ric_ind_message; + ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + + ric_ind_message.meas_data.resize(1); + ric_ind_message.meas_data[0].meas_record.resize(5); + for (uint32_t i = 0; i < ric_ind_message.meas_data[0].meas_record.size(); i++) { + ric_ind_message.meas_data[0].meas_record[i].set_integer() = i * 1000; + } + + ric_ind_message.meas_info_list.resize(1); + ric_ind_message.meas_info_list[0].meas_type.set_meas_name().from_string("RRU.PrbTotDl"); + ric_ind_message.meas_info_list[0].label_info_list.resize(1); + ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label_present = true; + ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label = + asn1::e2sm_kpm::meas_label_s::no_label_opts::true_value; + + // ric_ind_message.granul_period = 12345; // not implemented by flexric and crashes it + + ric_indication.ri_cind_msg = srsran::make_byte_buffer(); + this->generate_indication_message(ric_ind_message, ric_indication.ri_cind_msg); + return true; +} + bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf) { using namespace asn1::e2sm_kpm; diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 1db857080..7b69f8aeb 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -130,44 +130,24 @@ void ric_client::ric_subscription::delete_subscription() void ric_client::ric_subscription::send_ric_indication() { - printf("Sending RIC indication msg to RIC Requestor ID: %i\n", ric_requestor_id); - ric_indication_t ric_indication; - ric_indication.ric_requestor_id = ric_requestor_id; - ric_indication.ric_instance_id = ric_instance_id; - ric_indication.ra_nfunction_id = ra_nfunction_id; - ric_indication.ri_caction_id = ri_caction_id; - ric_indication.indication_type = ri_cind_type_opts::report; - - e2sm_kpm* sm_kpm_ptr = dynamic_cast(sm_ptr); - - E2SM_KPM_RIC_ind_header ric_ind_header; - ric_ind_header.collet_start_time = 0x12345; - ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); - sm_kpm_ptr->generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); - - E2SM_KPM_RIC_ind_message ric_ind_message; - ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; - - ric_ind_message.meas_data.resize(1); - ric_ind_message.meas_data[0].meas_record.resize(5); - for (uint32_t i = 0; i < ric_ind_message.meas_data[0].meas_record.size(); i++) { - ric_ind_message.meas_data[0].meas_record[i].set_integer() = i * 1000; + if (sm_ptr == nullptr) { + parent->logger.error("SM pointer not set in subscription: %i\n", ric_requestor_id); + return; } - ric_ind_message.meas_info_list.resize(1); - ric_ind_message.meas_info_list[0].meas_type.set_meas_name().from_string("RRU.PrbTotDl"); - ric_ind_message.meas_info_list[0].label_info_list.resize(1); - ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label_present = true; - ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label = - asn1::e2sm_kpm::meas_label_s::no_label_opts::true_value; - - // ric_ind_message.granul_period = 12345; // not implemented by flexric and crashes it + for (auto& action : admitted_actions) { + printf("Sending RIC indication msg to RIC Requestor ID: %i\n", ric_requestor_id); + ric_indication_t ric_indication; + ric_indication.ric_requestor_id = ric_requestor_id; + ric_indication.ric_instance_id = ric_instance_id; + ric_indication.ra_nfunction_id = ra_nfunction_id; + ric_indication.ri_caction_id = action.ric_action_id; - ric_indication.ri_cind_msg = srsran::make_byte_buffer(); - sm_kpm_ptr->generate_indication_message(ric_ind_message, ric_indication.ri_cind_msg); + sm_ptr->execute_action_fill_ric_indication(action, ric_indication); - e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(ric_indication); - parent->queue_send_e2ap_pdu(send_pdu); + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(ric_indication); + parent->queue_send_e2ap_pdu(send_pdu); + } // reschedule sending RIC indication reporting_timer.run(); From 6531f761ff646071ac26c99116dbcb46b91a1bad Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 15:20:44 +0100 Subject: [PATCH 054/167] e2ap: fix bug --- srsgnb/src/stack/ric/ric_subscription.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 7b69f8aeb..4106e4566 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -72,11 +72,10 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli action_item.ric_action_type, action_item.ric_subsequent_action.ric_subsequent_action_type, action_item.ric_subsequent_action.ric_time_to_wait); - } else { - parent->logger.debug( - "Not admitted action %i (type: %i)", action_item.ric_action_id, action_item.ric_action_type); - not_admitted_actions.push_back(action_item.ric_action_id); } + } else { + parent->logger.debug("Not admitted action %i (type: %i)", action_item.ric_action_id, action_item.ric_action_type); + not_admitted_actions.push_back(action_item.ric_action_id); } } } From 433e4b3ac1a01acbc0c817e67e20a9fb3e4cb0aa Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 15:24:34 +0100 Subject: [PATCH 055/167] e2ap: ric_subscription clean ctor --- srsgnb/src/stack/ric/ric_subscription.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 4106e4566..7cc1eb250 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -20,10 +20,9 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli parent(ric_client), ric_requestor_id(ric_subscription_request->ri_crequest_id->ric_requestor_id), ric_instance_id(ric_subscription_request->ri_crequest_id->ric_instance_id), - ra_nfunction_id(ric_subscription_request->ra_nfunction_id->value) + ra_nfunction_id(ric_subscription_request->ra_nfunction_id->value), + reporting_timer(parent->task_sched.get_unique_timer()) { - reporting_timer = parent->task_sched.get_unique_timer(); - RANfunction_description ran_func_desc; if (!parent->e2ap_.get_func_desc(ra_nfunction_id, ran_func_desc)) { parent->logger.debug("Cannot find RAN function with ID: %i\n", ra_nfunction_id); From 027590b85859f4ac4e3bec9243eff5ed05936d0e Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 15:47:12 +0100 Subject: [PATCH 056/167] e2ap: ric_subscription add subscription_failure --- srsgnb/hdr/stack/ric/e2ap.h | 2 +- srsgnb/hdr/stack/ric/ric_subscription.h | 5 ++++- srsgnb/src/stack/ric/e2ap.cc | 23 +++++++++++++++++++++++ srsgnb/src/stack/ric/ric_client.cc | 11 +++++++++-- srsgnb/src/stack/ric/ric_subscription.cc | 14 ++++++++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 83074787b..d38b0474d 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -52,7 +52,7 @@ public: int process_setup_failure(); int process_subscription_request(ricsubscription_request_s subscription_request); e2_ap_pdu_c generate_subscription_response(ric_subscription_reponse_t ric_subscription_reponse); - int generate_subscription_failure(); + e2_ap_pdu_c generate_subscription_failure(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_subscription_delete_response(uint32_t ric_requestor_id, uint32_t ric_instance_id, uint32_t ra_nfunction_id); e2_ap_pdu_c generate_indication(ric_indication_t& ric_indication); diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index 49b3ea6c0..a9bd4bf35 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -30,14 +30,17 @@ public: uint32_t get_ric_requestor_id() { return ric_requestor_id; }; uint32_t get_ric_instance_id() { return ric_instance_id; }; + bool is_initialized() { return initialized; }; void start_subscription(); + void send_subscription_failure(); void delete_subscription(); private: void send_ric_indication(); - ric_client* parent = nullptr; + ric_client* parent = nullptr; + bool initialized = false; uint32_t ric_requestor_id; uint32_t ric_instance_id; diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 7f3e0b723..6cd388d4b 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -115,6 +115,29 @@ e2_ap_pdu_c e2ap::generate_subscription_response(ric_subscription_reponse_t ric_ return pdu; } +e2_ap_pdu_c e2ap::generate_subscription_failure(ric_subscription_reponse_t ric_subscription_reponse) +{ + e2_ap_pdu_c pdu; + unsuccessful_outcome_s& failure = pdu.set_unsuccessful_outcome(); + failure.load_info_obj(ASN1_E2AP_ID_RICSUBSCRIPTION); + failure.crit = asn1::crit_opts::reject; + ricsubscription_fail_s& sub_resp = failure.value.ricsubscription_fail(); + + sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; + sub_resp->ri_crequest_id.id = ASN1_E2AP_ID_RI_CREQUEST_ID; + sub_resp->ri_crequest_id.value.ric_requestor_id = ric_subscription_reponse.ric_requestor_id; + sub_resp->ri_crequest_id.value.ric_instance_id = ric_subscription_reponse.ric_instance_id; + + sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; + sub_resp->ra_nfunction_id.id = ASN1_E2AP_ID_RA_NFUNCTION_ID; + sub_resp->ra_nfunction_id->value = ric_subscription_reponse.ra_nfunction_id; + + sub_resp->cause->set_misc(); // TODO: set the cause and crit_diagnostics properly + sub_resp->crit_diagnostics_present = false; + + return pdu; +} + e2_ap_pdu_c e2ap::generate_subscription_delete_response(uint32_t ric_requestor_id, uint32_t ric_instance_id, uint32_t ra_nfunction_id) diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 8765d0111..b0a5de1db 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -272,8 +272,15 @@ bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_s std::unique_ptr new_ric_subs = std::make_unique(this, ric_subscription_request); - new_ric_subs->start_subscription(); - active_subscriptions.push_back(std::move(new_ric_subs)); + + if (new_ric_subs->is_initialized()) { + new_ric_subs->start_subscription(); + active_subscriptions.push_back(std::move(new_ric_subs)); + } else { + new_ric_subs->send_subscription_failure(); + return false; + } + return true; } diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 7cc1eb250..7d19b4eb4 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -18,6 +18,7 @@ namespace srsenb { ric_client::ric_subscription::ric_subscription(ric_client* ric_client, ricsubscription_request_s ric_subscription_request) : parent(ric_client), + initialized(false), ric_requestor_id(ric_subscription_request->ri_crequest_id->ric_requestor_id), ric_instance_id(ric_subscription_request->ri_crequest_id->ric_instance_id), ra_nfunction_id(ric_subscription_request->ra_nfunction_id->value), @@ -77,6 +78,7 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli not_admitted_actions.push_back(action_item.ric_action_id); } } + initialized = true; } void ric_client::ric_subscription::start_subscription() @@ -106,6 +108,18 @@ void ric_client::ric_subscription::start_subscription() } } +void ric_client::ric_subscription::send_subscription_failure() +{ + parent->logger.debug("Send RIC Subscription Failure Response to RIC Requestor ID: %i\n", ric_requestor_id); + ric_subscription_reponse_t ric_subscription_reponse; + ric_subscription_reponse.ric_requestor_id = ric_requestor_id; + ric_subscription_reponse.ric_instance_id = ric_instance_id; + ric_subscription_reponse.ra_nfunction_id = ra_nfunction_id; + + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_failure(ric_subscription_reponse); + parent->queue_send_e2ap_pdu(send_pdu); +} + void ric_client::ric_subscription::delete_subscription() { if (reporting_timer.is_running()) { From 372a543bf5f2dddcec46c74c2022aef1d4ccdb6b Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 15:47:39 +0100 Subject: [PATCH 057/167] e2ap: ric_subscription reschedule only if positive reporting_period --- srsgnb/src/stack/ric/ric_subscription.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 7d19b4eb4..c425498cb 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -162,7 +162,9 @@ void ric_client::ric_subscription::send_ric_indication() } // reschedule sending RIC indication - reporting_timer.run(); + if (reporting_period) { + reporting_timer.run(); + } } } // namespace srsenb \ No newline at end of file From 4d48c389782d57f34200e746b48ba2eb5f58ef32 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 15:56:49 +0100 Subject: [PATCH 058/167] e2sm_kpm: use asn1 namespaces --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 28 +++++++++++++++------------- srsgnb/src/stack/ric/e2sm_kpm.cc | 30 ++++++++++-------------------- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index f62a0dd0a..7bc8a19d1 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -19,6 +19,9 @@ #ifndef RIC_E2SM_KPM_H #define RIC_E2SM_KPM_H +using namespace asn1::e2ap; +using namespace asn1::e2sm_kpm; + struct E2SM_KPM_RIC_ind_header { uint32_t collet_start_time; std::string file_formatversion; @@ -28,10 +31,10 @@ struct E2SM_KPM_RIC_ind_header { }; struct E2SM_KPM_RIC_ind_message { - asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types ind_msg_format; - asn1::e2sm_kpm::meas_data_l meas_data; - asn1::e2sm_kpm::meas_info_list_l meas_info_list; - uint64_t granul_period = 0; + e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types ind_msg_format; + meas_data_l meas_data; + meas_info_list_l meas_info_list; + uint64_t granul_period = 0; }; class e2sm_kpm : public e2sm @@ -46,20 +49,19 @@ public: ~e2sm_kpm() = default; virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf); - virtual bool process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_request_s subscription_request, - RIC_event_trigger_definition& event_def); - virtual bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action, - E2AP_RIC_action& action_entry); + virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, + RIC_event_trigger_definition& event_def); + virtual bool process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action& action_entry); virtual bool remove_ric_action_definition(E2AP_RIC_action& action_entry); virtual bool execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_indication_t& ric_indication); - bool generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf); - bool generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf); + bool generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf); + bool generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf); private: - srslog::basic_logger& logger; - std::vector supported_meas_types; - std::map registered_actions; + srslog::basic_logger& logger; + std::vector supported_meas_types; + std::map registered_actions; }; #endif /*E2SM_KPM*/ diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index acc5d6c4e..731087171 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -14,7 +14,6 @@ e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_d 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; @@ -86,10 +85,9 @@ bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, return true; } -bool e2sm_kpm::process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_request_s subscription_request, - RIC_event_trigger_definition& event_def) +bool e2sm_kpm::process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, + RIC_event_trigger_definition& event_def) { - using namespace asn1::e2sm_kpm; e2_sm_kpm_event_trigger_definition_s trigger_def; asn1::cbit_ref bref(subscription_request->ricsubscription_details->ric_event_trigger_definition.data(), subscription_request->ricsubscription_details->ric_event_trigger_definition.size()); @@ -103,10 +101,8 @@ bool e2sm_kpm::process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_ return true; } -bool e2sm_kpm::process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action, - E2AP_RIC_action& action_entry) +bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action& action_entry) { - using namespace asn1::e2sm_kpm; e2_sm_kpm_action_definition_s e2sm_kpm_action_def; asn1::cbit_ref bref(ric_action.ric_action_definition.data(), ric_action.ric_action_definition.size()); @@ -173,8 +169,8 @@ bool e2sm_kpm::process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_ } } action_entry.sm_local_ric_action_id = _generate_local_action_id(); - registered_actions.insert(std::pair( - action_entry.sm_local_ric_action_id, e2sm_kpm_action_def)); + registered_actions.insert( + std::pair(action_entry.sm_local_ric_action_id, e2sm_kpm_action_def)); break; default: logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", @@ -198,9 +194,6 @@ bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action& action_entry) bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_indication_t& ric_indication) { - using namespace asn1::e2ap; - using namespace asn1::e2sm_kpm; - ric_indication.indication_type = ri_cind_type_opts::report; E2SM_KPM_RIC_ind_header ric_ind_header; @@ -221,8 +214,7 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_ind_message.meas_info_list[0].meas_type.set_meas_name().from_string("RRU.PrbTotDl"); ric_ind_message.meas_info_list[0].label_info_list.resize(1); ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label_present = true; - ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label = - asn1::e2sm_kpm::meas_label_s::no_label_opts::true_value; + ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label = meas_label_s::no_label_opts::true_value; // ric_ind_message.granul_period = 12345; // not implemented by flexric and crashes it @@ -233,7 +225,6 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf) { - using namespace asn1::e2sm_kpm; e2_sm_kpm_ind_hdr_s e2_sm_kpm_ind_hdr; e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().collet_start_time.from_number(hdr.collet_start_time); e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().file_formatversion.from_string(hdr.file_formatversion); @@ -253,11 +244,10 @@ bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::u bool e2sm_kpm::generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf) { - using namespace asn1::e2sm_kpm; e2_sm_kpm_ind_msg_s e2_sm_kpm_ind_msg; switch (msg.ind_msg_format) { - case asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format1: + case e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format1: e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format1(); e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_data = msg.meas_data; e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_info_list = msg.meas_info_list; @@ -268,15 +258,15 @@ bool e2sm_kpm::generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran: } break; - case asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format2: + case e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format2: e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format2(); // TODO: support format2 break; - case asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format3: + case e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format3: e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format3(); // TODO: support format3 break; - case asn1::e2sm_kpm::e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::nulltype: + case e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::nulltype: break; default: log_invalid_choice_id(msg.ind_msg_format, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); From a5d8758fb81cc5fc7ea76ad92015967b384c7624 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 16:01:23 +0100 Subject: [PATCH 059/167] e2sm: use asn1 namespaces --- srsgnb/hdr/stack/ric/e2sm.h | 19 +++++++++---------- srsgnb/src/stack/ric/e2ap.cc | 1 - 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index f34b9532e..da76e7c03 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -18,7 +18,7 @@ #ifndef SRSRAN_E2SM_H #define SRSRAN_E2SM_H -enum e2sm_type_t { E2SM_KPM, UNKNOWN }; +using namespace asn1::e2ap; struct RANfunction_description; @@ -29,9 +29,9 @@ struct RIC_event_trigger_definition { }; struct E2AP_RIC_action { - uint16_t ric_action_id; - asn1::e2ap::ri_caction_type_e ric_action_type; - uint32_t sm_local_ric_action_id; + uint16_t ric_action_id; + ri_caction_type_e ric_action_type; + uint32_t sm_local_ric_action_id; }; typedef struct { @@ -39,7 +39,7 @@ typedef struct { uint32_t ric_instance_id; uint32_t ra_nfunction_id; uint32_t ri_caction_id; - asn1::e2ap::ri_cind_type_e indication_type; + ri_cind_type_e indication_type; srsran::unique_byte_buffer_t ri_cind_hdr; srsran::unique_byte_buffer_t ri_cind_msg; } ric_indication_t; @@ -58,10 +58,10 @@ public: uint32_t get_revision() { return _revision; }; virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf) = 0; - virtual bool process_ric_event_trigger_definition(asn1::e2ap::ricsubscription_request_s subscription_request, - RIC_event_trigger_definition& event_def) = 0; - virtual bool process_ric_action_definition(asn1::e2ap::ri_caction_to_be_setup_item_s ric_action, - E2AP_RIC_action& action_entry) = 0; + virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, + RIC_event_trigger_definition& event_def) = 0; + virtual bool process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, + E2AP_RIC_action& action_entry) = 0; virtual bool remove_ric_action_definition(E2AP_RIC_action& action_entry) = 0; virtual bool execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_indication_t& ric_indication) = 0; @@ -80,7 +80,6 @@ private: 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; diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 6cd388d4b..82ef1efa2 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -10,7 +10,6 @@ e2ap::e2ap(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metr uint32_t local_ran_function_id = 147; RANfunction_description 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; } From 67c5b50c53c5aa2fa1c83e5eeb44d5ffef4f7e0a Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 17:39:37 +0100 Subject: [PATCH 060/167] e2sm_kpm: improve ric indication generation --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 4 ++ srsgnb/src/stack/ric/e2sm_kpm.cc | 100 ++++++++++++++++++++++++------- 2 files changed, 84 insertions(+), 20 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 7bc8a19d1..ce1b9d5b0 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -59,9 +59,13 @@ public: bool generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf); private: + void _fill_measurement_records(std::string meas_name, std::string label, meas_record_l& meas_record_list); + srslog::basic_logger& logger; std::vector supported_meas_types; std::map registered_actions; + + srsran_random_t random_gen; }; #endif /*E2SM_KPM*/ diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 731087171..6ef8e36e3 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -7,6 +7,8 @@ const uint32_t e2sm_kpm::revision = 0; e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_description, revision), logger(logger_) { + random_gen = srsran_random_init(1234); + supported_meas_types.push_back("RRU.PrbTotDl"); supported_meas_types.push_back("RRU.PrbTotUl"); supported_meas_types.push_back("test"); @@ -194,35 +196,93 @@ bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action& action_entry) bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_indication_t& ric_indication) { - ric_indication.indication_type = ri_cind_type_opts::report; - - E2SM_KPM_RIC_ind_header ric_ind_header; - ric_ind_header.collet_start_time = 0x12345; - ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); - this->generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); + if (!registered_actions.count(action_entry.sm_local_ric_action_id)) { + logger.info("Unknown RIC action ID: %i (type %i) (SM local RIC action ID: %i)", + action_entry.ric_action_id, + action_entry.ric_action_type, + action_entry.sm_local_ric_action_id); + return false; + } + E2SM_KPM_RIC_ind_header ric_ind_header; E2SM_KPM_RIC_ind_message ric_ind_message; - ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; - - ric_ind_message.meas_data.resize(1); - ric_ind_message.meas_data[0].meas_record.resize(5); - for (uint32_t i = 0; i < ric_ind_message.meas_data[0].meas_record.size(); i++) { - ric_ind_message.meas_data[0].meas_record[i].set_integer() = i * 1000; + uint64_t granul_period; + meas_info_list_l action_meas_info_list; + + ric_indication.indication_type = ri_cind_type_opts::report; + e2_sm_kpm_action_definition_s action = registered_actions.at(action_entry.sm_local_ric_action_id); + + if (action.ric_style_type == 1) { + granul_period = action.action_definition_formats.action_definition_format1().granul_period; + action_meas_info_list = action.action_definition_formats.action_definition_format1().meas_info_list; + + ric_ind_header.collet_start_time = std::time(0); + ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); + this->generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); + + ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + // ric_ind_message.granul_period = granul_period; // not implemented by flexric and crashes it + + ric_ind_message.meas_info_list.resize(action_meas_info_list.size()); + ric_ind_message.meas_data.resize(action_meas_info_list.size()); + for (uint32_t i = 0; i < action_meas_info_list.size(); i++) { + // structs to fill + meas_info_item_s& meas_info_item = ric_ind_message.meas_info_list[i]; + meas_data_item_s& meas_data = ric_ind_message.meas_data[i]; + + // measure definition + meas_info_item_s meas_def_item = action_meas_info_list[i]; + std::string meas_name = meas_def_item.meas_type.meas_name().to_string(); + + meas_info_item.meas_type.set_meas_name().from_string(meas_name.c_str()); + meas_info_item.label_info_list.resize(meas_def_item.label_info_list.size()); + + for (uint32_t l = 0; l < meas_def_item.label_info_list.size(); l++) { + if (meas_def_item.label_info_list[l].meas_label.no_label_present) { + meas_info_item.label_info_list[l].meas_label.no_label_present = true; + meas_info_item.label_info_list[l].meas_label.no_label = meas_label_s::no_label_opts::true_value; + this->_fill_measurement_records(meas_name, "no_label", meas_data.meas_record); + } + if (meas_def_item.label_info_list[l].meas_label.min_present) { + meas_info_item.label_info_list[l].meas_label.min_present = true; + meas_info_item.label_info_list[l].meas_label.min = meas_label_s::min_opts::true_value; + this->_fill_measurement_records(meas_name, "min", meas_data.meas_record); + } + if (meas_def_item.label_info_list[l].meas_label.max_present) { + meas_info_item.label_info_list[l].meas_label.max_present = true; + meas_info_item.label_info_list[l].meas_label.max = meas_label_s::max_opts::true_value; + this->_fill_measurement_records(meas_name, "max", meas_data.meas_record); + } + if (meas_def_item.label_info_list[l].meas_label.avg_present) { + meas_info_item.label_info_list[l].meas_label.avg_present = true; + meas_info_item.label_info_list[l].meas_label.avg = meas_label_s::avg_opts::true_value; + this->_fill_measurement_records(meas_name, "avg", meas_data.meas_record); + } + if (meas_def_item.label_info_list[l].meas_label.sum_present) { + meas_info_item.label_info_list[l].meas_label.sum_present = true; + meas_info_item.label_info_list[l].meas_label.sum = meas_label_s::sum_opts::true_value; + this->_fill_measurement_records(meas_name, "sum", meas_data.meas_record); + } + } + } } - ric_ind_message.meas_info_list.resize(1); - ric_ind_message.meas_info_list[0].meas_type.set_meas_name().from_string("RRU.PrbTotDl"); - ric_ind_message.meas_info_list[0].label_info_list.resize(1); - ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label_present = true; - ric_ind_message.meas_info_list[0].label_info_list[0].meas_label.no_label = meas_label_s::no_label_opts::true_value; - - // ric_ind_message.granul_period = 12345; // not implemented by flexric and crashes it - ric_indication.ri_cind_msg = srsran::make_byte_buffer(); this->generate_indication_message(ric_ind_message, ric_indication.ri_cind_msg); return true; } +void e2sm_kpm::_fill_measurement_records(std::string meas_name, std::string label, meas_record_l& meas_record_list) +{ + uint32_t nof_records = srsran_random_uniform_int_dist(random_gen, 3, 10); + printf("Fill last N=%i measurements of %s value for label: %s\n", nof_records, meas_name.c_str(), label.c_str()); + + meas_record_list.resize(nof_records); + for (uint32_t i = 0; i < nof_records; i++) { + meas_record_list[i].set_integer() = srsran_random_uniform_int_dist(random_gen, 0, 100); + } +} + bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf) { e2_sm_kpm_ind_hdr_s e2_sm_kpm_ind_hdr; From 56a96950ca77781ce595a1c1340f84524e52afb7 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 17:48:26 +0100 Subject: [PATCH 061/167] e2ap: unify struct definition style --- srsgnb/hdr/stack/ric/e2sm.h | 18 +++++++++--------- srsgnb/hdr/stack/ric/e2sm_kpm.h | 24 ++++++++++++------------ srsgnb/hdr/stack/ric/ric_subscription.h | 2 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 21 +++++++++++---------- srsgnb/src/stack/ric/ric_subscription.cc | 6 +++--- 5 files changed, 36 insertions(+), 35 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index da76e7c03..385f8af26 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -22,17 +22,17 @@ using namespace asn1::e2ap; struct RANfunction_description; -struct RIC_event_trigger_definition { +typedef struct { enum e2sm_event_trigger_type_t { E2SM_REPORT, E2SM_INSERT, E2SM_POLICY, UNKNOWN_TRIGGER }; e2sm_event_trigger_type_t type; uint64_t report_period; -}; +} RIC_event_trigger_definition_t; -struct E2AP_RIC_action { +typedef struct { uint16_t ric_action_id; ri_caction_type_e ric_action_type; uint32_t sm_local_ric_action_id; -}; +} E2AP_RIC_action_t; typedef struct { uint32_t ric_requestor_id; @@ -57,13 +57,13 @@ public: 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; + virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf) = 0; virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, - RIC_event_trigger_definition& event_def) = 0; + RIC_event_trigger_definition_t& event_def) = 0; virtual bool process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, - E2AP_RIC_action& action_entry) = 0; - virtual bool remove_ric_action_definition(E2AP_RIC_action& action_entry) = 0; - virtual bool execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_indication_t& ric_indication) = 0; + E2AP_RIC_action_t& action_entry) = 0; + virtual bool remove_ric_action_definition(E2AP_RIC_action_t& action_entry) = 0; + virtual bool execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication) = 0; protected: uint32_t _generate_local_action_id() { return _registered_action_id_gen++; }; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index ce1b9d5b0..cfb5fde3e 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -22,20 +22,20 @@ using namespace asn1::e2ap; using namespace asn1::e2sm_kpm; -struct E2SM_KPM_RIC_ind_header { +typedef struct { uint32_t collet_start_time; std::string file_formatversion; std::string sender_name; std::string sender_type; std::string vendor_name; -}; +} E2SM_KPM_RIC_ind_header_t; -struct E2SM_KPM_RIC_ind_message { +typedef struct { e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types ind_msg_format; meas_data_l meas_data; meas_info_list_l meas_info_list; - uint64_t granul_period = 0; -}; + uint64_t granul_period; +} E2SM_KPM_RIC_ind_message_t; class e2sm_kpm : public e2sm { @@ -49,14 +49,14 @@ public: ~e2sm_kpm() = default; virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf); - virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, - RIC_event_trigger_definition& event_def); - virtual bool process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action& action_entry); - virtual bool remove_ric_action_definition(E2AP_RIC_action& action_entry); - virtual bool execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_indication_t& ric_indication); + virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, + RIC_event_trigger_definition_t& event_def); + virtual bool process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action_t& action_entry); + virtual bool remove_ric_action_definition(E2AP_RIC_action_t& action_entry); + virtual bool execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication); - bool generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf); - bool generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf); + bool generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf); + bool generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); private: void _fill_measurement_records(std::string meas_name, std::string label, meas_record_l& meas_record_list); diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index a9bd4bf35..85782d7aa 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -50,7 +50,7 @@ private: uint32_t reporting_period = 0; // ms srsran::unique_timer reporting_timer; // for RIC indication reporting - std::vector admitted_actions; + std::vector admitted_actions; std::vector not_admitted_actions; }; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 6ef8e36e3..ad3968a8b 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -87,8 +87,8 @@ bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, return true; } -bool e2sm_kpm::process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, - RIC_event_trigger_definition& event_def) +bool e2sm_kpm::process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, + RIC_event_trigger_definition_t& event_def) { e2_sm_kpm_event_trigger_definition_s trigger_def; asn1::cbit_ref bref(subscription_request->ricsubscription_details->ric_event_trigger_definition.data(), @@ -98,12 +98,12 @@ bool e2sm_kpm::process_ric_event_trigger_definition(ricsubscription_request_s return false; } - event_def.type = RIC_event_trigger_definition::e2sm_event_trigger_type_t::E2SM_REPORT; + event_def.type = RIC_event_trigger_definition_t::e2sm_event_trigger_type_t::E2SM_REPORT; event_def.report_period = trigger_def.event_definition_formats.event_definition_format1().report_period; return true; } -bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action& action_entry) +bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action_t& action_entry) { e2_sm_kpm_action_definition_s e2sm_kpm_action_def; asn1::cbit_ref bref(ric_action.ric_action_definition.data(), ric_action.ric_action_definition.size()); @@ -185,7 +185,7 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a return true; } -bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action& action_entry) +bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action_t& action_entry) { if (registered_actions.count(action_entry.sm_local_ric_action_id)) { registered_actions.erase(action_entry.sm_local_ric_action_id); @@ -194,7 +194,7 @@ bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action& action_entry) return false; } -bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_indication_t& ric_indication) +bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication) { if (!registered_actions.count(action_entry.sm_local_ric_action_id)) { logger.info("Unknown RIC action ID: %i (type %i) (SM local RIC action ID: %i)", @@ -204,8 +204,8 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, return false; } - E2SM_KPM_RIC_ind_header ric_ind_header; - E2SM_KPM_RIC_ind_message ric_ind_message; + E2SM_KPM_RIC_ind_header_t ric_ind_header; + E2SM_KPM_RIC_ind_message_t ric_ind_message; uint64_t granul_period; meas_info_list_l action_meas_info_list; @@ -222,6 +222,7 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action& action_entry, ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; // ric_ind_message.granul_period = granul_period; // not implemented by flexric and crashes it + ric_ind_message.granul_period = 0; ric_ind_message.meas_info_list.resize(action_meas_info_list.size()); ric_ind_message.meas_data.resize(action_meas_info_list.size()); @@ -283,7 +284,7 @@ void e2sm_kpm::_fill_measurement_records(std::string meas_name, std::string labe } } -bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::unique_byte_buffer_t& buf) +bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf) { e2_sm_kpm_ind_hdr_s e2_sm_kpm_ind_hdr; e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().collet_start_time.from_number(hdr.collet_start_time); @@ -302,7 +303,7 @@ bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header hdr, srsran::u return true; } -bool e2sm_kpm::generate_indication_message(E2SM_KPM_RIC_ind_message msg, srsran::unique_byte_buffer_t& buf) +bool e2sm_kpm::generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf) { e2_sm_kpm_ind_msg_s e2_sm_kpm_ind_msg; diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index c425498cb..7b832d9d7 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -36,9 +36,9 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli return; } - RIC_event_trigger_definition event_trigger; + RIC_event_trigger_definition_t event_trigger; if (sm_ptr->process_ric_event_trigger_definition(ric_subscription_request, event_trigger)) { - if (event_trigger.type == RIC_event_trigger_definition::e2sm_event_trigger_type_t::E2SM_REPORT) { + if (event_trigger.type == RIC_event_trigger_definition_t::e2sm_event_trigger_type_t::E2SM_REPORT) { reporting_period = event_trigger.report_period; reporting_period = 1000; // TODO: to remove, keep it 1s for testing } @@ -50,7 +50,7 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli for (uint32_t i = 0; i < action_list.size(); i++) { ri_caction_to_be_setup_item_s action_item = action_list[i]->ri_caction_to_be_setup_item(); - E2AP_RIC_action admitted_action; + E2AP_RIC_action_t admitted_action; admitted_action.ric_action_id = action_item.ric_action_id; admitted_action.ric_action_type = action_item.ric_action_type; From 27b68e159e97c6780652ff8fa93007ba5d8bbc3d Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 17:52:20 +0100 Subject: [PATCH 062/167] e2sm_kpm: make two funcs private --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 5 ++--- srsgnb/src/stack/ric/e2sm_kpm.cc | 8 ++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index cfb5fde3e..fdf667e1c 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -55,11 +55,10 @@ public: virtual bool remove_ric_action_definition(E2AP_RIC_action_t& action_entry); virtual bool execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication); - bool generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf); - bool generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); - private: void _fill_measurement_records(std::string meas_name, std::string label, meas_record_l& meas_record_list); + bool _generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf); + bool _generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); srslog::basic_logger& logger; std::vector supported_meas_types; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index ad3968a8b..aac5e83c6 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -218,7 +218,7 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr ric_ind_header.collet_start_time = std::time(0); ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); - this->generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); + this->_generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; // ric_ind_message.granul_period = granul_period; // not implemented by flexric and crashes it @@ -269,7 +269,7 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr } ric_indication.ri_cind_msg = srsran::make_byte_buffer(); - this->generate_indication_message(ric_ind_message, ric_indication.ri_cind_msg); + this->_generate_indication_message(ric_ind_message, ric_indication.ri_cind_msg); return true; } @@ -284,7 +284,7 @@ void e2sm_kpm::_fill_measurement_records(std::string meas_name, std::string labe } } -bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf) +bool e2sm_kpm::_generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf) { e2_sm_kpm_ind_hdr_s e2_sm_kpm_ind_hdr; e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().collet_start_time.from_number(hdr.collet_start_time); @@ -303,7 +303,7 @@ bool e2sm_kpm::generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran: return true; } -bool e2sm_kpm::generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf) +bool e2sm_kpm::_generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf) { e2_sm_kpm_ind_msg_s e2_sm_kpm_ind_msg; From 688067b29860a0ca1283bd80c182f01b6b58dbed Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 17:54:33 +0100 Subject: [PATCH 063/167] e2sm_kpm: add quotation marks to meas name --- srsgnb/src/stack/ric/e2sm_kpm.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index aac5e83c6..172f3adce 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -148,13 +148,13 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); if (std::find(supported_meas_types.begin(), supported_meas_types.end(), meas_name.c_str()) == supported_meas_types.end()) { - printf("Unsupported measurement name: %s --> do not admit action %i \n", + printf("Unsupported measurement name: \"%s\" --> do not admit action %i \n", meas_name.c_str(), ric_action.ric_action_id); return false; } - printf("Admitted action: measurement name: %s with the following labels: \n", meas_name.c_str()); + printf("Admitted action: measurement name: \"%s\" with the following labels: \n", meas_name.c_str()); for (uint32_t l = 0; l < meas_info_list[i].label_info_list.size(); l++) { if (meas_info_list[i].label_info_list[l].meas_label.no_label_present) { printf("--- Label %i: NO LABEL\n", i); @@ -276,7 +276,7 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr void e2sm_kpm::_fill_measurement_records(std::string meas_name, std::string label, meas_record_l& meas_record_list) { uint32_t nof_records = srsran_random_uniform_int_dist(random_gen, 3, 10); - printf("Fill last N=%i measurements of %s value for label: %s\n", nof_records, meas_name.c_str(), label.c_str()); + printf("Fill last N=%i measurements of \"%s\" value for label: %s\n", nof_records, meas_name.c_str(), label.c_str()); meas_record_list.resize(nof_records); for (uint32_t i = 0; i < nof_records; i++) { From 4b18a55c2ce9ded87547119b630051baa6bfa2fe Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 18:25:02 +0100 Subject: [PATCH 064/167] e2ap: change todo to info --- srsgnb/src/stack/ric/e2ap.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 82ef1efa2..41f6eab83 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -36,7 +36,7 @@ e2_ap_pdu_c e2ap::generate_setup_request() 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 + gnb_.global_g_nb_id.gnb_id.gnb_id().from_number(gnb_id, 28); // eutra_cell_id has 28 bits // add all supported e2SM functions setup->ra_nfunctions_added.crit = asn1::crit_opts::reject; From e51871a62634f9c17c2cb806698f6eba75be95dd Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 18:26:33 +0100 Subject: [PATCH 065/167] e2ap: change func signature and move logic to the function --- srsgnb/hdr/stack/ric/e2sm.h | 2 +- srsgnb/hdr/stack/ric/e2sm_kpm.h | 2 +- srsgnb/src/stack/ric/e2ap.cc | 8 +------- srsgnb/src/stack/ric/e2sm_kpm.cc | 14 ++++++++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index 385f8af26..54df1a31b 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -57,7 +57,7 @@ public: 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; + virtual bool generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func) = 0; virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, RIC_event_trigger_definition_t& event_def) = 0; virtual bool process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index fdf667e1c..42fb87059 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -48,7 +48,7 @@ public: e2sm_kpm(srslog::basic_logger& logger_); ~e2sm_kpm() = default; - virtual bool generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf); + virtual bool generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func); virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, RIC_event_trigger_definition_t& event_def); virtual bool process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action_t& action_entry); diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 41f6eab83..178789904 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -52,13 +52,7 @@ e2_ap_pdu_c e2ap::generate_setup_request() ran_func.ran_function_id = local_ran_function_id; ran_func.ran_function_revision = sm_ptr->get_revision(); ran_func.ran_function_oid.from_string(sm_ptr->get_oid().c_str()); - - auto& ran_func_def = ran_func.ran_function_definition; - srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); - sm_ptr->generate_ran_function_description(x.second, 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()); + sm_ptr->generate_ran_function_description(x.second, ran_func); idx++; } diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 172f3adce..f182a89f2 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -14,7 +14,7 @@ e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_d supported_meas_types.push_back("test"); } -bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, srsran::unique_byte_buffer_t& buf) +bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func) { desc.function_shortname = short_name; desc.function_e2_sm_oid = oid; @@ -78,12 +78,18 @@ bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, 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()); + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); if (e2sm_kpm_ra_nfunction_description.pack(bref) != asn1::SRSASN_SUCCESS) { printf("Failed to pack TX E2 PDU\n"); return false; } buf->N_bytes = bref.distance_bytes(); + + ran_func.ran_function_definition.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.ran_function_definition.data()); + return true; } @@ -206,8 +212,8 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr E2SM_KPM_RIC_ind_header_t ric_ind_header; E2SM_KPM_RIC_ind_message_t ric_ind_message; - uint64_t granul_period; - meas_info_list_l action_meas_info_list; + uint64_t granul_period; + meas_info_list_l action_meas_info_list; ric_indication.indication_type = ri_cind_type_opts::report; e2_sm_kpm_action_definition_s action = registered_actions.at(action_entry.sm_local_ric_action_id); From 72fd9b4dfceb050809f7b424d9c1a59245aaff45 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 18:48:53 +0100 Subject: [PATCH 066/167] e2sm_kpm: process ric action definition formats in separate funcs --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 6 ++ srsgnb/src/stack/ric/e2sm_kpm.cc | 157 +++++++++++++++++++------------ 2 files changed, 104 insertions(+), 59 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 42fb87059..7e148520e 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -56,6 +56,12 @@ public: virtual bool execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication); private: + bool _process_ric_action_definition_format1(e2_sm_kpm_action_definition_format1_s& action_definition_format1); + bool _process_ric_action_definition_format2(e2_sm_kpm_action_definition_format2_s& action_definition_format2); + bool _process_ric_action_definition_format3(e2_sm_kpm_action_definition_format3_s& action_definition_format3); + bool _process_ric_action_definition_format4(e2_sm_kpm_action_definition_format4_s& action_definition_format4); + bool _process_ric_action_definition_format5(e2_sm_kpm_action_definition_format5_s& action_definition_format5); + void _fill_measurement_records(std::string meas_name, std::string label, meas_record_l& meas_record_list); bool _generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf); bool _generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index f182a89f2..fb6c7c19b 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -111,74 +111,34 @@ bool e2sm_kpm::process_ric_event_trigger_definition(ricsubscription_request_s bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action_t& action_entry) { + bool admit_action = false; e2_sm_kpm_action_definition_s e2sm_kpm_action_def; asn1::cbit_ref bref(ric_action.ric_action_definition.data(), ric_action.ric_action_definition.size()); - uint64_t granul_period; - uint64_t eutra_cell_id; - uint64_t plmn_id; - ueid_c ue_id; - meas_info_list_l meas_info_list; - if (e2sm_kpm_action_def.unpack(bref) != asn1::SRSASN_SUCCESS) { return false; } switch (e2sm_kpm_action_def.ric_style_type) { case 1: - granul_period = e2sm_kpm_action_def.action_definition_formats.action_definition_format1().granul_period; - - if (granul_period == 0) { - logger.debug("Action granularity period of %i is not supported -> do not admitted action %i", - granul_period, - ric_action.ric_action_id); - return false; - } - - if (e2sm_kpm_action_def.action_definition_formats.action_definition_format1().cell_global_id_present) { - if (e2sm_kpm_action_def.action_definition_formats.action_definition_format1().cell_global_id.type() == - cgi_c::types_opts::eutra_cgi) { - eutra_cell_id = e2sm_kpm_action_def.action_definition_formats.action_definition_format1() - .cell_global_id.eutra_cgi() - .eutra_cell_id.to_number(); - plmn_id = e2sm_kpm_action_def.action_definition_formats.action_definition_format1() - .cell_global_id.eutra_cgi() - .plmn_id.to_number(); - logger.debug("plmn_id 0x%x, eutra_cell_id %i", plmn_id, eutra_cell_id); - // TODO: check if E2 node has cell_id and plmn_id - } - } - - meas_info_list = e2sm_kpm_action_def.action_definition_formats.action_definition_format1().meas_info_list; - for (uint32_t i = 0; i < meas_info_list.size(); i++) { - std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); - if (std::find(supported_meas_types.begin(), supported_meas_types.end(), meas_name.c_str()) == - supported_meas_types.end()) { - printf("Unsupported measurement name: \"%s\" --> do not admit action %i \n", - meas_name.c_str(), - ric_action.ric_action_id); - return false; - } - - printf("Admitted action: measurement name: \"%s\" with the following labels: \n", meas_name.c_str()); - for (uint32_t l = 0; l < meas_info_list[i].label_info_list.size(); l++) { - if (meas_info_list[i].label_info_list[l].meas_label.no_label_present) { - printf("--- Label %i: NO LABEL\n", i); - } - if (meas_info_list[i].label_info_list[l].meas_label.min_present) { - printf("--- Label %i: MIN\n", i); - } - if (meas_info_list[i].label_info_list[l].meas_label.max_present) { - printf("--- Label %i: MAX\n", i); - } - if (meas_info_list[i].label_info_list[l].meas_label.avg_present) { - printf("--- Label %i: AVG\n", i); - } - } - } - action_entry.sm_local_ric_action_id = _generate_local_action_id(); - registered_actions.insert( - std::pair(action_entry.sm_local_ric_action_id, e2sm_kpm_action_def)); + admit_action = _process_ric_action_definition_format1( + e2sm_kpm_action_def.action_definition_formats.action_definition_format1()); + break; + case 2: + admit_action = _process_ric_action_definition_format2( + e2sm_kpm_action_def.action_definition_formats.action_definition_format2()); + break; + case 3: + admit_action = _process_ric_action_definition_format3( + e2sm_kpm_action_def.action_definition_formats.action_definition_format3()); + break; + case 4: + admit_action = _process_ric_action_definition_format4( + e2sm_kpm_action_def.action_definition_formats.action_definition_format4()); + break; + case 5: + admit_action = _process_ric_action_definition_format5( + e2sm_kpm_action_def.action_definition_formats.action_definition_format5()); break; default: logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", @@ -188,9 +148,88 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a return false; } + if (admit_action) { + action_entry.sm_local_ric_action_id = _generate_local_action_id(); + registered_actions.insert( + std::pair(action_entry.sm_local_ric_action_id, e2sm_kpm_action_def)); + } + return true; } +bool e2sm_kpm::_process_ric_action_definition_format1(e2_sm_kpm_action_definition_format1_s& action_definition_format1) +{ + uint64_t granul_period; + uint64_t eutra_cell_id; + uint64_t plmn_id; + ueid_c ue_id; + meas_info_list_l meas_info_list; + + granul_period = action_definition_format1.granul_period; + + if (granul_period == 0) { + logger.debug("Action granularity period of %i is not supported -> do not admitted action\n", granul_period); + return false; + } + + if (action_definition_format1.cell_global_id_present) { + if (action_definition_format1.cell_global_id.type() == cgi_c::types_opts::eutra_cgi) { + eutra_cell_id = action_definition_format1.cell_global_id.eutra_cgi().eutra_cell_id.to_number(); + plmn_id = action_definition_format1.cell_global_id.eutra_cgi().plmn_id.to_number(); + logger.debug("plmn_id 0x%x, eutra_cell_id %i", plmn_id, eutra_cell_id); + // TODO: check if E2 node has cell_id and plmn_id + } + } + + meas_info_list = action_definition_format1.meas_info_list; + for (uint32_t i = 0; i < meas_info_list.size(); i++) { + std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); + if (std::find(supported_meas_types.begin(), supported_meas_types.end(), meas_name.c_str()) == + supported_meas_types.end()) { + printf("Unsupported measurement name: \"%s\" --> do not admit action\n", meas_name.c_str()); + return false; + } + + printf("Admitted action: measurement name: \"%s\" with the following labels: \n", meas_name.c_str()); + for (uint32_t l = 0; l < meas_info_list[i].label_info_list.size(); l++) { + if (meas_info_list[i].label_info_list[l].meas_label.no_label_present) { + printf("--- Label %i: NO LABEL\n", i); + } + if (meas_info_list[i].label_info_list[l].meas_label.min_present) { + printf("--- Label %i: MIN\n", i); + } + if (meas_info_list[i].label_info_list[l].meas_label.max_present) { + printf("--- Label %i: MAX\n", i); + } + if (meas_info_list[i].label_info_list[l].meas_label.avg_present) { + printf("--- Label %i: AVG\n", i); + } + } + } + + return true; +} + +bool e2sm_kpm::_process_ric_action_definition_format2(e2_sm_kpm_action_definition_format2_s& action_definition_format2) +{ + return false; +} + +bool e2sm_kpm::_process_ric_action_definition_format3(e2_sm_kpm_action_definition_format3_s& action_definition_format3) +{ + return false; +} + +bool e2sm_kpm::_process_ric_action_definition_format4(e2_sm_kpm_action_definition_format4_s& action_definition_format4) +{ + return false; +} + +bool e2sm_kpm::_process_ric_action_definition_format5(e2_sm_kpm_action_definition_format5_s& action_definition_format5) +{ + return false; +} + bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action_t& action_entry) { if (registered_actions.count(action_entry.sm_local_ric_action_id)) { From a3c8f202067ad6f37f96c4bc8d6aac627121b775 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 22:41:44 +0100 Subject: [PATCH 067/167] ric_subscription: rename struct --- srsgnb/src/stack/ric/ric_subscription.cc | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 7b832d9d7..24dcef893 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -50,21 +50,21 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli for (uint32_t i = 0; i < action_list.size(); i++) { ri_caction_to_be_setup_item_s action_item = action_list[i]->ri_caction_to_be_setup_item(); - E2AP_RIC_action_t admitted_action; - admitted_action.ric_action_id = action_item.ric_action_id; - admitted_action.ric_action_type = action_item.ric_action_type; + E2AP_RIC_action_t candidate_action; + candidate_action.ric_action_id = action_item.ric_action_id; + candidate_action.ric_action_type = action_item.ric_action_type; - if (sm_ptr->process_ric_action_definition(action_item, admitted_action)) { + if (sm_ptr->process_ric_action_definition(action_item, candidate_action)) { parent->logger.debug("Admitted action %i (type: %i), mapped to SM local action ID: %i", - admitted_action.ric_action_id, - admitted_action.ric_action_type, - admitted_action.sm_local_ric_action_id); + candidate_action.ric_action_id, + candidate_action.ric_action_type, + candidate_action.sm_local_ric_action_id); printf("Admitted action %i, mapped to SM local action ID: %i\n", - action_item.ric_action_id, - admitted_action.sm_local_ric_action_id); + candidate_action.ric_action_id, + candidate_action.sm_local_ric_action_id); - admitted_actions.push_back(admitted_action); + admitted_actions.push_back(candidate_action); if (action_item.ric_subsequent_action_present) { parent->logger.debug("--Action %i (type: %i) contains subsequent action of type %i with wait time: %i", @@ -154,7 +154,6 @@ void ric_client::ric_subscription::send_ric_indication() ric_indication.ric_instance_id = ric_instance_id; ric_indication.ra_nfunction_id = ra_nfunction_id; ric_indication.ri_caction_id = action.ric_action_id; - sm_ptr->execute_action_fill_ric_indication(action, ric_indication); e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(ric_indication); From 65f56f07899c1aeb00ebcd4441b581c5bc7e5562 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 22:42:19 +0100 Subject: [PATCH 068/167] e2sm_kpm: fix return value --- srsgnb/src/stack/ric/e2sm_kpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index fb6c7c19b..134c4e7ae 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -154,7 +154,7 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a std::pair(action_entry.sm_local_ric_action_id, e2sm_kpm_action_def)); } - return true; + return admit_action; } bool e2sm_kpm::_process_ric_action_definition_format1(e2_sm_kpm_action_definition_format1_s& action_definition_format1) From 5016e4b543266fc7cabc4452646e8dff60533eda Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 22:43:04 +0100 Subject: [PATCH 069/167] e2sm_kpm: fill different ric indication msg formats in separate functions --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 6 ++ srsgnb/src/stack/ric/e2sm_kpm.cc | 172 +++++++++++++++++++++---------- 2 files changed, 121 insertions(+), 57 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 7e148520e..ed7a47a26 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -62,6 +62,12 @@ private: bool _process_ric_action_definition_format4(e2_sm_kpm_action_definition_format4_s& action_definition_format4); bool _process_ric_action_definition_format5(e2_sm_kpm_action_definition_format5_s& action_definition_format5); + bool _fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format1_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); + bool _fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format2_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); + bool _fill_ric_ind_msg_format2(e2_sm_kpm_action_definition_format3_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); + bool _fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format4_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); + bool _fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format5_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); + void _fill_measurement_records(std::string meas_name, std::string label, meas_record_l& meas_record_list); bool _generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf); bool _generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 134c4e7ae..9309b3aca 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -251,66 +251,40 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr E2SM_KPM_RIC_ind_header_t ric_ind_header; E2SM_KPM_RIC_ind_message_t ric_ind_message; - uint64_t granul_period; - meas_info_list_l action_meas_info_list; - ric_indication.indication_type = ri_cind_type_opts::report; + ric_indication.indication_type = ri_cind_type_opts::report; + + // header is the same for all RIC service styles, i.e., type 1 + ric_ind_header.collet_start_time = std::time(0); + ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); + this->_generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); + e2_sm_kpm_action_definition_s action = registered_actions.at(action_entry.sm_local_ric_action_id); - if (action.ric_style_type == 1) { - granul_period = action.action_definition_formats.action_definition_format1().granul_period; - action_meas_info_list = action.action_definition_formats.action_definition_format1().meas_info_list; - - ric_ind_header.collet_start_time = std::time(0); - ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); - this->_generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); - - ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; - // ric_ind_message.granul_period = granul_period; // not implemented by flexric and crashes it - ric_ind_message.granul_period = 0; - - ric_ind_message.meas_info_list.resize(action_meas_info_list.size()); - ric_ind_message.meas_data.resize(action_meas_info_list.size()); - for (uint32_t i = 0; i < action_meas_info_list.size(); i++) { - // structs to fill - meas_info_item_s& meas_info_item = ric_ind_message.meas_info_list[i]; - meas_data_item_s& meas_data = ric_ind_message.meas_data[i]; - - // measure definition - meas_info_item_s meas_def_item = action_meas_info_list[i]; - std::string meas_name = meas_def_item.meas_type.meas_name().to_string(); - - meas_info_item.meas_type.set_meas_name().from_string(meas_name.c_str()); - meas_info_item.label_info_list.resize(meas_def_item.label_info_list.size()); - - for (uint32_t l = 0; l < meas_def_item.label_info_list.size(); l++) { - if (meas_def_item.label_info_list[l].meas_label.no_label_present) { - meas_info_item.label_info_list[l].meas_label.no_label_present = true; - meas_info_item.label_info_list[l].meas_label.no_label = meas_label_s::no_label_opts::true_value; - this->_fill_measurement_records(meas_name, "no_label", meas_data.meas_record); - } - if (meas_def_item.label_info_list[l].meas_label.min_present) { - meas_info_item.label_info_list[l].meas_label.min_present = true; - meas_info_item.label_info_list[l].meas_label.min = meas_label_s::min_opts::true_value; - this->_fill_measurement_records(meas_name, "min", meas_data.meas_record); - } - if (meas_def_item.label_info_list[l].meas_label.max_present) { - meas_info_item.label_info_list[l].meas_label.max_present = true; - meas_info_item.label_info_list[l].meas_label.max = meas_label_s::max_opts::true_value; - this->_fill_measurement_records(meas_name, "max", meas_data.meas_record); - } - if (meas_def_item.label_info_list[l].meas_label.avg_present) { - meas_info_item.label_info_list[l].meas_label.avg_present = true; - meas_info_item.label_info_list[l].meas_label.avg = meas_label_s::avg_opts::true_value; - this->_fill_measurement_records(meas_name, "avg", meas_data.meas_record); - } - if (meas_def_item.label_info_list[l].meas_label.sum_present) { - meas_info_item.label_info_list[l].meas_label.sum_present = true; - meas_info_item.label_info_list[l].meas_label.sum = meas_label_s::sum_opts::true_value; - this->_fill_measurement_records(meas_name, "sum", meas_data.meas_record); - } - } - } + switch (action.ric_style_type) { + case 1: + ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + _fill_ric_ind_msg_format1(action.action_definition_formats.action_definition_format1(), ric_ind_message); + break; + case 2: + ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + _fill_ric_ind_msg_format1(action.action_definition_formats.action_definition_format2(), ric_ind_message); + break; + case 3: + ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format2; + _fill_ric_ind_msg_format2(action.action_definition_formats.action_definition_format3(), ric_ind_message); + break; + case 4: + ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format3; + _fill_ric_ind_msg_format3(action.action_definition_formats.action_definition_format4(), ric_ind_message); + break; + case 5: + ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format3; + _fill_ric_ind_msg_format3(action.action_definition_formats.action_definition_format5(), ric_ind_message); + break; + default: + logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", action.ric_style_type); + return false; } ric_indication.ri_cind_msg = srsran::make_byte_buffer(); @@ -318,6 +292,90 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr return true; } +bool e2sm_kpm::_fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format1_s& action, + E2SM_KPM_RIC_ind_message_t& ric_ind_msg) +{ + cgi_c cell_global_id; + meas_info_list_l action_meas_info_list = action.meas_info_list; + + if (action.cell_global_id_present) { + cell_global_id = action.cell_global_id; + } + + // ric_ind_message.granul_period = action.granul_period; // not implemented by flexric and crashes it + ric_ind_msg.granul_period = 0; + + ric_ind_msg.meas_info_list.resize(action_meas_info_list.size()); + ric_ind_msg.meas_data.resize(action_meas_info_list.size()); + + for (uint32_t i = 0; i < action_meas_info_list.size(); i++) { + // structs to fill + meas_info_item_s& meas_info_item = ric_ind_msg.meas_info_list[i]; + meas_data_item_s& meas_data = ric_ind_msg.meas_data[i]; + + // measurements definition + meas_info_item_s meas_def_item = action_meas_info_list[i]; + std::string meas_name = meas_def_item.meas_type.meas_name().to_string(); + + meas_info_item.meas_type.set_meas_name().from_string(meas_name.c_str()); + meas_info_item.label_info_list.resize(meas_def_item.label_info_list.size()); + + for (uint32_t l = 0; l < meas_def_item.label_info_list.size(); l++) { + if (meas_def_item.label_info_list[l].meas_label.no_label_present) { + meas_info_item.label_info_list[l].meas_label.no_label_present = true; + meas_info_item.label_info_list[l].meas_label.no_label = meas_label_s::no_label_opts::true_value; + this->_fill_measurement_records(meas_name, "no_label", meas_data.meas_record); + } + if (meas_def_item.label_info_list[l].meas_label.min_present) { + meas_info_item.label_info_list[l].meas_label.min_present = true; + meas_info_item.label_info_list[l].meas_label.min = meas_label_s::min_opts::true_value; + this->_fill_measurement_records(meas_name, "min", meas_data.meas_record); + } + if (meas_def_item.label_info_list[l].meas_label.max_present) { + meas_info_item.label_info_list[l].meas_label.max_present = true; + meas_info_item.label_info_list[l].meas_label.max = meas_label_s::max_opts::true_value; + this->_fill_measurement_records(meas_name, "max", meas_data.meas_record); + } + if (meas_def_item.label_info_list[l].meas_label.avg_present) { + meas_info_item.label_info_list[l].meas_label.avg_present = true; + meas_info_item.label_info_list[l].meas_label.avg = meas_label_s::avg_opts::true_value; + this->_fill_measurement_records(meas_name, "avg", meas_data.meas_record); + } + if (meas_def_item.label_info_list[l].meas_label.sum_present) { + meas_info_item.label_info_list[l].meas_label.sum_present = true; + meas_info_item.label_info_list[l].meas_label.sum = meas_label_s::sum_opts::true_value; + this->_fill_measurement_records(meas_name, "sum", meas_data.meas_record); + } + } + } + + return true; +} + +bool e2sm_kpm::_fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format2_s& action, + E2SM_KPM_RIC_ind_message_t& ric_ind_msg) +{ + return false; +} + +bool e2sm_kpm::_fill_ric_ind_msg_format2(e2_sm_kpm_action_definition_format3_s& action, + E2SM_KPM_RIC_ind_message_t& ric_ind_msg) +{ + return false; +} + +bool e2sm_kpm::_fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format4_s& action, + E2SM_KPM_RIC_ind_message_t& ric_ind_msg) +{ + return false; +} + +bool e2sm_kpm::_fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format5_s& action, + E2SM_KPM_RIC_ind_message_t& ric_ind_msg) +{ + return false; +} + void e2sm_kpm::_fill_measurement_records(std::string meas_name, std::string label, meas_record_l& meas_record_list) { uint32_t nof_records = srsran_random_uniform_int_dist(random_gen, 3, 10); From 868c0efe6eb055901056b3ba1211af8b38221935 Mon Sep 17 00:00:00 2001 From: yagoda Date: Tue, 21 Mar 2023 20:48:10 +0100 Subject: [PATCH 070/167] e2ap: passing ric timer to e2ap object --- srsgnb/hdr/stack/ric/e2ap.h | 7 ++++++- srsgnb/src/stack/ric/e2ap.cc | 6 ++++-- srsgnb/src/stack/ric/ric_client.cc | 2 +- srsgnb/src/stack/ric/test/e2ap_test.cc | 8 ++++---- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index d38b0474d..701000de0 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -13,6 +13,8 @@ #include "e2sm_kpm.h" #include "srsran/asn1/e2ap.h" +#include "srsran/common/task_scheduler.h" +#include "srsran/common/timers.h" #include "srsran/interfaces/e2_metrics_interface.h" #include "srsran/interfaces/enb_metrics_interface.h" #include "srsran/srsran.h" @@ -46,7 +48,9 @@ typedef struct { class e2ap { public: - e2ap(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics); + e2ap(srslog::basic_logger& logger, + srsenb::e2_interface_metrics* _gnb_metrics, + srsran::task_scheduler* _task_sched_ptr); e2_ap_pdu_c generate_setup_request(); int process_setup_response(e2setup_resp_s setup_response); int process_setup_failure(); @@ -76,6 +80,7 @@ private: std::map ran_functions; srsenb::e2_interface_metrics* gnb_metrics = nullptr; bool reset_response_received = false; + srsran::task_scheduler* task_sched_ptr = nullptr; int reset_transaction_id = 1; cause_c reset_cause = cause_c(); int reset_id = 1; diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 178789904..71dd809e8 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -2,10 +2,12 @@ #include "srsgnb/hdr/stack/ric/e2ap.h" #include "stdint.h" -e2ap::e2ap(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics) : logger(logger), e2sm_(logger) +e2ap::e2ap(srslog::basic_logger& logger, + srsenb::e2_interface_metrics* _gnb_metrics, + srsran::task_scheduler* _task_sched_ptr) : + logger(logger), e2sm_(logger), task_sched_ptr(_task_sched_ptr) { gnb_metrics = _gnb_metrics; - // add SMs to map uint32_t local_ran_function_id = 147; RANfunction_description add_func; diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index b0a5de1db..67b523093 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -17,7 +17,7 @@ using namespace srsenb; ric_client::ric_client(srslog::basic_logger& logger, e2_interface_metrics* _gnb_metrics) : - task_sched(), logger(logger), rx_sockets(), thread("RIC_CLIENT_THREAD"), e2ap_(logger, _gnb_metrics) + task_sched(), logger(logger), rx_sockets(), thread("RIC_CLIENT_THREAD"), e2ap_(logger, _gnb_metrics, &task_sched) { gnb_metrics = _gnb_metrics; } diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index 08561cd52..c589be1ad 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -103,7 +103,7 @@ void test_native_e2ap_setup_request() e2_ap_pdu_c pdu, pdu2; srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); dummy_metrics_interface dummy_metrics; - e2ap e2ap_(logger, &dummy_metrics); + e2ap e2ap_(logger, &dummy_metrics, NULL); pdu = e2ap_.generate_setup_request(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); @@ -139,7 +139,7 @@ void test_native_e2ap_subscription_response() e2_ap_pdu_c pdu, pdu2; srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); dummy_metrics_interface dummy_metrics; - e2ap e2ap_(logger, &dummy_metrics); + e2ap e2ap_(logger, &dummy_metrics, NULL); ric_subscription_reponse_t ric_subscription_reponse; ric_subscription_reponse.ric_requestor_id = 1021; @@ -167,7 +167,7 @@ void test_native_e2ap_reset_request() e2_ap_pdu_c pdu, pdu2; srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); dummy_metrics_interface dummy_metrics; - e2ap e2ap_(logger, &dummy_metrics); + e2ap e2ap_(logger, &dummy_metrics, NULL); pdu = e2ap_.generate_reset_request(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); @@ -188,7 +188,7 @@ void test_native_e2ap_reset_response() e2_ap_pdu_c pdu, pdu2; srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); dummy_metrics_interface dummy_metrics; - e2ap e2ap_(logger, &dummy_metrics); + e2ap e2ap_(logger, &dummy_metrics, NULL); pdu = e2ap_.generate_reset_response(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); From 81b5632d96c277d5ec2d368bd1422ae61d015cfa Mon Sep 17 00:00:00 2001 From: yagoda Date: Tue, 21 Mar 2023 20:58:04 +0100 Subject: [PATCH 071/167] e2ap: adding failure message handling, implementation of e2 setup failure --- srsgnb/hdr/stack/ric/e2ap.h | 19 +++++++--- srsgnb/src/stack/ric/e2ap.cc | 57 ++++++++++++++++++++++++++---- srsgnb/src/stack/ric/ric_client.cc | 37 ++++++++++++++++--- 3 files changed, 99 insertions(+), 14 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 701000de0..5c615ca6d 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -64,23 +64,34 @@ public: e2_ap_pdu_c generate_reset_response(); int process_reset_request(reset_request_s reset_request); int process_reset_response(reset_resp_s reset_response); + + int process_e2_setup_failure(e2setup_fail_s e2setup_failure); + int process_ric_service_update_failure(ricservice_upd_fail_s ric_service_update_failure); + int process_e2_node_config_update_failure(e2node_cfg_upd_fail_s e2node_config_update_failure); + int process_e2_removal_failure(e2_removal_fail_s e2_remove_failure); + int get_reset_id(); - bool has_setup_response() { return setup_response_received; } bool get_func_desc(uint32_t ran_func_id, RANfunction_description& fdesc); + bool send_setup_request() { return !e2_established && pending_e2_setup; } private: srslog::basic_logger& logger; e2sm_kpm e2sm_; - bool setup_response_received = false; - bool pending_subscription_request = false; + bool e2_established = false; + srsran::unique_timer e2_procedure_timeout; + bool pending_e2_setup = false; + bool pending_e2_node_config_update = false; + bool pending_ric_service_update = false; + bool pending_e2_removal = false; + int setup_procedure_transaction_id = 0; uint64_t plmn_id = 0x05f510; uint64_t gnb_id = 1; global_ric_id_t global_ric_id = {}; std::map ran_functions; srsenb::e2_interface_metrics* gnb_metrics = nullptr; - bool reset_response_received = false; srsran::task_scheduler* task_sched_ptr = nullptr; + bool reset_response_received = false; int reset_transaction_id = 1; cause_c reset_cause = cause_c(); int reset_id = 1; diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 71dd809e8..034f07f5d 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -8,6 +8,8 @@ e2ap::e2ap(srslog::basic_logger& logger, logger(logger), e2sm_(logger), task_sched_ptr(_task_sched_ptr) { gnb_metrics = _gnb_metrics; + e2_procedure_timeout = task_sched_ptr->get_unique_timer(); + // add SMs to map uint32_t local_ran_function_id = 147; RANfunction_description add_func; @@ -155,11 +157,12 @@ e2_ap_pdu_c e2ap::generate_subscription_delete_response(uint32_t ric_requestor_i int e2ap::process_setup_response(e2setup_resp_s setup_response) { - setup_response_received = true; if (setup_procedure_transaction_id == setup_response->transaction_id.value.value) { setup_procedure_transaction_id++; + e2_established = true; } else { logger.error("Received setup response with wrong transaction id"); + return SRSRAN_ERROR; } global_ric_id.plmn_id = setup_response->global_ric_id.value.plmn_id.to_number(); global_ric_id.ric_id = setup_response->global_ric_id.value.ric_id.to_number(); @@ -175,14 +178,13 @@ int e2ap::process_setup_response(e2setup_resp_s setup_response) } } } - return 0; + return SRSRAN_SUCCESS; } int e2ap::process_subscription_request(ricsubscription_request_s subscription_request) { - pending_subscription_request = true; // TODO: this function seems to be not needed - return 0; + return SRSRAN_SUCCESS; } e2_ap_pdu_c e2ap::generate_indication(ric_indication_t& ric_indication) @@ -254,7 +256,7 @@ int e2ap::process_reset_request(reset_request_s reset_request) // TO DO: Parse and store the cause for future extension of the ric client - return 0; + return SRSRAN_SUCCESS; } int e2ap::process_reset_response(reset_resp_s reset_response) @@ -262,10 +264,53 @@ int e2ap::process_reset_response(reset_resp_s reset_response) // TO DO process reset response from RIC reset_response_received = true; - return 0; + return SRSRAN_SUCCESS; } int e2ap::get_reset_id() { return reset_id; } + +// implementation of e2ap failure functions +int e2ap::process_e2_setup_failure(e2setup_fail_s e2setup_failure) +{ + if (setup_procedure_transaction_id == e2setup_failure->transaction_id.value.value) { + setup_procedure_transaction_id++; + } else { + logger.error("Received setup failure with wrong transaction id"); + } + if (e2setup_failure->tn_linfo_present) { + logger.error("Received setup failure with transport layer info"); + } + if (e2setup_failure->time_to_wait_present) { + logger.error("Received setup failure with time to wait"); + e2_procedure_timeout.set(e2setup_failure->time_to_wait.value.to_number(), [this](int trans_id) { + logger.info("E2AP procedure timeout expired transaction id %d", trans_id); + pending_e2_setup = false; + }); + e2_procedure_timeout.run(); + } + return SRSRAN_SUCCESS; +} + +int e2ap::process_e2_node_config_update_failure(e2node_cfg_upd_fail_s e2node_config_update_failure) +{ + pending_e2_node_config_update = false; + + return SRSRAN_SUCCESS; +} + +int e2ap::process_ric_service_update_failure(ricservice_upd_fail_s service_update_failure) +{ + pending_ric_service_update = false; + + return SRSRAN_SUCCESS; +} + +int e2ap::process_e2_removal_failure(e2_removal_fail_s e2removal_failure) +{ + pending_e2_removal = false; + + return SRSRAN_SUCCESS; +} diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 67b523093..600b41ada 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -78,7 +78,7 @@ void ric_client::run_thread() using namespace asn1::e2ap; while (running) { - if (!e2ap_.has_setup_response()) { + if (e2ap_.send_setup_request()) { send_e2_msg(E2_SETUP_REQUEST); printf("e2 setup request sent\n"); } @@ -180,7 +180,7 @@ bool ric_client::handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, handle_e2_successful_outcome(pdu_c.successful_outcome()); } else if (pdu_c.type().value == e2_ap_pdu_c::types_opts::unsuccessful_outcome) { logger.info("Received E2AP Unsuccessful Outcome "); - // handle_e2_unsuccessful_outcome(pdu_c.unsuccessful_outcome()); + handle_e2_unsuccessful_outcome(pdu_c.unsuccessful_outcome()); } else { logger.warning("Received E2AP Unknown Message "); } @@ -258,8 +258,37 @@ bool ric_client::handle_e2_setup_response(e2setup_resp_s setup_response) bool ric_client::handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome) { using namespace asn1::e2ap; - // TODO check for different type of RIC generated unsuccessful outcomes - // eg. RIC subscription failure, RIC Reset failure, RIC control failure, RIC subscription delete failure + if (unsuccessful_outcome.value.type() == e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::e2setup_fail) { + logger.info("Received E2AP E2 Setup Failure"); + if (e2ap_.process_e2_setup_failure(unsuccessful_outcome.value.e2setup_fail())) { + logger.error("Failed to process E2 Setup Failure \n"); + return false; + } + } else if (unsuccessful_outcome.value.type() == + e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::e2node_cfg_upd_fail) { + logger.info("Received E2node configuration update Failure"); + if (e2ap_.process_e2_node_config_update_failure(unsuccessful_outcome.value.e2node_cfg_upd_fail())) { + logger.error("Failed to process E2node configuration update Failure \n"); + return false; + } + } else if (unsuccessful_outcome.value.type() == + e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::ricservice_upd_fail) { + logger.info("Received E2AP RIC Service Update Failure \n"); + if (e2ap_.process_ric_service_update_failure(unsuccessful_outcome.value.ricservice_upd_fail())) { + logger.error("Failed to process RIC service update failure \n"); + return false; + } + } else if (unsuccessful_outcome.value.type() == + e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::e2_removal_fail) { + logger.info("Received E2AP removal Unsuccessful Outcome \n"); + if (e2ap_.process_e2_removal_failure(unsuccessful_outcome.value.e2_removal_fail())) { + logger.error("Failed to process RIC service status failure \n"); + return false; + } + } else { + logger.info("Received E2AP Unknown Unsuccessful Outcome \n"); + } + return true; } From 9a03eb56351f958783a9a9bac725b91ae668c717 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 23:41:07 +0100 Subject: [PATCH 072/167] e2ap: fix initialization order to avoid enb crashing --- srsgnb/hdr/stack/ric/ric_client.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index 909438808..c99821539 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -72,14 +72,15 @@ public: class ric_subscription; private: - e2ap e2ap_; - srsran::unique_socket ric_socket; - srsran::task_queue_handle ric_rece_task_queue; srsran::task_scheduler task_sched; + srsran::task_queue_handle ric_rece_task_queue; + srsran::unique_socket ric_socket; srsran::socket_manager rx_sockets; srslog::basic_logger& logger; struct sockaddr_in ric_addr = {}; // RIC address bool running = false; + + e2ap e2ap_; srsenb::e2_interface_metrics* gnb_metrics = nullptr; std::vector > active_subscriptions; From 2047c1b62ca83f43095eacf49fdc8b6aa277198f Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 21 Mar 2023 23:41:14 +0100 Subject: [PATCH 073/167] e2ap: allow send setup_request --- srsgnb/hdr/stack/ric/e2ap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 5c615ca6d..5949a9097 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -79,7 +79,7 @@ private: e2sm_kpm e2sm_; bool e2_established = false; srsran::unique_timer e2_procedure_timeout; - bool pending_e2_setup = false; + bool pending_e2_setup = true; bool pending_e2_node_config_update = false; bool pending_ric_service_update = false; bool pending_e2_removal = false; From 0c7d499250ec0cf32685d585ae9280d431c57fdd Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 22 Mar 2023 15:43:48 +0100 Subject: [PATCH 074/167] e2ap: add RIC indication SN --- srsgnb/hdr/stack/ric/e2sm.h | 2 ++ srsgnb/hdr/stack/ric/ric_subscription.h | 3 +++ srsgnb/src/stack/ric/e2ap.cc | 6 ++++++ srsgnb/src/stack/ric/ric_subscription.cc | 12 ++++++++++++ 4 files changed, 23 insertions(+) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index 54df1a31b..242936812 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -39,6 +39,8 @@ typedef struct { uint32_t ric_instance_id; uint32_t ra_nfunction_id; uint32_t ri_caction_id; + bool ri_indication_sn_present; + uint32_t ri_indication_sn; ri_cind_type_e indication_type; srsran::unique_byte_buffer_t ri_cind_hdr; srsran::unique_byte_buffer_t ri_cind_msg; diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index 85782d7aa..b3c0381ad 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -38,6 +38,7 @@ public: private: void send_ric_indication(); + uint32_t _generate_ric_indication_sn(); ric_client* parent = nullptr; bool initialized = false; @@ -52,6 +53,8 @@ private: std::vector admitted_actions; std::vector not_admitted_actions; + + uint32_t _ric_indication_sn_gen = 0; }; } // namespace srsenb diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 034f07f5d..667d365c5 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -207,6 +207,12 @@ e2_ap_pdu_c e2ap::generate_indication(ric_indication_t& ric_indication) indication->ri_caction_id.crit = asn1::crit_opts::reject; indication->ri_caction_id.value = ric_indication.ri_caction_id; + if (ric_indication.ri_indication_sn_present) { + indication->ri_cind_sn_present = true; + indication->ri_cind_sn.crit = asn1::crit_opts::reject; + indication->ri_cind_sn->value = ric_indication.ri_indication_sn; + } + indication->ri_cind_type.crit = asn1::crit_opts::reject; indication->ri_cind_type.value = ric_indication.indication_type; diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 24dcef893..7d1a2ad5f 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -140,6 +140,16 @@ void ric_client::ric_subscription::delete_subscription() parent->queue_send_e2ap_pdu(send_pdu); } +uint32_t ric_client::ric_subscription::_generate_ric_indication_sn() +{ + uint32_t sn = _ric_indication_sn_gen; + _ric_indication_sn_gen++; + if (_ric_indication_sn_gen > 65535) { + _ric_indication_sn_gen = 0; + } + return sn; +}; + void ric_client::ric_subscription::send_ric_indication() { if (sm_ptr == nullptr) { @@ -154,6 +164,8 @@ void ric_client::ric_subscription::send_ric_indication() ric_indication.ric_instance_id = ric_instance_id; ric_indication.ra_nfunction_id = ra_nfunction_id; ric_indication.ri_caction_id = action.ric_action_id; + ric_indication.ri_indication_sn_present = true; + ric_indication.ri_indication_sn = _generate_ric_indication_sn(); sm_ptr->execute_action_fill_ric_indication(action, ric_indication); e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(ric_indication); From 15d3cc54bd3ea5549fc2d30f5927a05e3bea2627 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 22 Mar 2023 16:02:45 +0100 Subject: [PATCH 075/167] e2ap: change generate_subscription_delete_response signature --- srsgnb/hdr/stack/ric/e2ap.h | 3 +-- srsgnb/src/stack/ric/e2ap.cc | 10 ++++------ srsgnb/src/stack/ric/ric_subscription.cc | 7 +++++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 5949a9097..de66d9516 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -57,8 +57,7 @@ public: int process_subscription_request(ricsubscription_request_s subscription_request); e2_ap_pdu_c generate_subscription_response(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_subscription_failure(ric_subscription_reponse_t ric_subscription_reponse); - e2_ap_pdu_c - generate_subscription_delete_response(uint32_t ric_requestor_id, uint32_t ric_instance_id, uint32_t ra_nfunction_id); + e2_ap_pdu_c generate_subscription_delete_response(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_indication(ric_indication_t& ric_indication); e2_ap_pdu_c generate_reset_request(); e2_ap_pdu_c generate_reset_response(); diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 667d365c5..426280666 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -135,9 +135,7 @@ e2_ap_pdu_c e2ap::generate_subscription_failure(ric_subscription_reponse_t ric_s return pdu; } -e2_ap_pdu_c e2ap::generate_subscription_delete_response(uint32_t ric_requestor_id, - uint32_t ric_instance_id, - uint32_t ra_nfunction_id) +e2_ap_pdu_c e2ap::generate_subscription_delete_response(ric_subscription_reponse_t ric_subscription_reponse) { e2_ap_pdu_c pdu; successful_outcome_s& success = pdu.set_successful_outcome(); @@ -146,11 +144,11 @@ e2_ap_pdu_c e2ap::generate_subscription_delete_response(uint32_t ric_requestor_i ricsubscription_delete_resp_s& sub_resp = success.value.ricsubscription_delete_resp(); sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; - sub_resp->ri_crequest_id->ric_requestor_id = ric_requestor_id; - sub_resp->ri_crequest_id->ric_instance_id = ric_instance_id; + sub_resp->ri_crequest_id->ric_requestor_id = ric_subscription_reponse.ric_requestor_id; + sub_resp->ri_crequest_id->ric_instance_id = ric_subscription_reponse.ric_instance_id; sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; - sub_resp->ra_nfunction_id->value = ra_nfunction_id; + sub_resp->ra_nfunction_id->value = ric_subscription_reponse.ra_nfunction_id; return pdu; } diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 7d1a2ad5f..e95e78b22 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -135,8 +135,11 @@ void ric_client::ric_subscription::delete_subscription() } parent->logger.debug("Send RIC Subscription Delete Response to RIC Requestor ID: %i\n", ric_requestor_id); - e2_ap_pdu_c send_pdu = - parent->e2ap_.generate_subscription_delete_response(ric_requestor_id, ric_instance_id, ra_nfunction_id); + ric_subscription_reponse_t ric_subscription_reponse; + ric_subscription_reponse.ric_requestor_id = ric_requestor_id; + ric_subscription_reponse.ric_instance_id = ric_instance_id; + ric_subscription_reponse.ra_nfunction_id = ra_nfunction_id; + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_delete_response(ric_subscription_reponse); parent->queue_send_e2ap_pdu(send_pdu); } From 53280294e752a665031151a4b768628efbc24ef9 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 22 Mar 2023 16:04:30 +0100 Subject: [PATCH 076/167] e2ap: add generate_subscription_delete_failure --- srsgnb/hdr/stack/ric/e2ap.h | 1 + srsgnb/src/stack/ric/e2ap.cc | 23 +++++++++++++++++++++++ srsgnb/src/stack/ric/ric_subscription.cc | 14 ++++++++++---- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index de66d9516..c539de8ba 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -58,6 +58,7 @@ public: e2_ap_pdu_c generate_subscription_response(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_subscription_failure(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_subscription_delete_response(ric_subscription_reponse_t ric_subscription_reponse); + e2_ap_pdu_c generate_subscription_delete_failure(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_indication(ric_indication_t& ric_indication); e2_ap_pdu_c generate_reset_request(); e2_ap_pdu_c generate_reset_response(); diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 426280666..a2527d68a 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -153,6 +153,29 @@ e2_ap_pdu_c e2ap::generate_subscription_delete_response(ric_subscription_reponse return pdu; } +e2_ap_pdu_c e2ap::generate_subscription_delete_failure(ric_subscription_reponse_t ric_subscription_reponse) +{ + e2_ap_pdu_c pdu; + unsuccessful_outcome_s& failure = pdu.set_unsuccessful_outcome(); + failure.load_info_obj(ASN1_E2AP_ID_RICSUBSCRIPTION); + failure.crit = asn1::crit_opts::reject; + ricsubscription_delete_fail_s& sub_resp = failure.value.ricsubscription_delete_fail(); + + sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; + sub_resp->ri_crequest_id.id = ASN1_E2AP_ID_RI_CREQUEST_ID; + sub_resp->ri_crequest_id.value.ric_requestor_id = ric_subscription_reponse.ric_requestor_id; + sub_resp->ri_crequest_id.value.ric_instance_id = ric_subscription_reponse.ric_instance_id; + + sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; + sub_resp->ra_nfunction_id.id = ASN1_E2AP_ID_RA_NFUNCTION_ID; + sub_resp->ra_nfunction_id->value = ric_subscription_reponse.ra_nfunction_id; + + sub_resp->cause->set_misc(); // TODO: set the cause and crit_diagnostics properly + sub_resp->crit_diagnostics_present = false; + + return pdu; +} + int e2ap::process_setup_response(e2setup_resp_s setup_response) { if (setup_procedure_transaction_id == setup_response->transaction_id.value.value) { diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index e95e78b22..22e37149e 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -127,18 +127,24 @@ void ric_client::ric_subscription::delete_subscription() reporting_timer.stop(); } + ric_subscription_reponse_t ric_subscription_reponse; + ric_subscription_reponse.ric_requestor_id = ric_requestor_id; + ric_subscription_reponse.ric_instance_id = ric_instance_id; + ric_subscription_reponse.ra_nfunction_id = ra_nfunction_id; + // remove registered actions from SM if (sm_ptr) { for (auto& action : admitted_actions) { sm_ptr->remove_ric_action_definition(action); } + } else { + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_delete_failure(ric_subscription_reponse); + parent->queue_send_e2ap_pdu(send_pdu); + return; } parent->logger.debug("Send RIC Subscription Delete Response to RIC Requestor ID: %i\n", ric_requestor_id); - ric_subscription_reponse_t ric_subscription_reponse; - ric_subscription_reponse.ric_requestor_id = ric_requestor_id; - ric_subscription_reponse.ric_instance_id = ric_instance_id; - ric_subscription_reponse.ra_nfunction_id = ra_nfunction_id; + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_delete_response(ric_subscription_reponse); parent->queue_send_e2ap_pdu(send_pdu); } From a54e18e686be41e37e79cf07acec801f74b39b6f Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 22 Mar 2023 16:35:10 +0100 Subject: [PATCH 077/167] e2ap: add all RIC subscription API funcs --- srsgnb/hdr/stack/ric/e2ap.h | 5 +++++ srsgnb/hdr/stack/ric/ric_subscription.h | 4 ++++ srsgnb/src/stack/ric/e2ap.cc | 28 ++++++++++++++++++++++++ srsgnb/src/stack/ric/ric_subscription.cc | 21 ++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index c539de8ba..0ff57e664 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -59,6 +59,11 @@ public: e2_ap_pdu_c generate_subscription_failure(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_subscription_delete_response(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_subscription_delete_failure(ric_subscription_reponse_t ric_subscription_reponse); + e2_ap_pdu_c generate_subscription_delete_required(ric_subscription_reponse_t ric_subscription_reponse); + e2_ap_pdu_c generate_subscription_modification_response(); + e2_ap_pdu_c generate_subscription_modification_failure(); + e2_ap_pdu_c generate_subscription_modification_required(); + e2_ap_pdu_c generate_indication(ric_indication_t& ric_indication); e2_ap_pdu_c generate_reset_request(); e2_ap_pdu_c generate_reset_response(); diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index b3c0381ad..140c26b43 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -36,6 +36,10 @@ public: void send_subscription_failure(); void delete_subscription(); + bool handle_subscription_modification_request(uint32_t ric_subscription_modification_request); + bool handle_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm); + bool handle_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse); + private: void send_ric_indication(); uint32_t _generate_ric_indication_sn(); diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index a2527d68a..b62b44e16 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -176,6 +176,34 @@ e2_ap_pdu_c e2ap::generate_subscription_delete_failure(ric_subscription_reponse_ return pdu; } +e2_ap_pdu_c e2ap::generate_subscription_delete_required(ric_subscription_reponse_t ric_subscription_reponse) +{ + // TODO: available in e2ap-v3 + e2_ap_pdu_c pdu; + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_modification_response() +{ + // TODO: available in e2ap-v3 + e2_ap_pdu_c pdu; + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_modification_failure() +{ + // TODO: available in e2ap-v3 + e2_ap_pdu_c pdu; + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_modification_required() +{ + // TODO: available in e2ap-v3 + e2_ap_pdu_c pdu; + return pdu; +} + int e2ap::process_setup_response(e2setup_resp_s setup_response) { if (setup_procedure_transaction_id == setup_response->transaction_id.value.value) { diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 22e37149e..1eeb1dd81 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -149,6 +149,27 @@ void ric_client::ric_subscription::delete_subscription() parent->queue_send_e2ap_pdu(send_pdu); } +bool ric_client::ric_subscription::handle_subscription_modification_request( + uint32_t ric_subscription_modification_request) +{ + // TODO: available in e2ap-v3 + return false; +} + +bool ric_client::ric_subscription::handle_subscription_modification_confirm( + uint32_t ric_subscription_modification_confirm) +{ + // TODO: available in e2ap-v3 + return false; +} + +bool ric_client::ric_subscription::handle_subscription_modification_refuse( + uint32_t ric_subscription_modification_refuse) +{ + // TODO: available in e2ap-v3 + return false; +} + uint32_t ric_client::ric_subscription::_generate_ric_indication_sn() { uint32_t sn = _ric_indication_sn_gen; From 91141e41ad925290d104a334c2d35e0954d27db3 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 22 Mar 2023 18:01:18 +0100 Subject: [PATCH 078/167] e2sm_kpm: add definition of supported metrics --- srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h | 78 +++++++++++++++++++++++++ srsgnb/src/stack/ric/e2sm_kpm.cc | 25 +++++++- 2 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h new file mode 100644 index 000000000..162086c50 --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h @@ -0,0 +1,78 @@ +/** + * + * \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. + * + * + */ + +#ifndef SRSRAN_E2SM_KPM_METRICS_H +#define SRSRAN_E2SM_KPM_METRICS_H + +#include "srsran/srsran.h" + +#define NO_LABEL 0x0001 +#define MIN_LABEL 0x0002 +#define MAX_LABEL 0x0004 +#define AVG_LABEL 0x0008 + +enum e2_metric_data_type_t { INTEGER, REAL }; + +struct E2SM_KPM_metric_t { + std::string name; + e2_metric_data_type_t data_type; + std::string units; + bool min_val_present; + double min_val; + bool max_val_present; + double max_val; + uint32_t supported_labels; + bool supported; +}; + +// Measurements defined in 3GPP TS 28.552 +std::vector get_e2sm_kpm_28_552_metrics() +{ + // TODO: add all metrics from 3GPP TS 28.552 + std::vector metrics; + // supported metrics + metrics.push_back({"RRU.PrbTotDl", REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, true}); + metrics.push_back({"RRU.PrbTotUl", REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, true}); + // not supported metrics + metrics.push_back({"RRU.RachPreambleDedMean", REAL, "%", false, 0, false, 100, NO_LABEL, false}); + return metrics; +} + +// Measurements defined in 3GPP TS 32.425 +std::vector get_e2sm_kpm_34_425_metrics() +{ + // TODO: add all metrics from 3GPP TS 32.425 + std::vector metrics; + return metrics; +} + +// E2SM_KPM O-RAN specific Measurements +std::vector e2sm_kpm_oran_metrics() +{ + // TODO: add all E2SM_KPM O-RAN specific Measurements + std::vector metrics; + return metrics; +} + +// Custom Measurements +std::vector e2sm_kpm_custom_metrics() +{ + std::vector metrics; + // supported metrics + metrics.push_back({"test", REAL, "", true, 0, true, 100, NO_LABEL, true}); + // not supported metrics + metrics.push_back({"test123", REAL, "", true, 0, true, 100, NO_LABEL, false}); + return metrics; +} + +#endif // SRSRAN_E2SM_KPM_METRICS_H diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 9309b3aca..9897ac716 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -1,4 +1,5 @@ #include "srsgnb/hdr/stack/ric/e2sm_kpm.h" +#include "srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h" 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"; @@ -9,9 +10,27 @@ e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_d { random_gen = srsran_random_init(1234); - supported_meas_types.push_back("RRU.PrbTotDl"); - supported_meas_types.push_back("RRU.PrbTotUl"); - supported_meas_types.push_back("test"); + // add supported metrics + for (auto& metric : get_e2sm_kpm_28_552_metrics()) { + if (metric.supported) { + supported_meas_types.push_back(metric.name); + } + } + for (auto& metric : get_e2sm_kpm_34_425_metrics()) { + if (metric.supported) { + supported_meas_types.push_back(metric.name); + } + } + for (auto& metric : e2sm_kpm_oran_metrics()) { + if (metric.supported) { + supported_meas_types.push_back(metric.name); + } + } + for (auto& metric : e2sm_kpm_custom_metrics()) { + if (metric.supported) { + supported_meas_types.push_back(metric.name); + } + } } bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func) From 6e85882551cc8e81e75b4d0ab09d7678309e1055 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 22 Mar 2023 18:06:56 +0100 Subject: [PATCH 079/167] e2ap: remove subscription if no action admitted --- srsgnb/src/stack/ric/ric_subscription.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 1eeb1dd81..09cb2ac46 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -78,6 +78,13 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli not_admitted_actions.push_back(action_item.ric_action_id); } } + + if (admitted_actions.size() == 0) { + parent->logger.debug("No Action admitted -> remove subscription for RAN function id: %i", ra_nfunction_id); + printf("No Action admitted -> remove subscription for RAN function id: %i\n", ra_nfunction_id); + return; + } + initialized = true; } From 80f6d5a762a39a8549f18db63d38ca79b40b1726 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 22 Mar 2023 18:12:14 +0100 Subject: [PATCH 080/167] e2ap: change _send_subscription_response and _send_subscription_failure --- srsgnb/hdr/stack/ric/ric_subscription.h | 3 ++- srsgnb/src/stack/ric/ric_client.cc | 1 - srsgnb/src/stack/ric/ric_subscription.cc | 24 ++++++++++++++++-------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index 140c26b43..48798e83c 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -33,7 +33,6 @@ public: bool is_initialized() { return initialized; }; void start_subscription(); - void send_subscription_failure(); void delete_subscription(); bool handle_subscription_modification_request(uint32_t ric_subscription_modification_request); @@ -41,6 +40,8 @@ public: bool handle_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse); private: + void _send_subscription_response(); + void _send_subscription_failure(); void send_ric_indication(); uint32_t _generate_ric_indication_sn(); diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 600b41ada..010dea651 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -306,7 +306,6 @@ bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_s new_ric_subs->start_subscription(); active_subscriptions.push_back(std::move(new_ric_subs)); } else { - new_ric_subs->send_subscription_failure(); return false; } diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 09cb2ac46..fbbae94fa 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -27,12 +27,14 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli RANfunction_description ran_func_desc; if (!parent->e2ap_.get_func_desc(ra_nfunction_id, ran_func_desc)) { parent->logger.debug("Cannot find RAN function with ID: %i\n", ra_nfunction_id); + this->_send_subscription_failure(); return; } sm_ptr = ran_func_desc.sm_ptr; if (sm_ptr == nullptr) { parent->logger.debug("No valid pointer to SM with RAN function id: %i\n", ra_nfunction_id); + this->_send_subscription_failure(); return; } @@ -82,6 +84,7 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli if (admitted_actions.size() == 0) { parent->logger.debug("No Action admitted -> remove subscription for RAN function id: %i", ra_nfunction_id); printf("No Action admitted -> remove subscription for RAN function id: %i\n", ra_nfunction_id); + this->_send_subscription_failure(); return; } @@ -89,6 +92,18 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli } void ric_client::ric_subscription::start_subscription() +{ + this->_send_subscription_response(); + + if (reporting_period) { + printf("Start sending RIC indication msgs every %i ms\n", reporting_period); + parent->logger.debug("Start sending RIC indication msgs every %i ms", reporting_period); + reporting_timer.set(reporting_period, [this](uint32_t tid) { send_ric_indication(); }); + reporting_timer.run(); + } +} + +void ric_client::ric_subscription::_send_subscription_response() { parent->logger.debug("Send RIC Subscription Response to RIC Requestor ID: %i\n", ric_requestor_id); ric_subscription_reponse_t ric_subscription_reponse; @@ -106,16 +121,9 @@ void ric_client::ric_subscription::start_subscription() e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_response(ric_subscription_reponse); parent->queue_send_e2ap_pdu(send_pdu); - - if (reporting_period) { - printf("Start sending RIC indication msgs every %i ms\n", reporting_period); - parent->logger.debug("Start sending RIC indication msgs every %i ms", reporting_period); - reporting_timer.set(reporting_period, [this](uint32_t tid) { send_ric_indication(); }); - reporting_timer.run(); - } } -void ric_client::ric_subscription::send_subscription_failure() +void ric_client::ric_subscription::_send_subscription_failure() { parent->logger.debug("Send RIC Subscription Failure Response to RIC Requestor ID: %i\n", ric_requestor_id); ric_subscription_reponse_t ric_subscription_reponse; From 9d7bfcc9c9ac46c2d29a2985b3306bd5c2268344 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 23 Mar 2023 08:58:39 +0100 Subject: [PATCH 081/167] e2sm_kpm: update metric definitions --- srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h index 162086c50..e96afbe66 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h @@ -16,15 +16,24 @@ #include "srsran/srsran.h" +/* Labels supported for a metric */ #define NO_LABEL 0x0001 #define MIN_LABEL 0x0002 #define MAX_LABEL 0x0004 #define AVG_LABEL 0x0008 +// TODO: define all labels and scopes + +/* Scopes supported for a metric */ +#define ENB_LEVEL 0x0001 +#define CELL_LEVEL 0x0002 +#define UE_LEVEL 0x0004 +#define BEARER_LEVEL 0x0008 enum e2_metric_data_type_t { INTEGER, REAL }; struct E2SM_KPM_metric_t { std::string name; + bool supported; e2_metric_data_type_t data_type; std::string units; bool min_val_present; @@ -32,19 +41,20 @@ struct E2SM_KPM_metric_t { bool max_val_present; double max_val; uint32_t supported_labels; - bool supported; + uint32_t supported_scopes; }; +// clang-format off // Measurements defined in 3GPP TS 28.552 std::vector get_e2sm_kpm_28_552_metrics() { // TODO: add all metrics from 3GPP TS 28.552 std::vector metrics; // supported metrics - metrics.push_back({"RRU.PrbTotDl", REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, true}); - metrics.push_back({"RRU.PrbTotUl", REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, true}); + metrics.push_back({"RRU.PrbTotDl", true, REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, CELL_LEVEL | UE_LEVEL }); + metrics.push_back({"RRU.PrbTotUl", true, REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, CELL_LEVEL | UE_LEVEL }); // not supported metrics - metrics.push_back({"RRU.RachPreambleDedMean", REAL, "%", false, 0, false, 100, NO_LABEL, false}); + metrics.push_back({"RRU.RachPreambleDedMean", false, REAL, "-", false, 0, false, 100, NO_LABEL, CELL_LEVEL | UE_LEVEL }); return metrics; } @@ -69,10 +79,11 @@ std::vector e2sm_kpm_custom_metrics() { std::vector metrics; // supported metrics - metrics.push_back({"test", REAL, "", true, 0, true, 100, NO_LABEL, true}); + metrics.push_back({"test", true, REAL, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL | UE_LEVEL }); // not supported metrics - metrics.push_back({"test123", REAL, "", true, 0, true, 100, NO_LABEL, false}); + metrics.push_back({"test123", false, REAL, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL | UE_LEVEL }); return metrics; } +// clang-format on #endif // SRSRAN_E2SM_KPM_METRICS_H From d5d876ecb033c8ecc0cc521ec1b0543597fb1af9 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 23 Mar 2023 10:33:32 +0100 Subject: [PATCH 082/167] e2ap: send metrics to all registred e2am instances --- .../srsran/interfaces/e2_metrics_interface.h | 4 ++++ srsenb/hdr/metrics_e2.h | 4 ++++ srsenb/src/metrics_e2.cc | 21 +++++++++++++++++++ srsgnb/hdr/stack/ric/e2sm.h | 4 ++++ srsgnb/hdr/stack/ric/e2sm_kpm.h | 4 ++++ srsgnb/src/stack/ric/e2ap.cc | 3 +++ srsgnb/src/stack/ric/e2sm_kpm.cc | 9 ++++++++ 7 files changed, 49 insertions(+) diff --git a/lib/include/srsran/interfaces/e2_metrics_interface.h b/lib/include/srsran/interfaces/e2_metrics_interface.h index 0328c56d8..d09a8d53b 100644 --- a/lib/include/srsran/interfaces/e2_metrics_interface.h +++ b/lib/include/srsran/interfaces/e2_metrics_interface.h @@ -10,6 +10,7 @@ * */ +#include "srsgnb/hdr/stack/ric/e2sm.h" #include "srsran/common/common.h" #include "srsran/common/interfaces_common.h" #include "srsran/interfaces/enb_metrics_interface.h" @@ -24,6 +25,9 @@ class e2_interface_metrics { public: virtual bool pull_metrics(enb_metrics_t* m) = 0; + + virtual bool register_e2sm(e2sm* sm) = 0; + virtual bool unregister_e2sm(e2sm* sm) = 0; }; } // namespace srsenb diff --git a/srsenb/hdr/metrics_e2.h b/srsenb/hdr/metrics_e2.h index 63aea1842..873c41883 100644 --- a/srsenb/hdr/metrics_e2.h +++ b/srsenb/hdr/metrics_e2.h @@ -36,11 +36,15 @@ public: bool pull_metrics(enb_metrics_t* m) override; void stop(){}; + bool register_e2sm(e2sm* sm) override; + bool unregister_e2sm(e2sm* sm) override; + private: std::atomic do_print = {false}; uint8_t n_reports = 0; std::queue metrics_queue; enb_metrics_interface* enb = nullptr; + std::vector e2sm_vec; }; } // namespace srsenb diff --git a/srsenb/src/metrics_e2.cc b/srsenb/src/metrics_e2.cc index ffc0f897f..4be8cb701 100644 --- a/srsenb/src/metrics_e2.cc +++ b/srsenb/src/metrics_e2.cc @@ -23,6 +23,27 @@ void metrics_e2::set_metrics(const enb_metrics_t& m, const uint32_t period_usec) } else { metrics_queue.push(m); } + + // send new enb metrics to all registered SMs + for (auto sm_ : e2sm_vec) { + sm_->receive_e2_metrics_callback(m); + } +} + +bool metrics_e2::register_e2sm(e2sm* sm) +{ + e2sm_vec.push_back(sm); + return true; +} + +bool metrics_e2::unregister_e2sm(e2sm* sm) +{ + auto it = std::find(e2sm_vec.begin(), e2sm_vec.end(), sm); + if (it != e2sm_vec.end()) { + e2sm_vec.erase(it); + return true; + } + return false; } bool metrics_e2::pull_metrics(enb_metrics_t* m) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index 242936812..bb2cf1ed0 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -13,12 +13,14 @@ #include "srsran/asn1/e2ap.h" #include "srsran/common/byte_buffer.h" +#include "srsran/interfaces/enb_metrics_interface.h" #include "srsran/srsran.h" #ifndef SRSRAN_E2SM_H #define SRSRAN_E2SM_H using namespace asn1::e2ap; +using namespace srsenb; struct RANfunction_description; @@ -67,6 +69,8 @@ public: virtual bool remove_ric_action_definition(E2AP_RIC_action_t& action_entry) = 0; virtual bool execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication) = 0; + virtual void receive_e2_metrics_callback(const enb_metrics_t& m) = 0; + protected: uint32_t _generate_local_action_id() { return _registered_action_id_gen++; }; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index ed7a47a26..4e6d5d4b3 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -55,6 +55,8 @@ public: virtual bool remove_ric_action_definition(E2AP_RIC_action_t& action_entry); virtual bool execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication); + virtual void receive_e2_metrics_callback(const enb_metrics_t& m); + private: bool _process_ric_action_definition_format1(e2_sm_kpm_action_definition_format1_s& action_definition_format1); bool _process_ric_action_definition_format2(e2_sm_kpm_action_definition_format2_s& action_definition_format2); @@ -77,6 +79,8 @@ private: std::map registered_actions; srsran_random_t random_gen; + + enb_metrics_t last_enb_metrics; }; #endif /*E2SM_KPM*/ diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index b62b44e16..6b8b40dbc 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -10,6 +10,9 @@ e2ap::e2ap(srslog::basic_logger& logger, gnb_metrics = _gnb_metrics; e2_procedure_timeout = task_sched_ptr->get_unique_timer(); + // register SM to receive enb metrics + gnb_metrics->register_e2sm(&e2sm_); + // add SMs to map uint32_t local_ran_function_id = 147; RANfunction_description add_func; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 9897ac716..751931348 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -33,6 +33,15 @@ e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_d } } +void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) +{ + last_enb_metrics = m; + logger.debug("e2sm_kpm received new enb metrics, CPU0 Load: %.1f", last_enb_metrics.sys.cpu_load[0]); + + // TODO: for INSERT type of reporting check if a specified metrics exceeds predefined thresholds, + // if so then send RIC indication throught proper subscription +} + bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func) { desc.function_shortname = short_name; From 3a6cd77e9cc4760a51d56f96f6eed520af058c33 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 23 Mar 2023 12:09:39 +0100 Subject: [PATCH 083/167] e2ap: add missing implementation to dummy interface in test --- srsgnb/src/stack/ric/test/e2ap_test.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index c589be1ad..4a8e3ebe9 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -8,6 +8,8 @@ class dummy_metrics_interface : public srsenb::e2_interface_metrics { bool pull_metrics(srsenb::enb_metrics_t* m) { return true; } + bool register_e2sm(e2sm* sm) { return true; } + bool unregister_e2sm(e2sm* sm) { return true; } }; // function to test the encoding of the E2AP message void test_reference_e2ap_setup_request() From 8bac9211a0173d1d345c7e6d868ad5af7a4f3029 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 23 Mar 2023 13:01:53 +0100 Subject: [PATCH 084/167] e2sm_kpm: store definitions of the supported metrics --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 17 ++++++++++++++++- srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h | 16 +--------------- srsgnb/src/stack/ric/e2sm_kpm.cc | 11 ++++++----- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 4e6d5d4b3..009f5c754 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -37,6 +37,21 @@ typedef struct { uint64_t granul_period; } E2SM_KPM_RIC_ind_message_t; +enum e2_metric_data_type_t { INTEGER, REAL }; + +typedef struct { + std::string name; + bool supported; + e2_metric_data_type_t data_type; + std::string units; + bool min_val_present; + double min_val; + bool max_val_present; + double max_val; + uint32_t supported_labels; + uint32_t supported_scopes; +} E2SM_KPM_metric_t; + class e2sm_kpm : public e2sm { public: @@ -75,7 +90,7 @@ private: bool _generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); srslog::basic_logger& logger; - std::vector supported_meas_types; + std::vector supported_meas_types; std::map registered_actions; srsran_random_t random_gen; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h index e96afbe66..695ed1f3a 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h @@ -14,6 +14,7 @@ #ifndef SRSRAN_E2SM_KPM_METRICS_H #define SRSRAN_E2SM_KPM_METRICS_H +#include "e2sm_kpm.h" #include "srsran/srsran.h" /* Labels supported for a metric */ @@ -29,21 +30,6 @@ #define UE_LEVEL 0x0004 #define BEARER_LEVEL 0x0008 -enum e2_metric_data_type_t { INTEGER, REAL }; - -struct E2SM_KPM_metric_t { - std::string name; - bool supported; - e2_metric_data_type_t data_type; - std::string units; - bool min_val_present; - double min_val; - bool max_val_present; - double max_val; - uint32_t supported_labels; - uint32_t supported_scopes; -}; - // clang-format off // Measurements defined in 3GPP TS 28.552 std::vector get_e2sm_kpm_28_552_metrics() diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 751931348..a59e4dafc 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -13,22 +13,22 @@ e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_d // add supported metrics for (auto& metric : get_e2sm_kpm_28_552_metrics()) { if (metric.supported) { - supported_meas_types.push_back(metric.name); + supported_meas_types.push_back(metric); } } for (auto& metric : get_e2sm_kpm_34_425_metrics()) { if (metric.supported) { - supported_meas_types.push_back(metric.name); + supported_meas_types.push_back(metric); } } for (auto& metric : e2sm_kpm_oran_metrics()) { if (metric.supported) { - supported_meas_types.push_back(metric.name); + supported_meas_types.push_back(metric); } } for (auto& metric : e2sm_kpm_custom_metrics()) { if (metric.supported) { - supported_meas_types.push_back(metric.name); + supported_meas_types.push_back(metric); } } } @@ -212,7 +212,8 @@ bool e2sm_kpm::_process_ric_action_definition_format1(e2_sm_kpm_action_definitio meas_info_list = action_definition_format1.meas_info_list; for (uint32_t i = 0; i < meas_info_list.size(); i++) { std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); - if (std::find(supported_meas_types.begin(), supported_meas_types.end(), meas_name.c_str()) == + auto name_matches = [&meas_name](const E2SM_KPM_metric_t& x) { return x.name == meas_name.c_str(); }; + if (std::find_if(supported_meas_types.begin(), supported_meas_types.end(), name_matches) == supported_meas_types.end()) { printf("Unsupported measurement name: \"%s\" --> do not admit action\n", meas_name.c_str()); return false; From ddfadc9e6fc38915c71990dcc1384aa74d035c16 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 23 Mar 2023 12:15:48 +0100 Subject: [PATCH 085/167] e2sm_kpm: report values from the last enb metrics --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 15 +++ srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h | 5 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 159 ++++++++++++++++++++++-- 3 files changed, 169 insertions(+), 10 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 009f5c754..01c72f27f 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -52,6 +52,14 @@ typedef struct { uint32_t supported_scopes; } E2SM_KPM_metric_t; +typedef struct { + std::string name; + std::string label; + e2_metric_data_type_t data_type; + std::vector integer_values; + std::vector real_values; +} E2SM_KPM_meas_values_t; + class e2sm_kpm : public e2sm { public: @@ -89,6 +97,13 @@ private: bool _generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf); bool _generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); + bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); + bool _get_last_meas_value(E2SM_KPM_meas_values_t& meas_values); + bool _get_last_N_meas_values(uint32_t N, E2SM_KPM_meas_values_t& meas_values); + + bool _get_last_integer_type_meas_value(std::string meas_name, std::string label, int32_t& value); + bool _get_last_real_type_meas_value(std::string meas_name, std::string label, float& value); + srslog::basic_logger& logger; std::vector supported_meas_types; std::map registered_actions; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h index 695ed1f3a..1019505f8 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h @@ -65,7 +65,10 @@ std::vector e2sm_kpm_custom_metrics() { std::vector metrics; // supported metrics - metrics.push_back({"test", true, REAL, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL | UE_LEVEL }); + metrics.push_back({"test", true, INTEGER, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL | UE_LEVEL }); + metrics.push_back({"random_int", true, INTEGER, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL }); + metrics.push_back({"cpu0_load", true, REAL, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL }); + metrics.push_back({"cpu_load", true, REAL, "", true, 0, true, 100, MIN_LABEL|MAX_LABEL|AVG_LABEL, CELL_LEVEL }); // not supported metrics metrics.push_back({"test123", false, REAL, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL | UE_LEVEL }); return metrics; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index a59e4dafc..2af1130b4 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -1,5 +1,19 @@ +/** + * + * \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 "srsgnb/hdr/stack/ric/e2sm_kpm.h" #include "srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h" +#include 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"; @@ -211,15 +225,15 @@ bool e2sm_kpm::_process_ric_action_definition_format1(e2_sm_kpm_action_definitio meas_info_list = action_definition_format1.meas_info_list; for (uint32_t i = 0; i < meas_info_list.size(); i++) { - std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); - auto name_matches = [&meas_name](const E2SM_KPM_metric_t& x) { return x.name == meas_name.c_str(); }; - if (std::find_if(supported_meas_types.begin(), supported_meas_types.end(), name_matches) == - supported_meas_types.end()) { + std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); + E2SM_KPM_metric_t measurement_definition; + if (not _get_meas_definition(meas_name, measurement_definition)) { printf("Unsupported measurement name: \"%s\" --> do not admit action\n", meas_name.c_str()); return false; } printf("Admitted action: measurement name: \"%s\" with the following labels: \n", meas_name.c_str()); + // TODO: all all labels defined in e2sm_kpm doc for (uint32_t l = 0; l < meas_info_list[i].label_info_list.size(); l++) { if (meas_info_list[i].label_info_list[l].meas_label.no_label_present) { printf("--- Label %i: NO LABEL\n", i); @@ -405,14 +419,63 @@ bool e2sm_kpm::_fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format5_s& return false; } +bool e2sm_kpm::_get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def) +{ + // TODO: we need a generic string comparison, why do we need c_str() here? + auto name_matches = [&meas_name](const E2SM_KPM_metric_t& x) { return x.name == meas_name.c_str(); }; + auto it = std::find_if(supported_meas_types.begin(), supported_meas_types.end(), name_matches); + if (it == supported_meas_types.end()) { + return false; + } + def = *it; + return true; +} + +bool e2sm_kpm::_get_last_N_meas_values(uint32_t N, E2SM_KPM_meas_values_t& meas_values) +{ + // TODO: currently only N=1 supported + return _get_last_meas_value(meas_values); +} + void e2sm_kpm::_fill_measurement_records(std::string meas_name, std::string label, meas_record_l& meas_record_list) { - uint32_t nof_records = srsran_random_uniform_int_dist(random_gen, 3, 10); - printf("Fill last N=%i measurements of \"%s\" value for label: %s\n", nof_records, meas_name.c_str(), label.c_str()); + E2SM_KPM_metric_t metric_definition; + if (not _get_meas_definition(meas_name, metric_definition)) { + logger.debug("No definition for measurement type \"%s\"", metric_definition.name); + return; + } + + E2SM_KPM_meas_values_t meas_values; + meas_values.name = meas_name; + // TODO: check if label supported + meas_values.label = label; + meas_values.data_type = metric_definition.data_type; + if (not _get_last_N_meas_values(1, meas_values)) { + logger.debug("No measurement values for type \"%s\" \n", meas_name.c_str()); + return; + } + + if ((meas_values.integer_values.size() + meas_values.real_values.size()) == 0) { + logger.debug("No measurement values for type \"%s\" \n", meas_name.c_str()); + meas_record_list.resize(1); + meas_record_list[0].set_no_value(); + return; + } - meas_record_list.resize(nof_records); - for (uint32_t i = 0; i < nof_records; i++) { - meas_record_list[i].set_integer() = srsran_random_uniform_int_dist(random_gen, 0, 100); + if (meas_values.data_type == e2_metric_data_type_t::INTEGER) { + meas_record_list.resize(meas_values.integer_values.size()); + for (uint32_t i = 0; i < meas_values.integer_values.size(); i++) { + meas_record_list[i].set_integer() = meas_values.integer_values[i]; + } + } else { + // values.data_type == e2_metric_data_type_t::REAL + meas_record_list.resize(meas_values.real_values.size()); + for (uint32_t i = 0; i < meas_values.real_values.size(); i++) { + real_s real_value; + // TODO: real value seems to be not supported in asn1??? + // real_value.value = values.real_values[i]; + meas_record_list[i].set_real() = real_value; + } } } @@ -475,3 +538,81 @@ bool e2sm_kpm::_generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsr return true; } + +bool e2sm_kpm::_get_last_meas_value(E2SM_KPM_meas_values_t& meas_values) +{ + meas_values.data_type = + e2_metric_data_type_t::INTEGER; // TODO: overwrite as REAL seems to be not supported by asn1 now + + if (meas_values.data_type == e2_metric_data_type_t::INTEGER) { + int32_t value; + if (_get_last_integer_type_meas_value(meas_values.name, meas_values.label, value)) { + meas_values.integer_values.push_back(value); + } + } else { + // values.data_type == e2_metric_data_type_t::REAL + float value; + if (_get_last_real_type_meas_value(meas_values.name, meas_values.label, value)) { + meas_values.real_values.push_back(value); + } + } + + return true; +} + +bool e2sm_kpm::_get_last_integer_type_meas_value(std::string meas_name, std::string label, int32_t& value) +{ + // TODO: need to translate labels to enum, maybe also add ID to metric types in e2sm_kpm_metrics definitions + // TODO: make string comparison case insensitive + // all integer type measurements + // random_int: no_label + if (meas_name.c_str() == std::string("test")) { + if (label.c_str() == std::string("no_label")) { + value = (int32_t)last_enb_metrics.sys.cpu_load[0]; + printf("report last \"test\" value as int, (filled with CPU0_load) value %i \n", value); + return true; + } + } + + // random_int: no_label + if (meas_name.c_str() == std::string("random_int")) { + if (label.c_str() == std::string("no_label")) { + value = srsran_random_uniform_int_dist(random_gen, 0, 100); + printf("report last \"random_int\" value as int, random value %i \n", value); + return true; + } + } + + return false; +} + +bool e2sm_kpm::_get_last_real_type_meas_value(std::string meas_name, std::string label, float& value) +{ + // all real type measurements + // cpu0_load: no_label + if (meas_name.c_str() == std::string("cpu0_load")) { + if (label.c_str() == std::string("no_label")) { + value = last_enb_metrics.sys.cpu_load[0]; + return true; + } + } + + // cpu_load: min,max,avg + if (meas_name.c_str() == std::string("cpu_load")) { + if (label.c_str() == std::string("min")) { + value = *std::min_element(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end()); + return true; + } + if (label.c_str() == std::string("max")) { + value = *std::max_element(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end()); + return true; + } + if (label.c_str() == std::string("avg")) { + uint32_t size = last_enb_metrics.sys.cpu_load.size(); + value = std::accumulate(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end(), 0.0 / size); + return true; + } + } + + return false; +} From f0cb38db47b9d132f061de0a455c3cdec20b4a2f Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 23 Mar 2023 15:02:26 +0100 Subject: [PATCH 086/167] e2sm_kpm: metric label is now enum --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 32 +++++++-- srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h | 13 ---- srsgnb/src/stack/ric/e2sm_kpm.cc | 90 ++++++++++++++++--------- 3 files changed, 86 insertions(+), 49 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 01c72f27f..daaa266a1 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -52,9 +52,33 @@ typedef struct { uint32_t supported_scopes; } E2SM_KPM_metric_t; +// TODO: define all labels and scopes + +/* Labels supported for a metric */ +enum e2sm_kpm_label_enum { + NO_LABEL = 0x0001, + MIN_LABEL = 0x0002, + MAX_LABEL = 0x0004, + AVG_LABEL = 0x0008, + SUM_LABEL = 0x0010, + UNKNOWN_LABEL = 0x8000 +}; + +e2sm_kpm_label_enum str2kpm_label(const std::string& label_str); + +/* Scopes supported for a metric */ +enum e2sm_kpm_metric_scope_enum { + ENB_LEVEL = 0x0001, + CELL_LEVEL = 0x0002, + UE_LEVEL = 0x0004, + BEARER_LEVEL = 0x0008, + UNKNOWN_LEVEL = 0xffff +}; + typedef struct { std::string name; - std::string label; + e2sm_kpm_label_enum label; + e2sm_kpm_metric_scope_enum scope; e2_metric_data_type_t data_type; std::vector integer_values; std::vector real_values; @@ -93,7 +117,7 @@ private: bool _fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format4_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); bool _fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format5_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); - void _fill_measurement_records(std::string meas_name, std::string label, meas_record_l& meas_record_list); + void _fill_measurement_records(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list); bool _generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf); bool _generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); @@ -101,8 +125,8 @@ private: bool _get_last_meas_value(E2SM_KPM_meas_values_t& meas_values); bool _get_last_N_meas_values(uint32_t N, E2SM_KPM_meas_values_t& meas_values); - bool _get_last_integer_type_meas_value(std::string meas_name, std::string label, int32_t& value); - bool _get_last_real_type_meas_value(std::string meas_name, std::string label, float& value); + bool _get_last_integer_type_meas_value(std::string meas_name, e2sm_kpm_label_enum label, int32_t& value); + bool _get_last_real_type_meas_value(std::string meas_name, e2sm_kpm_label_enum label, float& value); srslog::basic_logger& logger; std::vector supported_meas_types; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h index 1019505f8..dd9531871 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h @@ -17,19 +17,6 @@ #include "e2sm_kpm.h" #include "srsran/srsran.h" -/* Labels supported for a metric */ -#define NO_LABEL 0x0001 -#define MIN_LABEL 0x0002 -#define MAX_LABEL 0x0004 -#define AVG_LABEL 0x0008 -// TODO: define all labels and scopes - -/* Scopes supported for a metric */ -#define ENB_LEVEL 0x0001 -#define CELL_LEVEL 0x0002 -#define UE_LEVEL 0x0004 -#define BEARER_LEVEL 0x0008 - // clang-format off // Measurements defined in 3GPP TS 28.552 std::vector get_e2sm_kpm_28_552_metrics() diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 2af1130b4..662978fed 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -363,31 +363,32 @@ bool e2sm_kpm::_fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format1_s& meas_info_item.meas_type.set_meas_name().from_string(meas_name.c_str()); meas_info_item.label_info_list.resize(meas_def_item.label_info_list.size()); + // TODO: add all labels defined in e2sm_kpm doc for (uint32_t l = 0; l < meas_def_item.label_info_list.size(); l++) { if (meas_def_item.label_info_list[l].meas_label.no_label_present) { meas_info_item.label_info_list[l].meas_label.no_label_present = true; meas_info_item.label_info_list[l].meas_label.no_label = meas_label_s::no_label_opts::true_value; - this->_fill_measurement_records(meas_name, "no_label", meas_data.meas_record); + this->_fill_measurement_records(meas_name, NO_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.min_present) { meas_info_item.label_info_list[l].meas_label.min_present = true; meas_info_item.label_info_list[l].meas_label.min = meas_label_s::min_opts::true_value; - this->_fill_measurement_records(meas_name, "min", meas_data.meas_record); + this->_fill_measurement_records(meas_name, MIN_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.max_present) { meas_info_item.label_info_list[l].meas_label.max_present = true; meas_info_item.label_info_list[l].meas_label.max = meas_label_s::max_opts::true_value; - this->_fill_measurement_records(meas_name, "max", meas_data.meas_record); + this->_fill_measurement_records(meas_name, MAX_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.avg_present) { meas_info_item.label_info_list[l].meas_label.avg_present = true; meas_info_item.label_info_list[l].meas_label.avg = meas_label_s::avg_opts::true_value; - this->_fill_measurement_records(meas_name, "avg", meas_data.meas_record); + this->_fill_measurement_records(meas_name, AVG_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.sum_present) { meas_info_item.label_info_list[l].meas_label.sum_present = true; meas_info_item.label_info_list[l].meas_label.sum = meas_label_s::sum_opts::true_value; - this->_fill_measurement_records(meas_name, "sum", meas_data.meas_record); + this->_fill_measurement_records(meas_name, SUM_LABEL, meas_data.meas_record); } } } @@ -437,7 +438,7 @@ bool e2sm_kpm::_get_last_N_meas_values(uint32_t N, E2SM_KPM_meas_values_t& meas_ return _get_last_meas_value(meas_values); } -void e2sm_kpm::_fill_measurement_records(std::string meas_name, std::string label, meas_record_l& meas_record_list) +void e2sm_kpm::_fill_measurement_records(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list) { E2SM_KPM_metric_t metric_definition; if (not _get_meas_definition(meas_name, metric_definition)) { @@ -560,59 +561,84 @@ bool e2sm_kpm::_get_last_meas_value(E2SM_KPM_meas_values_t& meas_values) return true; } -bool e2sm_kpm::_get_last_integer_type_meas_value(std::string meas_name, std::string label, int32_t& value) +bool e2sm_kpm::_get_last_integer_type_meas_value(std::string meas_name, e2sm_kpm_label_enum label, int32_t& value) { - // TODO: need to translate labels to enum, maybe also add ID to metric types in e2sm_kpm_metrics definitions + // TODO: maybe add ID to metric types in e2sm_kpm_metrics definitions, so we do not have to compare strings? // TODO: make string comparison case insensitive // all integer type measurements // random_int: no_label if (meas_name.c_str() == std::string("test")) { - if (label.c_str() == std::string("no_label")) { - value = (int32_t)last_enb_metrics.sys.cpu_load[0]; - printf("report last \"test\" value as int, (filled with CPU0_load) value %i \n", value); - return true; + switch (label) { + case NO_LABEL: + value = (int32_t)last_enb_metrics.sys.cpu_load[0]; + printf("report last \"test\" value as int, (filled with CPU0_load) value %i \n", value); + return true; + default: + return false; } } // random_int: no_label if (meas_name.c_str() == std::string("random_int")) { - if (label.c_str() == std::string("no_label")) { - value = srsran_random_uniform_int_dist(random_gen, 0, 100); - printf("report last \"random_int\" value as int, random value %i \n", value); - return true; + switch (label) { + case NO_LABEL: + value = srsran_random_uniform_int_dist(random_gen, 0, 100); + printf("report last \"random_int\" value as int, random value %i \n", value); + return true; + default: + return false; } } return false; } -bool e2sm_kpm::_get_last_real_type_meas_value(std::string meas_name, std::string label, float& value) +bool e2sm_kpm::_get_last_real_type_meas_value(std::string meas_name, e2sm_kpm_label_enum label, float& value) { // all real type measurements // cpu0_load: no_label if (meas_name.c_str() == std::string("cpu0_load")) { - if (label.c_str() == std::string("no_label")) { - value = last_enb_metrics.sys.cpu_load[0]; - return true; + switch (label) { + case NO_LABEL: + value = last_enb_metrics.sys.cpu_load[0]; + return true; + default: + return false; } } // cpu_load: min,max,avg if (meas_name.c_str() == std::string("cpu_load")) { - if (label.c_str() == std::string("min")) { - value = *std::min_element(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end()); - return true; - } - if (label.c_str() == std::string("max")) { - value = *std::max_element(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end()); - return true; - } - if (label.c_str() == std::string("avg")) { - uint32_t size = last_enb_metrics.sys.cpu_load.size(); - value = std::accumulate(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end(), 0.0 / size); - return true; + uint32_t size; + switch (label) { + case MIN_LABEL: + value = *std::min_element(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end()); + return true; + case MAX_LABEL: + value = *std::max_element(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end()); + return true; + case AVG_LABEL: + size = last_enb_metrics.sys.cpu_load.size(); + value = std::accumulate(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end(), 0.0 / size); + return true; + default: + return false; } } return false; } + +e2sm_kpm_label_enum str2kpm_label(const std::string& label_str) +{ + std::string label_str_uc{label_str}; + std::transform(label_str_uc.cbegin(), label_str_uc.cend(), label_str_uc.begin(), [](unsigned char c) { + return std::toupper(c); + }); + + if(label_str_uc == "NO_LABEL") return NO_LABEL; + else if(label_str_uc == "MIN_LABEL") return MIN_LABEL; + else if(label_str_uc == "MAX_LABEL") return MAX_LABEL; + else if(label_str_uc == "AVG_LABEL") return AVG_LABEL; + return UNKNOWN_LABEL; +} \ No newline at end of file From 0d3f8064de802d3fab45497d79d1560c189797af Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 23 Mar 2023 15:02:57 +0100 Subject: [PATCH 087/167] e2sm_kpm: check if action label is supported --- srsgnb/src/stack/ric/e2sm_kpm.cc | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 662978fed..988171a23 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -226,26 +226,34 @@ bool e2sm_kpm::_process_ric_action_definition_format1(e2_sm_kpm_action_definitio meas_info_list = action_definition_format1.meas_info_list; for (uint32_t i = 0; i < meas_info_list.size(); i++) { std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); - E2SM_KPM_metric_t measurement_definition; - if (not _get_meas_definition(meas_name, measurement_definition)) { + E2SM_KPM_metric_t metric_definition; + if (not _get_meas_definition(meas_name, metric_definition)) { printf("Unsupported measurement name: \"%s\" --> do not admit action\n", meas_name.c_str()); return false; } printf("Admitted action: measurement name: \"%s\" with the following labels: \n", meas_name.c_str()); - // TODO: all all labels defined in e2sm_kpm doc + // TODO: add all labels defined in e2sm_kpm doc, if at least one label not supported do not admit action? for (uint32_t l = 0; l < meas_info_list[i].label_info_list.size(); l++) { if (meas_info_list[i].label_info_list[l].meas_label.no_label_present) { - printf("--- Label %i: NO LABEL\n", i); + if (metric_definition.supported_labels & NO_LABEL) { + printf("--- Label %i: NO LABEL\n", i); + } } if (meas_info_list[i].label_info_list[l].meas_label.min_present) { - printf("--- Label %i: MIN\n", i); + if (metric_definition.supported_labels & MIN_LABEL) { + printf("--- Label %i: MIN\n", i); + } } if (meas_info_list[i].label_info_list[l].meas_label.max_present) { - printf("--- Label %i: MAX\n", i); + if (metric_definition.supported_labels & MAX_LABEL) { + printf("--- Label %i: MAX\n", i); + } } if (meas_info_list[i].label_info_list[l].meas_label.avg_present) { - printf("--- Label %i: AVG\n", i); + if (metric_definition.supported_labels & AVG_LABEL) { + printf("--- Label %i: AVG\n", i); + } } } } @@ -566,7 +574,7 @@ bool e2sm_kpm::_get_last_integer_type_meas_value(std::string meas_name, e2sm_kpm // TODO: maybe add ID to metric types in e2sm_kpm_metrics definitions, so we do not have to compare strings? // TODO: make string comparison case insensitive // all integer type measurements - // random_int: no_label + // test: no_label if (meas_name.c_str() == std::string("test")) { switch (label) { case NO_LABEL: From cf80c3bc17caa8fe44924e0bad36f03bd8c8a1a1 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 27 Mar 2023 10:18:17 +0200 Subject: [PATCH 088/167] e2sm_kpm: function now extracts a proper value from enb_metrics --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 8 +++++-- srsgnb/src/stack/ric/e2sm_kpm.cc | 40 ++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index daaa266a1..0b01845ab 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -125,8 +125,12 @@ private: bool _get_last_meas_value(E2SM_KPM_meas_values_t& meas_values); bool _get_last_N_meas_values(uint32_t N, E2SM_KPM_meas_values_t& meas_values); - bool _get_last_integer_type_meas_value(std::string meas_name, e2sm_kpm_label_enum label, int32_t& value); - bool _get_last_real_type_meas_value(std::string meas_name, e2sm_kpm_label_enum label, float& value); + bool _extract_last_integer_type_meas_value(E2SM_KPM_meas_values_t& meas_values, + const enb_metrics_t& enb_metrics, + int32_t& value); + bool _extract_last_real_type_meas_value(E2SM_KPM_meas_values_t& meas_values, + const enb_metrics_t& enb_metrics, + float& value); srslog::basic_logger& logger; std::vector supported_meas_types; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 988171a23..30ec423fd 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -555,13 +555,13 @@ bool e2sm_kpm::_get_last_meas_value(E2SM_KPM_meas_values_t& meas_values) if (meas_values.data_type == e2_metric_data_type_t::INTEGER) { int32_t value; - if (_get_last_integer_type_meas_value(meas_values.name, meas_values.label, value)) { + if (_extract_last_integer_type_meas_value(meas_values, last_enb_metrics, value)) { meas_values.integer_values.push_back(value); } } else { // values.data_type == e2_metric_data_type_t::REAL float value; - if (_get_last_real_type_meas_value(meas_values.name, meas_values.label, value)) { + if (_extract_last_real_type_meas_value(meas_values, last_enb_metrics, value)) { meas_values.real_values.push_back(value); } } @@ -569,16 +569,18 @@ bool e2sm_kpm::_get_last_meas_value(E2SM_KPM_meas_values_t& meas_values) return true; } -bool e2sm_kpm::_get_last_integer_type_meas_value(std::string meas_name, e2sm_kpm_label_enum label, int32_t& value) +bool e2sm_kpm::_extract_last_integer_type_meas_value(E2SM_KPM_meas_values_t& meas_values, + const enb_metrics_t& enb_metrics, + int32_t& value) { // TODO: maybe add ID to metric types in e2sm_kpm_metrics definitions, so we do not have to compare strings? // TODO: make string comparison case insensitive // all integer type measurements // test: no_label - if (meas_name.c_str() == std::string("test")) { - switch (label) { + if (meas_values.name.c_str() == std::string("test")) { + switch (meas_values.label) { case NO_LABEL: - value = (int32_t)last_enb_metrics.sys.cpu_load[0]; + value = (int32_t)enb_metrics.sys.cpu_load[0]; printf("report last \"test\" value as int, (filled with CPU0_load) value %i \n", value); return true; default: @@ -587,8 +589,8 @@ bool e2sm_kpm::_get_last_integer_type_meas_value(std::string meas_name, e2sm_kpm } // random_int: no_label - if (meas_name.c_str() == std::string("random_int")) { - switch (label) { + if (meas_values.name.c_str() == std::string("random_int")) { + switch (meas_values.label) { case NO_LABEL: value = srsran_random_uniform_int_dist(random_gen, 0, 100); printf("report last \"random_int\" value as int, random value %i \n", value); @@ -601,14 +603,16 @@ bool e2sm_kpm::_get_last_integer_type_meas_value(std::string meas_name, e2sm_kpm return false; } -bool e2sm_kpm::_get_last_real_type_meas_value(std::string meas_name, e2sm_kpm_label_enum label, float& value) +bool e2sm_kpm::_extract_last_real_type_meas_value(E2SM_KPM_meas_values_t& meas_values, + const enb_metrics_t& enb_metrics, + float& value) { // all real type measurements // cpu0_load: no_label - if (meas_name.c_str() == std::string("cpu0_load")) { - switch (label) { + if (meas_values.name.c_str() == std::string("cpu0_load")) { + switch (meas_values.label) { case NO_LABEL: - value = last_enb_metrics.sys.cpu_load[0]; + value = enb_metrics.sys.cpu_load[0]; return true; default: return false; @@ -616,18 +620,18 @@ bool e2sm_kpm::_get_last_real_type_meas_value(std::string meas_name, e2sm_kpm_la } // cpu_load: min,max,avg - if (meas_name.c_str() == std::string("cpu_load")) { + if (meas_values.name.c_str() == std::string("cpu_load")) { uint32_t size; - switch (label) { + switch (meas_values.label) { case MIN_LABEL: - value = *std::min_element(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end()); + value = *std::min_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); return true; case MAX_LABEL: - value = *std::max_element(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end()); + value = *std::max_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); return true; case AVG_LABEL: - size = last_enb_metrics.sys.cpu_load.size(); - value = std::accumulate(last_enb_metrics.sys.cpu_load.begin(), last_enb_metrics.sys.cpu_load.end(), 0.0 / size); + size = enb_metrics.sys.cpu_load.size(); + value = std::accumulate(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end(), 0.0 / size); return true; default: return false; From 5b579b502d9d12863f0dae9064b0c9684699cd6f Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 27 Mar 2023 10:27:24 +0200 Subject: [PATCH 089/167] e2sm_kpm: use metric name from metric defition --- srsgnb/src/stack/ric/e2sm_kpm.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 30ec423fd..52a39dfcd 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -455,17 +455,17 @@ void e2sm_kpm::_fill_measurement_records(std::string meas_name, e2sm_kpm_label_e } E2SM_KPM_meas_values_t meas_values; - meas_values.name = meas_name; + meas_values.name = metric_definition.name; // TODO: check if label supported meas_values.label = label; meas_values.data_type = metric_definition.data_type; if (not _get_last_N_meas_values(1, meas_values)) { - logger.debug("No measurement values for type \"%s\" \n", meas_name.c_str()); + logger.debug("No measurement values for type \"%s\" \n", metric_definition.name.c_str()); return; } if ((meas_values.integer_values.size() + meas_values.real_values.size()) == 0) { - logger.debug("No measurement values for type \"%s\" \n", meas_name.c_str()); + logger.debug("No measurement values for type \"%s\" \n", metric_definition.name.c_str()); meas_record_list.resize(1); meas_record_list[0].set_no_value(); return; From c2a756da12fa7d8ddabe16f663a895f2ff0399c3 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 27 Mar 2023 11:49:37 +0200 Subject: [PATCH 090/167] e2sm_kpm: remove cell ID and use ric_ind_msg.meas_info_list.size() --- srsgnb/src/stack/ric/e2sm_kpm.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 52a39dfcd..a078befcb 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -346,20 +346,14 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr bool e2sm_kpm::_fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format1_s& action, E2SM_KPM_RIC_ind_message_t& ric_ind_msg) { - cgi_c cell_global_id; meas_info_list_l action_meas_info_list = action.meas_info_list; - if (action.cell_global_id_present) { - cell_global_id = action.cell_global_id; - } - // ric_ind_message.granul_period = action.granul_period; // not implemented by flexric and crashes it ric_ind_msg.granul_period = 0; - ric_ind_msg.meas_info_list.resize(action_meas_info_list.size()); ric_ind_msg.meas_data.resize(action_meas_info_list.size()); - for (uint32_t i = 0; i < action_meas_info_list.size(); i++) { + for (uint32_t i = 0; i < ric_ind_msg.meas_info_list.size(); i++) { // structs to fill meas_info_item_s& meas_info_item = ric_ind_msg.meas_info_list[i]; meas_data_item_s& meas_data = ric_ind_msg.meas_data[i]; From bace9a2b5b175959e94e9ca4614fa58d304e8a19 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 27 Mar 2023 11:54:41 +0200 Subject: [PATCH 091/167] e2sm_kpm: change func name and use push --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 2 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 0b01845ab..6d3646447 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -117,7 +117,7 @@ private: bool _fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format4_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); bool _fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format5_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); - void _fill_measurement_records(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list); + void _add_measurement_records(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list); bool _generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf); bool _generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index a078befcb..79215ce7f 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -370,27 +370,27 @@ bool e2sm_kpm::_fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format1_s& if (meas_def_item.label_info_list[l].meas_label.no_label_present) { meas_info_item.label_info_list[l].meas_label.no_label_present = true; meas_info_item.label_info_list[l].meas_label.no_label = meas_label_s::no_label_opts::true_value; - this->_fill_measurement_records(meas_name, NO_LABEL, meas_data.meas_record); + this->_add_measurement_records(meas_name, NO_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.min_present) { meas_info_item.label_info_list[l].meas_label.min_present = true; meas_info_item.label_info_list[l].meas_label.min = meas_label_s::min_opts::true_value; - this->_fill_measurement_records(meas_name, MIN_LABEL, meas_data.meas_record); + this->_add_measurement_records(meas_name, MIN_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.max_present) { meas_info_item.label_info_list[l].meas_label.max_present = true; meas_info_item.label_info_list[l].meas_label.max = meas_label_s::max_opts::true_value; - this->_fill_measurement_records(meas_name, MAX_LABEL, meas_data.meas_record); + this->_add_measurement_records(meas_name, MAX_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.avg_present) { meas_info_item.label_info_list[l].meas_label.avg_present = true; meas_info_item.label_info_list[l].meas_label.avg = meas_label_s::avg_opts::true_value; - this->_fill_measurement_records(meas_name, AVG_LABEL, meas_data.meas_record); + this->_add_measurement_records(meas_name, AVG_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.sum_present) { meas_info_item.label_info_list[l].meas_label.sum_present = true; meas_info_item.label_info_list[l].meas_label.sum = meas_label_s::sum_opts::true_value; - this->_fill_measurement_records(meas_name, SUM_LABEL, meas_data.meas_record); + this->_add_measurement_records(meas_name, SUM_LABEL, meas_data.meas_record); } } } @@ -440,7 +440,7 @@ bool e2sm_kpm::_get_last_N_meas_values(uint32_t N, E2SM_KPM_meas_values_t& meas_ return _get_last_meas_value(meas_values); } -void e2sm_kpm::_fill_measurement_records(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list) +void e2sm_kpm::_add_measurement_records(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list) { E2SM_KPM_metric_t metric_definition; if (not _get_meas_definition(meas_name, metric_definition)) { @@ -466,18 +466,20 @@ void e2sm_kpm::_fill_measurement_records(std::string meas_name, e2sm_kpm_label_e } if (meas_values.data_type == e2_metric_data_type_t::INTEGER) { - meas_record_list.resize(meas_values.integer_values.size()); for (uint32_t i = 0; i < meas_values.integer_values.size(); i++) { - meas_record_list[i].set_integer() = meas_values.integer_values[i]; + meas_record_item_c item; + item.set_integer() = meas_values.integer_values[i]; + meas_record_list.push_back(item); } } else { // values.data_type == e2_metric_data_type_t::REAL - meas_record_list.resize(meas_values.real_values.size()); for (uint32_t i = 0; i < meas_values.real_values.size(); i++) { + meas_record_item_c item; real_s real_value; // TODO: real value seems to be not supported in asn1??? // real_value.value = values.real_values[i]; - meas_record_list[i].set_real() = real_value; + item.set_real() = real_value; + meas_record_list.push_back(item); } } } From 81f28a4d4571b81115573626a4dc47d1f84ab996 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 27 Mar 2023 14:14:03 +0200 Subject: [PATCH 092/167] e2sm_kpm: save measurements to support the case when measurement period < reporting period --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 46 ++++-- srsgnb/src/stack/ric/e2sm_kpm.cc | 173 +++++++++++++++++------ srsgnb/src/stack/ric/ric_subscription.cc | 2 +- 3 files changed, 164 insertions(+), 57 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 6d3646447..ad5f2ba72 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -35,6 +35,7 @@ typedef struct { meas_data_l meas_data; meas_info_list_l meas_info_list; uint64_t granul_period; + // TODO: add fields needef in format2 and format3 } E2SM_KPM_RIC_ind_message_t; enum e2_metric_data_type_t { INTEGER, REAL }; @@ -76,12 +77,13 @@ enum e2sm_kpm_metric_scope_enum { }; typedef struct { - std::string name; + uint32_t action_id; + std::string name; e2sm_kpm_label_enum label; e2sm_kpm_metric_scope_enum scope; - e2_metric_data_type_t data_type; - std::vector integer_values; - std::vector real_values; + e2_metric_data_type_t data_type; + std::vector integer_values; + std::vector real_values; } E2SM_KPM_meas_values_t; class e2sm_kpm : public e2sm @@ -111,19 +113,34 @@ private: bool _process_ric_action_definition_format4(e2_sm_kpm_action_definition_format4_s& action_definition_format4); bool _process_ric_action_definition_format5(e2_sm_kpm_action_definition_format5_s& action_definition_format5); - bool _fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format1_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); - bool _fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format2_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); - bool _fill_ric_ind_msg_format2(e2_sm_kpm_action_definition_format3_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); - bool _fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format4_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); - bool _fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format5_s& action, E2SM_KPM_RIC_ind_message_t& r_ind_msg); - - void _add_measurement_records(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list); + bool _fill_ric_ind_msg_format1(uint32_t action_id, + e2_sm_kpm_action_definition_format1_s& action, + E2SM_KPM_RIC_ind_message_t& r_ind_msg); + bool _fill_ric_ind_msg_format1(uint32_t action_id, + e2_sm_kpm_action_definition_format2_s& action, + E2SM_KPM_RIC_ind_message_t& r_ind_msg); + bool _fill_ric_ind_msg_format2(uint32_t action_id, + e2_sm_kpm_action_definition_format3_s& action, + E2SM_KPM_RIC_ind_message_t& r_ind_msg); + bool _fill_ric_ind_msg_format3(uint32_t action_id, + e2_sm_kpm_action_definition_format4_s& action, + E2SM_KPM_RIC_ind_message_t& r_ind_msg); + bool _fill_ric_ind_msg_format3(uint32_t action_id, + e2_sm_kpm_action_definition_format5_s& action, + E2SM_KPM_RIC_ind_message_t& r_ind_msg); + + void _add_measurement_records(uint32_t action_id, + std::string meas_name, + e2sm_kpm_label_enum label, + meas_record_l& meas_record_list); bool _generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf); bool _generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); - bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); - bool _get_last_meas_value(E2SM_KPM_meas_values_t& meas_values); - bool _get_last_N_meas_values(uint32_t N, E2SM_KPM_meas_values_t& meas_values); + bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); + E2SM_KPM_meas_values_t& _get_collected_meas_values(uint32_t act_id, std::string meas_name, e2sm_kpm_label_enum label); + bool _save_last_meas_value(E2SM_KPM_meas_values_t& meas_values); + + std::vector _get_present_labels(const meas_info_item_s& action_meas_info_item); bool _extract_last_integer_type_meas_value(E2SM_KPM_meas_values_t& meas_values, const enb_metrics_t& enb_metrics, @@ -135,6 +152,7 @@ private: srslog::basic_logger& logger; std::vector supported_meas_types; std::map registered_actions; + std::vector collected_meas_data; srsran_random_t random_gen; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 79215ce7f..9010743d6 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -47,6 +47,30 @@ e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_d } } +std::vector e2sm_kpm::_get_present_labels(const meas_info_item_s& action_meas_info_item) +{ + std::vector labels; + // TODO: add all labels defined in e2sm_kpm doc + for (uint32_t l = 0; l < action_meas_info_item.label_info_list.size(); l++) { + if (action_meas_info_item.label_info_list[l].meas_label.no_label_present) { + labels.push_back(NO_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.min_present) { + labels.push_back(MIN_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.max_present) { + labels.push_back(MAX_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.avg_present) { + labels.push_back(AVG_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.sum_present) { + labels.push_back(SUM_LABEL); + } + } + return labels; +} + void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) { last_enb_metrics = m; @@ -54,6 +78,45 @@ void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) // TODO: for INSERT type of reporting check if a specified metrics exceeds predefined thresholds, // if so then send RIC indication throught proper subscription + + for (auto const& it : registered_actions) { + uint32_t action_id = it.first; + e2_sm_kpm_action_definition_s action = it.second; + meas_info_list_l action_meas_info_list; + + switch (action.ric_style_type) { + case 1: + action_meas_info_list = action.action_definition_formats.action_definition_format1().meas_info_list; + for (uint32_t i = 0; i < action_meas_info_list.size(); i++) { + meas_info_item_s meas_def_item = action_meas_info_list[i]; + std::string meas_name = meas_def_item.meas_type.meas_name().to_string(); + std::vector labels = _get_present_labels(meas_def_item); + + for (const auto& label : labels) { + // TODO: probably some labels need a special processing (e.g., use bin width that needs to be stored) + E2SM_KPM_meas_values_t& meas_values = _get_collected_meas_values(action_id, meas_name, label); + // extract a needed value from enb metrics and save to the value vector + _save_last_meas_value(meas_values); + } + } + break; + case 2: + // TODO: add + break; + case 3: + // TODO: add + break; + case 4: + // TODO: add + break; + case 5: + // TODO: add + break; + default: + logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", action.ric_style_type); + return; + } + } } bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func) @@ -292,16 +355,17 @@ bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action_t& action_entry) bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication) { - if (!registered_actions.count(action_entry.sm_local_ric_action_id)) { + uint32_t action_id = action_entry.sm_local_ric_action_id; + if (!registered_actions.count(action_id)) { logger.info("Unknown RIC action ID: %i (type %i) (SM local RIC action ID: %i)", action_entry.ric_action_id, action_entry.ric_action_type, action_entry.sm_local_ric_action_id); return false; } - - E2SM_KPM_RIC_ind_header_t ric_ind_header; - E2SM_KPM_RIC_ind_message_t ric_ind_message; + e2_sm_kpm_action_definition_s action = registered_actions.at(action_id); + E2SM_KPM_RIC_ind_header_t ric_ind_header; + E2SM_KPM_RIC_ind_message_t ric_ind_message; ric_indication.indication_type = ri_cind_type_opts::report; @@ -310,28 +374,31 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); this->_generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); - e2_sm_kpm_action_definition_s action = registered_actions.at(action_entry.sm_local_ric_action_id); - switch (action.ric_style_type) { case 1: ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; - _fill_ric_ind_msg_format1(action.action_definition_formats.action_definition_format1(), ric_ind_message); + _fill_ric_ind_msg_format1( + action_id, action.action_definition_formats.action_definition_format1(), ric_ind_message); break; case 2: ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; - _fill_ric_ind_msg_format1(action.action_definition_formats.action_definition_format2(), ric_ind_message); + _fill_ric_ind_msg_format1( + action_id, action.action_definition_formats.action_definition_format2(), ric_ind_message); break; case 3: ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format2; - _fill_ric_ind_msg_format2(action.action_definition_formats.action_definition_format3(), ric_ind_message); + _fill_ric_ind_msg_format2( + action_id, action.action_definition_formats.action_definition_format3(), ric_ind_message); break; case 4: ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format3; - _fill_ric_ind_msg_format3(action.action_definition_formats.action_definition_format4(), ric_ind_message); + _fill_ric_ind_msg_format3( + action_id, action.action_definition_formats.action_definition_format4(), ric_ind_message); break; case 5: ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format3; - _fill_ric_ind_msg_format3(action.action_definition_formats.action_definition_format5(), ric_ind_message); + _fill_ric_ind_msg_format3( + action_id, action.action_definition_formats.action_definition_format5(), ric_ind_message); break; default: logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", action.ric_style_type); @@ -343,7 +410,8 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr return true; } -bool e2sm_kpm::_fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format1_s& action, +bool e2sm_kpm::_fill_ric_ind_msg_format1(uint32_t action_id, + e2_sm_kpm_action_definition_format1_s& action, E2SM_KPM_RIC_ind_message_t& ric_ind_msg) { meas_info_list_l action_meas_info_list = action.meas_info_list; @@ -370,27 +438,27 @@ bool e2sm_kpm::_fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format1_s& if (meas_def_item.label_info_list[l].meas_label.no_label_present) { meas_info_item.label_info_list[l].meas_label.no_label_present = true; meas_info_item.label_info_list[l].meas_label.no_label = meas_label_s::no_label_opts::true_value; - this->_add_measurement_records(meas_name, NO_LABEL, meas_data.meas_record); + this->_add_measurement_records(action_id, meas_name, NO_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.min_present) { meas_info_item.label_info_list[l].meas_label.min_present = true; meas_info_item.label_info_list[l].meas_label.min = meas_label_s::min_opts::true_value; - this->_add_measurement_records(meas_name, MIN_LABEL, meas_data.meas_record); + this->_add_measurement_records(action_id, meas_name, MIN_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.max_present) { meas_info_item.label_info_list[l].meas_label.max_present = true; meas_info_item.label_info_list[l].meas_label.max = meas_label_s::max_opts::true_value; - this->_add_measurement_records(meas_name, MAX_LABEL, meas_data.meas_record); + this->_add_measurement_records(action_id, meas_name, MAX_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.avg_present) { meas_info_item.label_info_list[l].meas_label.avg_present = true; meas_info_item.label_info_list[l].meas_label.avg = meas_label_s::avg_opts::true_value; - this->_add_measurement_records(meas_name, AVG_LABEL, meas_data.meas_record); + this->_add_measurement_records(action_id, meas_name, AVG_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.sum_present) { meas_info_item.label_info_list[l].meas_label.sum_present = true; meas_info_item.label_info_list[l].meas_label.sum = meas_label_s::sum_opts::true_value; - this->_add_measurement_records(meas_name, SUM_LABEL, meas_data.meas_record); + this->_add_measurement_records(action_id, meas_name, SUM_LABEL, meas_data.meas_record); } } } @@ -398,25 +466,29 @@ bool e2sm_kpm::_fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format1_s& return true; } -bool e2sm_kpm::_fill_ric_ind_msg_format1(e2_sm_kpm_action_definition_format2_s& action, +bool e2sm_kpm::_fill_ric_ind_msg_format1(uint32_t action_id, + e2_sm_kpm_action_definition_format2_s& action, E2SM_KPM_RIC_ind_message_t& ric_ind_msg) { return false; } -bool e2sm_kpm::_fill_ric_ind_msg_format2(e2_sm_kpm_action_definition_format3_s& action, +bool e2sm_kpm::_fill_ric_ind_msg_format2(uint32_t action_id, + e2_sm_kpm_action_definition_format3_s& action, E2SM_KPM_RIC_ind_message_t& ric_ind_msg) { return false; } -bool e2sm_kpm::_fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format4_s& action, +bool e2sm_kpm::_fill_ric_ind_msg_format3(uint32_t action_id, + e2_sm_kpm_action_definition_format4_s& action, E2SM_KPM_RIC_ind_message_t& ric_ind_msg) { return false; } -bool e2sm_kpm::_fill_ric_ind_msg_format3(e2_sm_kpm_action_definition_format5_s& action, +bool e2sm_kpm::_fill_ric_ind_msg_format3(uint32_t action_id, + e2_sm_kpm_action_definition_format5_s& action, E2SM_KPM_RIC_ind_message_t& ric_ind_msg) { return false; @@ -434,13 +506,10 @@ bool e2sm_kpm::_get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& de return true; } -bool e2sm_kpm::_get_last_N_meas_values(uint32_t N, E2SM_KPM_meas_values_t& meas_values) -{ - // TODO: currently only N=1 supported - return _get_last_meas_value(meas_values); -} - -void e2sm_kpm::_add_measurement_records(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list) +void e2sm_kpm::_add_measurement_records(uint32_t action_id, + std::string meas_name, + e2sm_kpm_label_enum label, + meas_record_l& meas_record_list) { E2SM_KPM_metric_t metric_definition; if (not _get_meas_definition(meas_name, metric_definition)) { @@ -448,16 +517,7 @@ void e2sm_kpm::_add_measurement_records(std::string meas_name, e2sm_kpm_label_en return; } - E2SM_KPM_meas_values_t meas_values; - meas_values.name = metric_definition.name; - // TODO: check if label supported - meas_values.label = label; - meas_values.data_type = metric_definition.data_type; - if (not _get_last_N_meas_values(1, meas_values)) { - logger.debug("No measurement values for type \"%s\" \n", metric_definition.name.c_str()); - return; - } - + E2SM_KPM_meas_values_t& meas_values = _get_collected_meas_values(action_id, meas_name, label); if ((meas_values.integer_values.size() + meas_values.real_values.size()) == 0) { logger.debug("No measurement values for type \"%s\" \n", metric_definition.name.c_str()); meas_record_list.resize(1); @@ -475,13 +535,17 @@ void e2sm_kpm::_add_measurement_records(std::string meas_name, e2sm_kpm_label_en // values.data_type == e2_metric_data_type_t::REAL for (uint32_t i = 0; i < meas_values.real_values.size(); i++) { meas_record_item_c item; - real_s real_value; + real_s real_value; // TODO: real value seems to be not supported in asn1??? // real_value.value = values.real_values[i]; item.set_real() = real_value; meas_record_list.push_back(item); } } + + // clear reported values + meas_values.integer_values.clear(); + meas_values.real_values.clear(); } bool e2sm_kpm::_generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf) @@ -544,7 +608,32 @@ bool e2sm_kpm::_generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsr return true; } -bool e2sm_kpm::_get_last_meas_value(E2SM_KPM_meas_values_t& meas_values) +E2SM_KPM_meas_values_t& +e2sm_kpm::_get_collected_meas_values(uint32_t action_id, std::string meas_name, e2sm_kpm_label_enum label) +{ + auto name_label_match = [&action_id, &meas_name, &label](const E2SM_KPM_meas_values_t& x) { + return ((x.action_id == action_id) and (x.name == meas_name or x.name == meas_name.c_str()) and (x.label == label)); + }; + + auto it = std::find_if(collected_meas_data.begin(), collected_meas_data.end(), name_label_match); + if (it == collected_meas_data.end()) { + E2SM_KPM_metric_t metric_definition; + if (not _get_meas_definition(meas_name, metric_definition)) { + logger.debug("No definition for measurement type \"%s\"", metric_definition.name); + } + E2SM_KPM_meas_values_t new_item; + new_item.action_id = action_id; + new_item.name = meas_name; + new_item.label = label; + new_item.data_type = metric_definition.data_type; + new_item.data_type = INTEGER; // TODO: overwrite with INTEGER as REAL is not supported yet + collected_meas_data.push_back(new_item); + return collected_meas_data.back(); + } + return *it; +} + +bool e2sm_kpm::_save_last_meas_value(E2SM_KPM_meas_values_t& meas_values) { meas_values.data_type = e2_metric_data_type_t::INTEGER; // TODO: overwrite as REAL seems to be not supported by asn1 now @@ -577,7 +666,7 @@ bool e2sm_kpm::_extract_last_integer_type_meas_value(E2SM_KPM_meas_values_t& mea switch (meas_values.label) { case NO_LABEL: value = (int32_t)enb_metrics.sys.cpu_load[0]; - printf("report last \"test\" value as int, (filled with CPU0_load) value %i \n", value); + printf("extract last \"test\" value as int, (filled with CPU0_load) value %i \n", value); return true; default: return false; @@ -589,7 +678,7 @@ bool e2sm_kpm::_extract_last_integer_type_meas_value(E2SM_KPM_meas_values_t& mea switch (meas_values.label) { case NO_LABEL: value = srsran_random_uniform_int_dist(random_gen, 0, 100); - printf("report last \"random_int\" value as int, random value %i \n", value); + printf("extract last \"random_int\" value as int, random value %i \n", value); return true; default: return false; diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index fbbae94fa..a754419e6 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -42,7 +42,7 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli if (sm_ptr->process_ric_event_trigger_definition(ric_subscription_request, event_trigger)) { if (event_trigger.type == RIC_event_trigger_definition_t::e2sm_event_trigger_type_t::E2SM_REPORT) { reporting_period = event_trigger.report_period; - reporting_period = 1000; // TODO: to remove, keep it 1s for testing + reporting_period = 3000; // TODO: to remove, keep it 3s for testing } } From 048b54c4f41bf5c72281526839042d80b02c5688 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 27 Mar 2023 15:11:47 +0200 Subject: [PATCH 093/167] e2sm_kpm: set collet_start_time timestamp correctly --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 3 +++ srsgnb/src/stack/ric/e2sm_kpm.cc | 27 ++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index ad5f2ba72..4de534f9b 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -137,6 +137,8 @@ private: bool _generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); + uint64_t _get_meas_collection_start_time(uint32_t action_id); + void _save_meas_collection_start_time(uint32_t action_id, uint64_t timestamp); E2SM_KPM_meas_values_t& _get_collected_meas_values(uint32_t act_id, std::string meas_name, e2sm_kpm_label_enum label); bool _save_last_meas_value(E2SM_KPM_meas_values_t& meas_values); @@ -152,6 +154,7 @@ private: srslog::basic_logger& logger; std::vector supported_meas_types; std::map registered_actions; + std::map action_meas_collection_start_timestamp; std::vector collected_meas_data; srsran_random_t random_gen; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 9010743d6..be8eaa83a 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -96,6 +96,12 @@ void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) // TODO: probably some labels need a special processing (e.g., use bin width that needs to be stored) E2SM_KPM_meas_values_t& meas_values = _get_collected_meas_values(action_id, meas_name, label); // extract a needed value from enb metrics and save to the value vector + if ((meas_values.integer_values.size() + meas_values.real_values.size()) == 0) { + // save timestamp of the first measurement value for this action + if (_get_meas_collection_start_time(action_id) == 0) { + _save_meas_collection_start_time(action_id, std::time(0)); + } + } _save_last_meas_value(meas_values); } } @@ -257,6 +263,8 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a action_entry.sm_local_ric_action_id = _generate_local_action_id(); registered_actions.insert( std::pair(action_entry.sm_local_ric_action_id, e2sm_kpm_action_def)); + // clear timestamp, i.e., save 0 as timestamp, so we can save the timestamp of the first measurement of this action + _save_meas_collection_start_time(action_entry.sm_local_ric_action_id, 0); } return admit_action; @@ -370,7 +378,7 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr ric_indication.indication_type = ri_cind_type_opts::report; // header is the same for all RIC service styles, i.e., type 1 - ric_ind_header.collet_start_time = std::time(0); + ric_ind_header.collet_start_time = _get_meas_collection_start_time(action_id); ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); this->_generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); @@ -407,6 +415,10 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr ric_indication.ri_cind_msg = srsran::make_byte_buffer(); this->_generate_indication_message(ric_ind_message, ric_indication.ri_cind_msg); + + // clear timestamp, i.e., save 0 as timestamp, so we can save the timestamp of the first measurement of this action + _save_meas_collection_start_time(action_id, 0); + return true; } @@ -633,6 +645,19 @@ e2sm_kpm::_get_collected_meas_values(uint32_t action_id, std::string meas_name, return *it; } +uint64_t e2sm_kpm::_get_meas_collection_start_time(uint32_t action_id) +{ + if (action_meas_collection_start_timestamp.find(action_id) != action_meas_collection_start_timestamp.end()) { + return action_meas_collection_start_timestamp.at(action_id); + } + return std::time(0); +} + +void e2sm_kpm::_save_meas_collection_start_time(uint32_t action_id, uint64_t timestamp) +{ + action_meas_collection_start_timestamp[action_id] = timestamp; +} + bool e2sm_kpm::_save_last_meas_value(E2SM_KPM_meas_values_t& meas_values) { meas_values.data_type = From 26b61b57db4085816a6c108fb698615edbc9ffc2 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 30 Mar 2023 15:04:28 +0200 Subject: [PATCH 094/167] e2sm_kpm: store collected meas data directly in the asn1 kpm ind msg --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 92 +++--- srsgnb/src/stack/ric/e2sm_kpm.cc | 487 +++++++++++++++---------------- 2 files changed, 265 insertions(+), 314 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 4de534f9b..19a78e18a 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -23,20 +23,12 @@ using namespace asn1::e2ap; using namespace asn1::e2sm_kpm; typedef struct { - uint32_t collet_start_time; - std::string file_formatversion; - std::string sender_name; - std::string sender_type; - std::string vendor_name; -} E2SM_KPM_RIC_ind_header_t; - -typedef struct { + uint16_t action_id; + e2_sm_kpm_action_definition_s action_definition; e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types ind_msg_format; - meas_data_l meas_data; - meas_info_list_l meas_info_list; - uint64_t granul_period; - // TODO: add fields needef in format2 and format3 -} E2SM_KPM_RIC_ind_message_t; + e2_sm_kpm_ind_hdr_s ric_ind_header; + e2_sm_kpm_ind_msg_s ric_ind_message; +} E2SM_KPM_action_data_t; enum e2_metric_data_type_t { INTEGER, REAL }; @@ -77,14 +69,13 @@ enum e2sm_kpm_metric_scope_enum { }; typedef struct { - uint32_t action_id; std::string name; e2sm_kpm_label_enum label; e2sm_kpm_metric_scope_enum scope; - e2_metric_data_type_t data_type; - std::vector integer_values; - std::vector real_values; -} E2SM_KPM_meas_values_t; + meas_record_item_c::types data_type; + int32_t integer_value; + float real_value; +} E2SM_KPM_meas_value_t; class e2sm_kpm : public e2sm { @@ -113,49 +104,34 @@ private: bool _process_ric_action_definition_format4(e2_sm_kpm_action_definition_format4_s& action_definition_format4); bool _process_ric_action_definition_format5(e2_sm_kpm_action_definition_format5_s& action_definition_format5); - bool _fill_ric_ind_msg_format1(uint32_t action_id, - e2_sm_kpm_action_definition_format1_s& action, - E2SM_KPM_RIC_ind_message_t& r_ind_msg); - bool _fill_ric_ind_msg_format1(uint32_t action_id, - e2_sm_kpm_action_definition_format2_s& action, - E2SM_KPM_RIC_ind_message_t& r_ind_msg); - bool _fill_ric_ind_msg_format2(uint32_t action_id, - e2_sm_kpm_action_definition_format3_s& action, - E2SM_KPM_RIC_ind_message_t& r_ind_msg); - bool _fill_ric_ind_msg_format3(uint32_t action_id, - e2_sm_kpm_action_definition_format4_s& action, - E2SM_KPM_RIC_ind_message_t& r_ind_msg); - bool _fill_ric_ind_msg_format3(uint32_t action_id, - e2_sm_kpm_action_definition_format5_s& action, - E2SM_KPM_RIC_ind_message_t& r_ind_msg); - - void _add_measurement_records(uint32_t action_id, - std::string meas_name, - e2sm_kpm_label_enum label, - meas_record_l& meas_record_list); - bool _generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf); - bool _generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf); - - bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); - uint64_t _get_meas_collection_start_time(uint32_t action_id); - void _save_meas_collection_start_time(uint32_t action_id, uint64_t timestamp); - E2SM_KPM_meas_values_t& _get_collected_meas_values(uint32_t act_id, std::string meas_name, e2sm_kpm_label_enum label); - bool _save_last_meas_value(E2SM_KPM_meas_values_t& meas_values); + bool _initialize_ric_ind_msg_style1(uint32_t action_id, + e2_sm_kpm_action_definition_format1_s& action, + e2_sm_kpm_ind_msg_format1_s& ric_ind_msg); + + bool _clear_action_data(E2SM_KPM_action_data_t& action_data); + + meas_record_item_c::types + _get_meas_data_type(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list); + + void _add_measurement_record(E2SM_KPM_meas_value_t& meas_value, meas_record_l& meas_record_list); + bool _generate_indication_header(e2_sm_kpm_ind_hdr_s& hdr, srsran::unique_byte_buffer_t& buf); + bool _generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::unique_byte_buffer_t& buf); + + bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); + meas_data_item_s& _get_meas_data_item_style1(e2_sm_kpm_ind_msg_s& ric_ind_msg, + std::string meas_name, + e2sm_kpm_label_enum label, + uint32_t ue_id, + bool& ref_found); std::vector _get_present_labels(const meas_info_item_s& action_meas_info_item); - bool _extract_last_integer_type_meas_value(E2SM_KPM_meas_values_t& meas_values, - const enb_metrics_t& enb_metrics, - int32_t& value); - bool _extract_last_real_type_meas_value(E2SM_KPM_meas_values_t& meas_values, - const enb_metrics_t& enb_metrics, - float& value); - - srslog::basic_logger& logger; - std::vector supported_meas_types; - std::map registered_actions; - std::map action_meas_collection_start_timestamp; - std::vector collected_meas_data; + bool _extract_last_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); + bool _extract_last_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); + + srslog::basic_logger& logger; + std::vector supported_meas_types; + std::map registered_actions_data; srsran_random_t random_gen; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index be8eaa83a..7a2f8c35b 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -76,33 +76,57 @@ void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) last_enb_metrics = m; logger.debug("e2sm_kpm received new enb metrics, CPU0 Load: %.1f", last_enb_metrics.sys.cpu_load[0]); - // TODO: for INSERT type of reporting check if a specified metrics exceeds predefined thresholds, - // if so then send RIC indication throught proper subscription - - for (auto const& it : registered_actions) { - uint32_t action_id = it.first; - e2_sm_kpm_action_definition_s action = it.second; - meas_info_list_l action_meas_info_list; + for (auto& it : registered_actions_data) { + uint32_t action_id = it.first; + e2_sm_kpm_action_definition_s& action = it.second.action_definition; + e2_sm_kpm_ind_msg_s& ric_ind_msg = it.second.ric_ind_message; + meas_info_list_l meas_info_list; switch (action.ric_style_type) { case 1: - action_meas_info_list = action.action_definition_formats.action_definition_format1().meas_info_list; - for (uint32_t i = 0; i < action_meas_info_list.size(); i++) { - meas_info_item_s meas_def_item = action_meas_info_list[i]; + meas_info_list = ric_ind_msg.ind_msg_formats.ind_msg_format1().meas_info_list; + for (uint32_t i = 0; i < meas_info_list.size(); i++) { + meas_info_item_s meas_def_item = meas_info_list[i]; std::string meas_name = meas_def_item.meas_type.meas_name().to_string(); std::vector labels = _get_present_labels(meas_def_item); for (const auto& label : labels) { // TODO: probably some labels need a special processing (e.g., use bin width that needs to be stored) - E2SM_KPM_meas_values_t& meas_values = _get_collected_meas_values(action_id, meas_name, label); - // extract a needed value from enb metrics and save to the value vector - if ((meas_values.integer_values.size() + meas_values.real_values.size()) == 0) { - // save timestamp of the first measurement value for this action - if (_get_meas_collection_start_time(action_id) == 0) { - _save_meas_collection_start_time(action_id, std::time(0)); + // get a proper record list + bool ref_found = false; + meas_data_item_s& meas_data_item = _get_meas_data_item_style1(ric_ind_msg, meas_name, label, 0, ref_found); + if (not ref_found) { + logger.info("Cannot find a meas record list, action_id %i, metric \"%s\" label: %i", + action_id, + meas_name.c_str(), + label); + return; + } + + // get data type + meas_record_item_c::types data_type = _get_meas_data_type(meas_name, label, meas_data_item.meas_record); + + // extract a needed value from enb metrics and add to the proper meas record list + E2SM_KPM_meas_value_t meas_value; + meas_value.name = meas_name; + meas_value.label = label; + // meas_values.scope = ...; + meas_value.data_type = data_type; + + if (meas_value.data_type == meas_record_item_c::types::options::integer) { + if (not _extract_last_integer_type_meas_value(meas_value, last_enb_metrics)) { + logger.info("Cannot extract value \"%s\" label: %i", meas_name.c_str(), label); + return; + } + } else { + // data_type == meas_record_item_c::types::options::real; + if (not _extract_last_real_type_meas_value(meas_value, last_enb_metrics)) { + logger.info("Cannot extract value \"%s\" label %i", meas_name.c_str(), label); + return; } } - _save_last_meas_value(meas_values); + // save meas value in the proper record list + _add_measurement_record(meas_value, meas_data_item.meas_record); } } break; @@ -222,7 +246,9 @@ bool e2sm_kpm::process_ric_event_trigger_definition(ricsubscription_request_s bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action_t& action_entry) { - bool admit_action = false; + bool admit_action = false; + E2SM_KPM_action_data_t action_data; + e2_sm_kpm_action_definition_s e2sm_kpm_action_def; asn1::cbit_ref bref(ric_action.ric_action_definition.data(), ric_action.ric_action_definition.size()); @@ -259,14 +285,62 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a return false; } - if (admit_action) { - action_entry.sm_local_ric_action_id = _generate_local_action_id(); - registered_actions.insert( - std::pair(action_entry.sm_local_ric_action_id, e2sm_kpm_action_def)); - // clear timestamp, i.e., save 0 as timestamp, so we can save the timestamp of the first measurement of this action - _save_meas_collection_start_time(action_entry.sm_local_ric_action_id, 0); + if (not admit_action) { + return false; + } + + action_entry.sm_local_ric_action_id = _generate_local_action_id(); + action_data.action_id = action_entry.sm_local_ric_action_id; + action_data.action_definition = e2sm_kpm_action_def; + + // initialize RIC indication header (always the same type 1) + action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().collet_start_time.from_number(std::time(0)); + // action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().file_formatversion.from_string(hdr.file_formatversion); + // action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().sender_name.from_string(hdr.sender_name); + // action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().sender_type.from_string(hdr.sender_type); + // action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().vendor_name.from_string(hdr.vendor_name); + + // initialize RIC indication message + switch (e2sm_kpm_action_def.ric_style_type) { + case 1: + action_data.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + action_data.ric_ind_message.ind_msg_formats.set_ind_msg_format1(); + _initialize_ric_ind_msg_style1( + action_entry.sm_local_ric_action_id, + action_data.action_definition.action_definition_formats.action_definition_format1(), + action_data.ric_ind_message.ind_msg_formats.ind_msg_format1()); + break; + case 2: + action_data.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + action_data.ric_ind_message.ind_msg_formats.set_ind_msg_format1(); + // TODO: add initialization + break; + case 3: + action_data.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format2; + action_data.ric_ind_message.ind_msg_formats.set_ind_msg_format2(); + // TODO: add initialization + break; + case 4: + action_data.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format3; + action_data.ric_ind_message.ind_msg_formats.set_ind_msg_format3(); + // TODO: add initialization + break; + case 5: + action_data.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format3; + action_data.ric_ind_message.ind_msg_formats.set_ind_msg_format3(); + // TODO: add initialization + break; + default: + logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", + e2sm_kpm_action_def.ric_style_type, + ric_action.ric_action_id, + ric_action.ric_action_type); + return false; } + registered_actions_data.insert( + std::pair(action_entry.sm_local_ric_action_id, action_data)); + return admit_action; } @@ -354,8 +428,8 @@ bool e2sm_kpm::_process_ric_action_definition_format5(e2_sm_kpm_action_definitio bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action_t& action_entry) { - if (registered_actions.count(action_entry.sm_local_ric_action_id)) { - registered_actions.erase(action_entry.sm_local_ric_action_id); + if (registered_actions_data.count(action_entry.sm_local_ric_action_id)) { + registered_actions_data.erase(action_entry.sm_local_ric_action_id); return true; } return false; @@ -364,67 +438,32 @@ bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action_t& action_entry) bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication) { uint32_t action_id = action_entry.sm_local_ric_action_id; - if (!registered_actions.count(action_id)) { + if (!registered_actions_data.count(action_id)) { logger.info("Unknown RIC action ID: %i (type %i) (SM local RIC action ID: %i)", action_entry.ric_action_id, action_entry.ric_action_type, action_entry.sm_local_ric_action_id); return false; } - e2_sm_kpm_action_definition_s action = registered_actions.at(action_id); - E2SM_KPM_RIC_ind_header_t ric_ind_header; - E2SM_KPM_RIC_ind_message_t ric_ind_message; - - ric_indication.indication_type = ri_cind_type_opts::report; + E2SM_KPM_action_data_t& action_data = registered_actions_data.at(action_id); + ric_indication.indication_type = ri_cind_type_opts::report; // header is the same for all RIC service styles, i.e., type 1 - ric_ind_header.collet_start_time = _get_meas_collection_start_time(action_id); - ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); - this->_generate_indication_header(ric_ind_header, ric_indication.ri_cind_hdr); - - switch (action.ric_style_type) { - case 1: - ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; - _fill_ric_ind_msg_format1( - action_id, action.action_definition_formats.action_definition_format1(), ric_ind_message); - break; - case 2: - ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; - _fill_ric_ind_msg_format1( - action_id, action.action_definition_formats.action_definition_format2(), ric_ind_message); - break; - case 3: - ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format2; - _fill_ric_ind_msg_format2( - action_id, action.action_definition_formats.action_definition_format3(), ric_ind_message); - break; - case 4: - ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format3; - _fill_ric_ind_msg_format3( - action_id, action.action_definition_formats.action_definition_format4(), ric_ind_message); - break; - case 5: - ric_ind_message.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format3; - _fill_ric_ind_msg_format3( - action_id, action.action_definition_formats.action_definition_format5(), ric_ind_message); - break; - default: - logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", action.ric_style_type); - return false; - } + ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); + this->_generate_indication_header(action_data.ric_ind_header, ric_indication.ri_cind_hdr); + logger.info("Generating E2-SM-KPM Indication Message"); ric_indication.ri_cind_msg = srsran::make_byte_buffer(); - this->_generate_indication_message(ric_ind_message, ric_indication.ri_cind_msg); - - // clear timestamp, i.e., save 0 as timestamp, so we can save the timestamp of the first measurement of this action - _save_meas_collection_start_time(action_id, 0); + this->_generate_indication_message(action_data.ric_ind_message, ric_indication.ri_cind_msg); + // clear data collected for this action + _clear_action_data(action_data); return true; } -bool e2sm_kpm::_fill_ric_ind_msg_format1(uint32_t action_id, - e2_sm_kpm_action_definition_format1_s& action, - E2SM_KPM_RIC_ind_message_t& ric_ind_msg) +bool e2sm_kpm::_initialize_ric_ind_msg_style1(uint32_t action_id, + e2_sm_kpm_action_definition_format1_s& action, + e2_sm_kpm_ind_msg_format1_s& ric_ind_msg) { meas_info_list_l action_meas_info_list = action.meas_info_list; @@ -433,10 +472,10 @@ bool e2sm_kpm::_fill_ric_ind_msg_format1(uint32_t ric_ind_msg.meas_info_list.resize(action_meas_info_list.size()); ric_ind_msg.meas_data.resize(action_meas_info_list.size()); + // add measurement info for (uint32_t i = 0; i < ric_ind_msg.meas_info_list.size(); i++) { // structs to fill meas_info_item_s& meas_info_item = ric_ind_msg.meas_info_list[i]; - meas_data_item_s& meas_data = ric_ind_msg.meas_data[i]; // measurements definition meas_info_item_s meas_def_item = action_meas_info_list[i]; @@ -450,27 +489,22 @@ bool e2sm_kpm::_fill_ric_ind_msg_format1(uint32_t if (meas_def_item.label_info_list[l].meas_label.no_label_present) { meas_info_item.label_info_list[l].meas_label.no_label_present = true; meas_info_item.label_info_list[l].meas_label.no_label = meas_label_s::no_label_opts::true_value; - this->_add_measurement_records(action_id, meas_name, NO_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.min_present) { meas_info_item.label_info_list[l].meas_label.min_present = true; meas_info_item.label_info_list[l].meas_label.min = meas_label_s::min_opts::true_value; - this->_add_measurement_records(action_id, meas_name, MIN_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.max_present) { meas_info_item.label_info_list[l].meas_label.max_present = true; meas_info_item.label_info_list[l].meas_label.max = meas_label_s::max_opts::true_value; - this->_add_measurement_records(action_id, meas_name, MAX_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.avg_present) { meas_info_item.label_info_list[l].meas_label.avg_present = true; meas_info_item.label_info_list[l].meas_label.avg = meas_label_s::avg_opts::true_value; - this->_add_measurement_records(action_id, meas_name, AVG_LABEL, meas_data.meas_record); } if (meas_def_item.label_info_list[l].meas_label.sum_present) { meas_info_item.label_info_list[l].meas_label.sum_present = true; meas_info_item.label_info_list[l].meas_label.sum = meas_label_s::sum_opts::true_value; - this->_add_measurement_records(action_id, meas_name, SUM_LABEL, meas_data.meas_record); } } } @@ -478,32 +512,20 @@ bool e2sm_kpm::_fill_ric_ind_msg_format1(uint32_t return true; } -bool e2sm_kpm::_fill_ric_ind_msg_format1(uint32_t action_id, - e2_sm_kpm_action_definition_format2_s& action, - E2SM_KPM_RIC_ind_message_t& ric_ind_msg) -{ - return false; -} - -bool e2sm_kpm::_fill_ric_ind_msg_format2(uint32_t action_id, - e2_sm_kpm_action_definition_format3_s& action, - E2SM_KPM_RIC_ind_message_t& ric_ind_msg) -{ - return false; -} - -bool e2sm_kpm::_fill_ric_ind_msg_format3(uint32_t action_id, - e2_sm_kpm_action_definition_format4_s& action, - E2SM_KPM_RIC_ind_message_t& ric_ind_msg) +bool e2sm_kpm::_clear_action_data(E2SM_KPM_action_data_t& action_data) { - return false; -} + switch (action_data.action_definition.ric_style_type) { + case 1: + action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().collet_start_time.from_number(std::time(0)); + for (uint32_t i = 0; i < action_data.ric_ind_message.ind_msg_formats.ind_msg_format1().meas_data.size(); ++i) { + action_data.ric_ind_message.ind_msg_formats.ind_msg_format1().meas_data[i].meas_record.clear(); + } + break; + default: + break; + } -bool e2sm_kpm::_fill_ric_ind_msg_format3(uint32_t action_id, - e2_sm_kpm_action_definition_format5_s& action, - E2SM_KPM_RIC_ind_message_t& ric_ind_msg) -{ - return false; + return true; } bool e2sm_kpm::_get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def) @@ -518,59 +540,101 @@ bool e2sm_kpm::_get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& de return true; } -void e2sm_kpm::_add_measurement_records(uint32_t action_id, - std::string meas_name, - e2sm_kpm_label_enum label, - meas_record_l& meas_record_list) +meas_data_item_s& e2sm_kpm::_get_meas_data_item_style1(e2_sm_kpm_ind_msg_s& ric_ind_msg_generic, + std::string meas_name, + e2sm_kpm_label_enum label, + uint32_t ue_id, + bool& ref_found) { - E2SM_KPM_metric_t metric_definition; - if (not _get_meas_definition(meas_name, metric_definition)) { - logger.debug("No definition for measurement type \"%s\"", metric_definition.name); - return; - } + e2_sm_kpm_ind_msg_format1_s& ric_ind_msg = ric_ind_msg_generic.ind_msg_formats.ind_msg_format1(); + meas_info_list_l& meas_info_list = ric_ind_msg.meas_info_list; + ref_found = false; + // find proper index of the metric + for (uint32_t i = 0; i < meas_info_list.size(); i++) { + // measurements definition + meas_info_item_s meas_def_item = meas_info_list[i]; + std::string meas_def_name = meas_def_item.meas_type.meas_name().to_string(); + + // TODO: check if UE_ID matches (for format2 and 3) + // check if the metric name matches + if (meas_def_name != meas_name.c_str()) { + continue; + } - E2SM_KPM_meas_values_t& meas_values = _get_collected_meas_values(action_id, meas_name, label); - if ((meas_values.integer_values.size() + meas_values.real_values.size()) == 0) { - logger.debug("No measurement values for type \"%s\" \n", metric_definition.name.c_str()); - meas_record_list.resize(1); - meas_record_list[0].set_no_value(); - return; + // check if the metric label matches + // TODO: add all labels defined in e2sm_kpm doc + for (uint32_t l = 0; l < meas_def_item.label_info_list.size(); l++) { + if (meas_def_item.label_info_list[l].meas_label.no_label_present and label == NO_LABEL) { + ref_found = true; + return ric_ind_msg.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.min_present and label == MIN_LABEL) { + ref_found = true; + return ric_ind_msg.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.max_present and label == MAX_LABEL) { + ref_found = true; + return ric_ind_msg.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.avg_present and label == AVG_LABEL) { + ref_found = true; + return ric_ind_msg.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.sum_present and label == SUM_LABEL) { + ref_found = true; + return ric_ind_msg.meas_data[i]; + } + } } + // TODO assert if match == false, has to be present as was created during initialization + ref_found = false; + return ric_ind_msg.meas_data[0]; +} - if (meas_values.data_type == e2_metric_data_type_t::INTEGER) { - for (uint32_t i = 0; i < meas_values.integer_values.size(); i++) { - meas_record_item_c item; - item.set_integer() = meas_values.integer_values[i]; - meas_record_list.push_back(item); +meas_record_item_c::types +e2sm_kpm::_get_meas_data_type(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list) +{ + meas_record_item_c::types data_type = meas_record_item_c::types::options::nulltype; + // if no data collected check the type using metric definition + if (meas_record_list.size() == 0) { + E2SM_KPM_metric_t metric_definition; + if (not _get_meas_definition(meas_name, metric_definition)) { + logger.debug("No definition for measurement type \"%s\"", metric_definition.name); + return data_type; } - } else { - // values.data_type == e2_metric_data_type_t::REAL - for (uint32_t i = 0; i < meas_values.real_values.size(); i++) { - meas_record_item_c item; - real_s real_value; - // TODO: real value seems to be not supported in asn1??? - // real_value.value = values.real_values[i]; - item.set_real() = real_value; - meas_record_list.push_back(item); + if (metric_definition.data_type == INTEGER) { + data_type = meas_record_item_c::types::options::integer; + } else { + data_type = meas_record_item_c::types::options::real; } + } else { + // check the data type of the first element in the list + data_type = meas_record_list[0].type(); } - - // clear reported values - meas_values.integer_values.clear(); - meas_values.real_values.clear(); + return data_type; } -bool e2sm_kpm::_generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran::unique_byte_buffer_t& buf) +void e2sm_kpm::_add_measurement_record(E2SM_KPM_meas_value_t& meas_value, meas_record_l& meas_record_list) { - e2_sm_kpm_ind_hdr_s e2_sm_kpm_ind_hdr; - e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().collet_start_time.from_number(hdr.collet_start_time); - e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().file_formatversion.from_string(hdr.file_formatversion); - e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().sender_name.from_string(hdr.sender_name); - e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().sender_type.from_string(hdr.sender_type); - e2_sm_kpm_ind_hdr.ind_hdr_formats.ind_hdr_format1().vendor_name.from_string(hdr.vendor_name); + if (meas_value.data_type == meas_record_item_c::types::options::integer) { + meas_record_item_c item; + item.set_integer() = meas_value.integer_value; + meas_record_list.push_back(item); + } else { + // data_type == meas_record_item_c::types::options::real; + meas_record_item_c item; + real_s real_value; + // TODO: real value seems to be not supported in asn1??? + // real_value.value = meas_value.real_value; + item.set_real() = real_value; + meas_record_list.push_back(item); + } +} +bool e2sm_kpm::_generate_indication_header(e2_sm_kpm_ind_hdr_s& hdr, srsran::unique_byte_buffer_t& buf) +{ asn1::bit_ref bref(buf->msg, buf->get_tailroom()); - if (e2_sm_kpm_ind_hdr.pack(bref) != asn1::SRSASN_SUCCESS) { + if (hdr.pack(bref) != asn1::SRSASN_SUCCESS) { printf("IND HEADER: Failed to pack TX E2 PDU\n"); return false; } @@ -579,39 +643,11 @@ bool e2sm_kpm::_generate_indication_header(E2SM_KPM_RIC_ind_header_t hdr, srsran return true; } -bool e2sm_kpm::_generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsran::unique_byte_buffer_t& buf) +bool e2sm_kpm::_generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::unique_byte_buffer_t& buf) { - e2_sm_kpm_ind_msg_s e2_sm_kpm_ind_msg; - - switch (msg.ind_msg_format) { - case e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format1: - e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format1(); - e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_data = msg.meas_data; - e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().meas_info_list = msg.meas_info_list; - - if (msg.granul_period) { - e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().granul_period_present = true; - e2_sm_kpm_ind_msg.ind_msg_formats.ind_msg_format1().granul_period = msg.granul_period; - } - - break; - case e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format2: - e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format2(); - // TODO: support format2 - break; - case e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::ind_msg_format3: - e2_sm_kpm_ind_msg.ind_msg_formats.set_ind_msg_format3(); - // TODO: support format3 - break; - case e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types::nulltype: - break; - default: - log_invalid_choice_id(msg.ind_msg_format, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); - } - logger.info("Generating E2-SM-KPM Indication Message"); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); - if (e2_sm_kpm_ind_msg.pack(bref) != asn1::SRSASN_SUCCESS) { + if (msg.pack(bref) != asn1::SRSASN_SUCCESS) { printf("IND MSG: Failed to pack TX E2 PDU\n"); return false; } @@ -620,78 +656,18 @@ bool e2sm_kpm::_generate_indication_message(E2SM_KPM_RIC_ind_message_t msg, srsr return true; } -E2SM_KPM_meas_values_t& -e2sm_kpm::_get_collected_meas_values(uint32_t action_id, std::string meas_name, e2sm_kpm_label_enum label) -{ - auto name_label_match = [&action_id, &meas_name, &label](const E2SM_KPM_meas_values_t& x) { - return ((x.action_id == action_id) and (x.name == meas_name or x.name == meas_name.c_str()) and (x.label == label)); - }; - - auto it = std::find_if(collected_meas_data.begin(), collected_meas_data.end(), name_label_match); - if (it == collected_meas_data.end()) { - E2SM_KPM_metric_t metric_definition; - if (not _get_meas_definition(meas_name, metric_definition)) { - logger.debug("No definition for measurement type \"%s\"", metric_definition.name); - } - E2SM_KPM_meas_values_t new_item; - new_item.action_id = action_id; - new_item.name = meas_name; - new_item.label = label; - new_item.data_type = metric_definition.data_type; - new_item.data_type = INTEGER; // TODO: overwrite with INTEGER as REAL is not supported yet - collected_meas_data.push_back(new_item); - return collected_meas_data.back(); - } - return *it; -} - -uint64_t e2sm_kpm::_get_meas_collection_start_time(uint32_t action_id) -{ - if (action_meas_collection_start_timestamp.find(action_id) != action_meas_collection_start_timestamp.end()) { - return action_meas_collection_start_timestamp.at(action_id); - } - return std::time(0); -} - -void e2sm_kpm::_save_meas_collection_start_time(uint32_t action_id, uint64_t timestamp) -{ - action_meas_collection_start_timestamp[action_id] = timestamp; -} - -bool e2sm_kpm::_save_last_meas_value(E2SM_KPM_meas_values_t& meas_values) -{ - meas_values.data_type = - e2_metric_data_type_t::INTEGER; // TODO: overwrite as REAL seems to be not supported by asn1 now - - if (meas_values.data_type == e2_metric_data_type_t::INTEGER) { - int32_t value; - if (_extract_last_integer_type_meas_value(meas_values, last_enb_metrics, value)) { - meas_values.integer_values.push_back(value); - } - } else { - // values.data_type == e2_metric_data_type_t::REAL - float value; - if (_extract_last_real_type_meas_value(meas_values, last_enb_metrics, value)) { - meas_values.real_values.push_back(value); - } - } - - return true; -} - -bool e2sm_kpm::_extract_last_integer_type_meas_value(E2SM_KPM_meas_values_t& meas_values, - const enb_metrics_t& enb_metrics, - int32_t& value) +bool e2sm_kpm::_extract_last_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, + const enb_metrics_t& enb_metrics) { // TODO: maybe add ID to metric types in e2sm_kpm_metrics definitions, so we do not have to compare strings? // TODO: make string comparison case insensitive // all integer type measurements // test: no_label - if (meas_values.name.c_str() == std::string("test")) { - switch (meas_values.label) { + if (meas_value.name.c_str() == std::string("test")) { + switch (meas_value.label) { case NO_LABEL: - value = (int32_t)enb_metrics.sys.cpu_load[0]; - printf("extract last \"test\" value as int, (filled with CPU0_load) value %i \n", value); + meas_value.integer_value = (int32_t)enb_metrics.sys.cpu_load[0]; + printf("extract last \"test\" value as int, (filled with CPU0_load) value %i \n", meas_value.integer_value); return true; default: return false; @@ -699,11 +675,11 @@ bool e2sm_kpm::_extract_last_integer_type_meas_value(E2SM_KPM_meas_values_t& mea } // random_int: no_label - if (meas_values.name.c_str() == std::string("random_int")) { - switch (meas_values.label) { + if (meas_value.name.c_str() == std::string("random_int")) { + switch (meas_value.label) { case NO_LABEL: - value = srsran_random_uniform_int_dist(random_gen, 0, 100); - printf("extract last \"random_int\" value as int, random value %i \n", value); + meas_value.integer_value = srsran_random_uniform_int_dist(random_gen, 0, 100); + printf("extract last \"random_int\" value as int, random value %i \n", meas_value.integer_value); return true; default: return false; @@ -713,16 +689,14 @@ bool e2sm_kpm::_extract_last_integer_type_meas_value(E2SM_KPM_meas_values_t& mea return false; } -bool e2sm_kpm::_extract_last_real_type_meas_value(E2SM_KPM_meas_values_t& meas_values, - const enb_metrics_t& enb_metrics, - float& value) +bool e2sm_kpm::_extract_last_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics) { // all real type measurements // cpu0_load: no_label - if (meas_values.name.c_str() == std::string("cpu0_load")) { - switch (meas_values.label) { + if (meas_value.name.c_str() == std::string("cpu0_load")) { + switch (meas_value.label) { case NO_LABEL: - value = enb_metrics.sys.cpu_load[0]; + meas_value.real_value = enb_metrics.sys.cpu_load[0]; return true; default: return false; @@ -730,18 +704,19 @@ bool e2sm_kpm::_extract_last_real_type_meas_value(E2SM_KPM_meas_values_t& meas_v } // cpu_load: min,max,avg - if (meas_values.name.c_str() == std::string("cpu_load")) { + if (meas_value.name.c_str() == std::string("cpu_load")) { uint32_t size; - switch (meas_values.label) { + switch (meas_value.label) { case MIN_LABEL: - value = *std::min_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); + meas_value.real_value = *std::min_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); return true; case MAX_LABEL: - value = *std::max_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); + meas_value.real_value = *std::max_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); return true; case AVG_LABEL: - size = enb_metrics.sys.cpu_load.size(); - value = std::accumulate(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end(), 0.0 / size); + size = enb_metrics.sys.cpu_load.size(); + meas_value.real_value = + std::accumulate(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end(), 0.0 / size); return true; default: return false; From 8ed3497bc80dfe026d0c1dfe7839286db43db872 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 30 Mar 2023 16:22:35 +0200 Subject: [PATCH 095/167] e2sm_kpm: move struct types to e2sm_kpm_common.h --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 56 +---------------- srsgnb/hdr/stack/ric/e2sm_kpm_common.h | 80 +++++++++++++++++++++++++ srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h | 2 +- 3 files changed, 82 insertions(+), 56 deletions(-) create mode 100644 srsgnb/hdr/stack/ric/e2sm_kpm_common.h diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 19a78e18a..86084fa1d 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -11,6 +11,7 @@ * */ #include "e2sm.h" +#include "e2sm_kpm_common.h" #include "srsran/asn1/e2ap.h" #include "srsran/asn1/e2sm.h" #include "srsran/asn1/e2sm_kpm_v2.h" @@ -22,61 +23,6 @@ using namespace asn1::e2ap; using namespace asn1::e2sm_kpm; -typedef struct { - uint16_t action_id; - e2_sm_kpm_action_definition_s action_definition; - e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types ind_msg_format; - e2_sm_kpm_ind_hdr_s ric_ind_header; - e2_sm_kpm_ind_msg_s ric_ind_message; -} E2SM_KPM_action_data_t; - -enum e2_metric_data_type_t { INTEGER, REAL }; - -typedef struct { - std::string name; - bool supported; - e2_metric_data_type_t data_type; - std::string units; - bool min_val_present; - double min_val; - bool max_val_present; - double max_val; - uint32_t supported_labels; - uint32_t supported_scopes; -} E2SM_KPM_metric_t; - -// TODO: define all labels and scopes - -/* Labels supported for a metric */ -enum e2sm_kpm_label_enum { - NO_LABEL = 0x0001, - MIN_LABEL = 0x0002, - MAX_LABEL = 0x0004, - AVG_LABEL = 0x0008, - SUM_LABEL = 0x0010, - UNKNOWN_LABEL = 0x8000 -}; - -e2sm_kpm_label_enum str2kpm_label(const std::string& label_str); - -/* Scopes supported for a metric */ -enum e2sm_kpm_metric_scope_enum { - ENB_LEVEL = 0x0001, - CELL_LEVEL = 0x0002, - UE_LEVEL = 0x0004, - BEARER_LEVEL = 0x0008, - UNKNOWN_LEVEL = 0xffff -}; - -typedef struct { - std::string name; - e2sm_kpm_label_enum label; - e2sm_kpm_metric_scope_enum scope; - meas_record_item_c::types data_type; - int32_t integer_value; - float real_value; -} E2SM_KPM_meas_value_t; - class e2sm_kpm : public e2sm { public: diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h new file mode 100644 index 000000000..b048f0510 --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h @@ -0,0 +1,80 @@ +/** + * + * \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/asn1/e2ap.h" +#include "srsran/asn1/e2sm.h" +#include "srsran/asn1/e2sm_kpm_v2.h" +#include "srsran/srsran.h" + +#ifndef SRSRAN_E2SM_KPM_COMMON_H +#define SRSRAN_E2SM_KPM_COMMON_H + +using namespace asn1::e2ap; +using namespace asn1::e2sm_kpm; + +typedef struct { + uint16_t action_id; + e2_sm_kpm_action_definition_s action_definition; + e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types ind_msg_format; + e2_sm_kpm_ind_hdr_s ric_ind_header; + e2_sm_kpm_ind_msg_s ric_ind_message; +} E2SM_KPM_action_data_t; + +enum e2_metric_data_type_t { INTEGER, REAL }; + +typedef struct { + std::string name; + bool supported; + e2_metric_data_type_t data_type; + std::string units; + bool min_val_present; + double min_val; + bool max_val_present; + double max_val; + uint32_t supported_labels; + uint32_t supported_scopes; +} E2SM_KPM_metric_t; + +// TODO: define all labels and scopes + +/* Labels supported for a metric */ +enum e2sm_kpm_label_enum { + NO_LABEL = 0x0001, + MIN_LABEL = 0x0002, + MAX_LABEL = 0x0004, + AVG_LABEL = 0x0008, + SUM_LABEL = 0x0010, + UNKNOWN_LABEL = 0x8000 +}; + +e2sm_kpm_label_enum str2kpm_label(const std::string& label_str); + +/* Scopes supported for a metric */ +enum e2sm_kpm_metric_scope_enum { + ENB_LEVEL = 0x0001, + CELL_LEVEL = 0x0002, + UE_LEVEL = 0x0004, + BEARER_LEVEL = 0x0008, + UNKNOWN_LEVEL = 0xffff +}; + +typedef struct { + std::string name; + e2sm_kpm_label_enum label; + e2sm_kpm_metric_scope_enum scope; + meas_record_item_c::types data_type; + int32_t integer_value; + float real_value; +} E2SM_KPM_meas_value_t; + +#endif // SRSRAN_E2SM_KPM_COMMON_H diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h index dd9531871..160dfc84e 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h @@ -14,7 +14,7 @@ #ifndef SRSRAN_E2SM_KPM_METRICS_H #define SRSRAN_E2SM_KPM_METRICS_H -#include "e2sm_kpm.h" +#include "e2sm_kpm_common.h" #include "srsran/srsran.h" // clang-format off From 6c8458bfb2e710c9754ad2a994453fd3d2ad0a6e Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 30 Mar 2023 17:39:25 +0200 Subject: [PATCH 096/167] e2sm_kpm: remove uneeded func --- srsgnb/hdr/stack/ric/e2sm_kpm_common.h | 2 -- srsgnb/src/stack/ric/e2sm_kpm.cc | 14 -------------- 2 files changed, 16 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h index b048f0510..cb2b90499 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h @@ -57,8 +57,6 @@ enum e2sm_kpm_label_enum { UNKNOWN_LABEL = 0x8000 }; -e2sm_kpm_label_enum str2kpm_label(const std::string& label_str); - /* Scopes supported for a metric */ enum e2sm_kpm_metric_scope_enum { ENB_LEVEL = 0x0001, diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 7a2f8c35b..42087bfca 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -724,18 +724,4 @@ bool e2sm_kpm::_extract_last_real_type_meas_value(E2SM_KPM_meas_value_t& meas_va } return false; -} - -e2sm_kpm_label_enum str2kpm_label(const std::string& label_str) -{ - std::string label_str_uc{label_str}; - std::transform(label_str_uc.cbegin(), label_str_uc.cend(), label_str_uc.begin(), [](unsigned char c) { - return std::toupper(c); - }); - - if(label_str_uc == "NO_LABEL") return NO_LABEL; - else if(label_str_uc == "MIN_LABEL") return MIN_LABEL; - else if(label_str_uc == "MAX_LABEL") return MAX_LABEL; - else if(label_str_uc == "AVG_LABEL") return AVG_LABEL; - return UNKNOWN_LABEL; } \ No newline at end of file From e70a2eb4e85fbbcb111886a928014135ea53f1c3 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 30 Mar 2023 17:48:22 +0200 Subject: [PATCH 097/167] e2sm_kpm: move ind msg processing logic to separate class and use virtual funcs --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 40 +- srsgnb/hdr/stack/ric/e2sm_kpm_common.h | 8 - .../hdr/stack/ric/e2sm_kpm_report_service.h | 79 ++++ srsgnb/src/stack/ric/CMakeLists.txt | 2 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 406 ++---------------- .../src/stack/ric/e2sm_kpm_report_service.cc | 338 +++++++++++++++ 6 files changed, 451 insertions(+), 422 deletions(-) create mode 100644 srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h create mode 100644 srsgnb/src/stack/ric/e2sm_kpm_report_service.cc diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 86084fa1d..ea8ba91ca 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -23,6 +23,8 @@ using namespace asn1::e2ap; using namespace asn1::e2sm_kpm; +class e2sm_kpm_report_service; + class e2sm_kpm : public e2sm { public: @@ -43,41 +45,17 @@ public: virtual void receive_e2_metrics_callback(const enb_metrics_t& m); -private: - bool _process_ric_action_definition_format1(e2_sm_kpm_action_definition_format1_s& action_definition_format1); - bool _process_ric_action_definition_format2(e2_sm_kpm_action_definition_format2_s& action_definition_format2); - bool _process_ric_action_definition_format3(e2_sm_kpm_action_definition_format3_s& action_definition_format3); - bool _process_ric_action_definition_format4(e2_sm_kpm_action_definition_format4_s& action_definition_format4); - bool _process_ric_action_definition_format5(e2_sm_kpm_action_definition_format5_s& action_definition_format5); - - bool _initialize_ric_ind_msg_style1(uint32_t action_id, - e2_sm_kpm_action_definition_format1_s& action, - e2_sm_kpm_ind_msg_format1_s& ric_ind_msg); - - bool _clear_action_data(E2SM_KPM_action_data_t& action_data); - - meas_record_item_c::types - _get_meas_data_type(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list); + bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); + bool _extract_last_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); + bool _extract_last_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); + srslog::basic_logger& logger; - void _add_measurement_record(E2SM_KPM_meas_value_t& meas_value, meas_record_l& meas_record_list); +private: bool _generate_indication_header(e2_sm_kpm_ind_hdr_s& hdr, srsran::unique_byte_buffer_t& buf); bool _generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::unique_byte_buffer_t& buf); - bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); - meas_data_item_s& _get_meas_data_item_style1(e2_sm_kpm_ind_msg_s& ric_ind_msg, - std::string meas_name, - e2sm_kpm_label_enum label, - uint32_t ue_id, - bool& ref_found); - - std::vector _get_present_labels(const meas_info_item_s& action_meas_info_item); - - bool _extract_last_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); - bool _extract_last_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); - - srslog::basic_logger& logger; - std::vector supported_meas_types; - std::map registered_actions_data; + std::vector supported_meas_types; + std::map registered_actions_data; srsran_random_t random_gen; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h index cb2b90499..9a2a873f6 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h @@ -22,14 +22,6 @@ using namespace asn1::e2ap; using namespace asn1::e2sm_kpm; -typedef struct { - uint16_t action_id; - e2_sm_kpm_action_definition_s action_definition; - e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types ind_msg_format; - e2_sm_kpm_ind_hdr_s ric_ind_header; - e2_sm_kpm_ind_msg_s ric_ind_message; -} E2SM_KPM_action_data_t; - enum e2_metric_data_type_t { INTEGER, REAL }; typedef struct { diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h new file mode 100644 index 000000000..e746190ea --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h @@ -0,0 +1,79 @@ +/** + * + * \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 "srsgnb/hdr/stack/ric/e2sm_kpm.h" +#include "srsgnb/hdr/stack/ric/e2sm_kpm_common.h" +#include "srsran/asn1/e2ap.h" +#include "srsran/asn1/e2sm.h" +#include "srsran/asn1/e2sm_kpm_v2.h" +#include "srsran/srsran.h" + +#ifndef SRSRAN_E2SM_KPM_ACTION_DATA_H +#define SRSRAN_E2SM_KPM_ACTION_DATA_H + +using namespace asn1::e2ap; +using namespace asn1::e2sm_kpm; + +class e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service() = delete; + e2sm_kpm_report_service(e2sm_kpm* e2sm_kpm, uint16_t action_id, e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service() = default; + + virtual bool _initialize_ric_ind_hdr(); + virtual bool _initialize_ric_ind_msg() = 0; + virtual bool collect_data(const enb_metrics_t& enb_metrics) = 0; + virtual bool clear_collected_data() = 0; + + std::vector _get_present_labels(const meas_info_item_s& action_meas_info_item); + meas_record_item_c::types + _get_meas_data_type(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list); + void _add_measurement_record(E2SM_KPM_meas_value_t& meas_value, meas_record_l& meas_record_list); + + e2_sm_kpm_ind_hdr_s& get_ind_hdr() { return ric_ind_header_generic; }; + e2_sm_kpm_ind_msg_s& get_ind_msg() { return ric_ind_message_generic; }; + + e2sm_kpm* parent; + uint16_t action_id; + e2_sm_kpm_action_definition_s action_def_generic; + e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types ind_msg_format; + e2_sm_kpm_ind_hdr_s ric_ind_header_generic; + e2_sm_kpm_ind_msg_s ric_ind_message_generic; + + // hdr format 1 in base class, as all types use it + e2_sm_kpm_ind_hdr_format1_s& ric_ind_header; +}; + +class e2sm_kpm_report_service_style1 : public e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service_style1(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition); + + static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); + + virtual bool _initialize_ric_ind_msg(); + virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool clear_collected_data(); + +private: + meas_data_item_s& + _get_meas_data_item(std::string meas_name, e2sm_kpm_label_enum label, uint32_t ue_id, bool& ref_found); + + e2_sm_kpm_action_definition_format1_s& action_def; + e2_sm_kpm_ind_msg_format1_s& ric_ind_message; +}; + +#endif // SRSRAN_E2SM_KPM_ACTION_DATA_H diff --git a/srsgnb/src/stack/ric/CMakeLists.txt b/srsgnb/src/stack/ric/CMakeLists.txt index 17d368003..0082f7333 100644 --- a/srsgnb/src/stack/ric/CMakeLists.txt +++ b/srsgnb/src/stack/ric/CMakeLists.txt @@ -1,4 +1,4 @@ -set(SOURCES ric_client.cc ric_subscription.cc e2ap.cc e2sm_kpm.cc) +set(SOURCES ric_client.cc ric_subscription.cc e2ap.cc e2sm_kpm.cc e2sm_kpm_report_service.cc) add_library(srsgnb_ric STATIC ${SOURCES}) target_link_libraries(srsgnb_ric srsran_asn1 ric_e2) diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 42087bfca..9d2ad9ec0 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -13,6 +13,7 @@ #include "srsgnb/hdr/stack/ric/e2sm_kpm.h" #include "srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h" +#include "srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h" #include const std::string e2sm_kpm::short_name = "ORAN-E2SM-KPM"; @@ -47,105 +48,14 @@ e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_d } } -std::vector e2sm_kpm::_get_present_labels(const meas_info_item_s& action_meas_info_item) -{ - std::vector labels; - // TODO: add all labels defined in e2sm_kpm doc - for (uint32_t l = 0; l < action_meas_info_item.label_info_list.size(); l++) { - if (action_meas_info_item.label_info_list[l].meas_label.no_label_present) { - labels.push_back(NO_LABEL); - } - if (action_meas_info_item.label_info_list[l].meas_label.min_present) { - labels.push_back(MIN_LABEL); - } - if (action_meas_info_item.label_info_list[l].meas_label.max_present) { - labels.push_back(MAX_LABEL); - } - if (action_meas_info_item.label_info_list[l].meas_label.avg_present) { - labels.push_back(AVG_LABEL); - } - if (action_meas_info_item.label_info_list[l].meas_label.sum_present) { - labels.push_back(SUM_LABEL); - } - } - return labels; -} - void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) { last_enb_metrics = m; logger.debug("e2sm_kpm received new enb metrics, CPU0 Load: %.1f", last_enb_metrics.sys.cpu_load[0]); for (auto& it : registered_actions_data) { - uint32_t action_id = it.first; - e2_sm_kpm_action_definition_s& action = it.second.action_definition; - e2_sm_kpm_ind_msg_s& ric_ind_msg = it.second.ric_ind_message; - meas_info_list_l meas_info_list; - - switch (action.ric_style_type) { - case 1: - meas_info_list = ric_ind_msg.ind_msg_formats.ind_msg_format1().meas_info_list; - for (uint32_t i = 0; i < meas_info_list.size(); i++) { - meas_info_item_s meas_def_item = meas_info_list[i]; - std::string meas_name = meas_def_item.meas_type.meas_name().to_string(); - std::vector labels = _get_present_labels(meas_def_item); - - for (const auto& label : labels) { - // TODO: probably some labels need a special processing (e.g., use bin width that needs to be stored) - // get a proper record list - bool ref_found = false; - meas_data_item_s& meas_data_item = _get_meas_data_item_style1(ric_ind_msg, meas_name, label, 0, ref_found); - if (not ref_found) { - logger.info("Cannot find a meas record list, action_id %i, metric \"%s\" label: %i", - action_id, - meas_name.c_str(), - label); - return; - } - - // get data type - meas_record_item_c::types data_type = _get_meas_data_type(meas_name, label, meas_data_item.meas_record); - - // extract a needed value from enb metrics and add to the proper meas record list - E2SM_KPM_meas_value_t meas_value; - meas_value.name = meas_name; - meas_value.label = label; - // meas_values.scope = ...; - meas_value.data_type = data_type; - - if (meas_value.data_type == meas_record_item_c::types::options::integer) { - if (not _extract_last_integer_type_meas_value(meas_value, last_enb_metrics)) { - logger.info("Cannot extract value \"%s\" label: %i", meas_name.c_str(), label); - return; - } - } else { - // data_type == meas_record_item_c::types::options::real; - if (not _extract_last_real_type_meas_value(meas_value, last_enb_metrics)) { - logger.info("Cannot extract value \"%s\" label %i", meas_name.c_str(), label); - return; - } - } - // save meas value in the proper record list - _add_measurement_record(meas_value, meas_data_item.meas_record); - } - } - break; - case 2: - // TODO: add - break; - case 3: - // TODO: add - break; - case 4: - // TODO: add - break; - case 5: - // TODO: add - break; - default: - logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", action.ric_style_type); - return; - } + e2sm_kpm_report_service* report_service = it.second; + report_service->collect_data(m); } } @@ -172,7 +82,7 @@ bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, 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 - /* + /* TODO: seems that flexric does not like this part and crashes auto& report_style_list = e2sm_kpm_ra_nfunction_description.ric_report_style_list; report_style_list.resize(5); @@ -246,9 +156,7 @@ bool e2sm_kpm::process_ric_event_trigger_definition(ricsubscription_request_s bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action_t& action_entry) { - bool admit_action = false; - E2SM_KPM_action_data_t action_data; - + bool admit_action = false; e2_sm_kpm_action_definition_s e2sm_kpm_action_def; asn1::cbit_ref bref(ric_action.ric_action_definition.data(), ric_action.ric_action_definition.size()); @@ -258,24 +166,19 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a switch (e2sm_kpm_action_def.ric_style_type) { case 1: - admit_action = _process_ric_action_definition_format1( - e2sm_kpm_action_def.action_definition_formats.action_definition_format1()); + admit_action = e2sm_kpm_report_service_style1::process_ric_action_definition(this, e2sm_kpm_action_def); break; case 2: - admit_action = _process_ric_action_definition_format2( - e2sm_kpm_action_def.action_definition_formats.action_definition_format2()); + admit_action = false; break; case 3: - admit_action = _process_ric_action_definition_format3( - e2sm_kpm_action_def.action_definition_formats.action_definition_format3()); + admit_action = false; break; case 4: - admit_action = _process_ric_action_definition_format4( - e2sm_kpm_action_def.action_definition_formats.action_definition_format4()); + admit_action = false; break; case 5: - admit_action = _process_ric_action_definition_format5( - e2sm_kpm_action_def.action_definition_formats.action_definition_format5()); + admit_action = false; break; default: logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", @@ -290,45 +193,23 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a } action_entry.sm_local_ric_action_id = _generate_local_action_id(); - action_data.action_id = action_entry.sm_local_ric_action_id; - action_data.action_definition = e2sm_kpm_action_def; - - // initialize RIC indication header (always the same type 1) - action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().collet_start_time.from_number(std::time(0)); - // action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().file_formatversion.from_string(hdr.file_formatversion); - // action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().sender_name.from_string(hdr.sender_name); - // action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().sender_type.from_string(hdr.sender_type); - // action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().vendor_name.from_string(hdr.vendor_name); - - // initialize RIC indication message + e2sm_kpm_report_service* report_service; switch (e2sm_kpm_action_def.ric_style_type) { case 1: - action_data.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; - action_data.ric_ind_message.ind_msg_formats.set_ind_msg_format1(); - _initialize_ric_ind_msg_style1( - action_entry.sm_local_ric_action_id, - action_data.action_definition.action_definition_formats.action_definition_format1(), - action_data.ric_ind_message.ind_msg_formats.ind_msg_format1()); + report_service = + new e2sm_kpm_report_service_style1(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); break; case 2: - action_data.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; - action_data.ric_ind_message.ind_msg_formats.set_ind_msg_format1(); - // TODO: add initialization + admit_action = false; break; case 3: - action_data.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format2; - action_data.ric_ind_message.ind_msg_formats.set_ind_msg_format2(); - // TODO: add initialization + admit_action = false; break; case 4: - action_data.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format3; - action_data.ric_ind_message.ind_msg_formats.set_ind_msg_format3(); - // TODO: add initialization + admit_action = false; break; case 5: - action_data.ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format3; - action_data.ric_ind_message.ind_msg_formats.set_ind_msg_format3(); - // TODO: add initialization + admit_action = false; break; default: logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", @@ -339,96 +220,15 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a } registered_actions_data.insert( - std::pair(action_entry.sm_local_ric_action_id, action_data)); + std::pair(action_entry.sm_local_ric_action_id, report_service)); return admit_action; } -bool e2sm_kpm::_process_ric_action_definition_format1(e2_sm_kpm_action_definition_format1_s& action_definition_format1) -{ - uint64_t granul_period; - uint64_t eutra_cell_id; - uint64_t plmn_id; - ueid_c ue_id; - meas_info_list_l meas_info_list; - - granul_period = action_definition_format1.granul_period; - - if (granul_period == 0) { - logger.debug("Action granularity period of %i is not supported -> do not admitted action\n", granul_period); - return false; - } - - if (action_definition_format1.cell_global_id_present) { - if (action_definition_format1.cell_global_id.type() == cgi_c::types_opts::eutra_cgi) { - eutra_cell_id = action_definition_format1.cell_global_id.eutra_cgi().eutra_cell_id.to_number(); - plmn_id = action_definition_format1.cell_global_id.eutra_cgi().plmn_id.to_number(); - logger.debug("plmn_id 0x%x, eutra_cell_id %i", plmn_id, eutra_cell_id); - // TODO: check if E2 node has cell_id and plmn_id - } - } - - meas_info_list = action_definition_format1.meas_info_list; - for (uint32_t i = 0; i < meas_info_list.size(); i++) { - std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); - E2SM_KPM_metric_t metric_definition; - if (not _get_meas_definition(meas_name, metric_definition)) { - printf("Unsupported measurement name: \"%s\" --> do not admit action\n", meas_name.c_str()); - return false; - } - - printf("Admitted action: measurement name: \"%s\" with the following labels: \n", meas_name.c_str()); - // TODO: add all labels defined in e2sm_kpm doc, if at least one label not supported do not admit action? - for (uint32_t l = 0; l < meas_info_list[i].label_info_list.size(); l++) { - if (meas_info_list[i].label_info_list[l].meas_label.no_label_present) { - if (metric_definition.supported_labels & NO_LABEL) { - printf("--- Label %i: NO LABEL\n", i); - } - } - if (meas_info_list[i].label_info_list[l].meas_label.min_present) { - if (metric_definition.supported_labels & MIN_LABEL) { - printf("--- Label %i: MIN\n", i); - } - } - if (meas_info_list[i].label_info_list[l].meas_label.max_present) { - if (metric_definition.supported_labels & MAX_LABEL) { - printf("--- Label %i: MAX\n", i); - } - } - if (meas_info_list[i].label_info_list[l].meas_label.avg_present) { - if (metric_definition.supported_labels & AVG_LABEL) { - printf("--- Label %i: AVG\n", i); - } - } - } - } - - return true; -} - -bool e2sm_kpm::_process_ric_action_definition_format2(e2_sm_kpm_action_definition_format2_s& action_definition_format2) -{ - return false; -} - -bool e2sm_kpm::_process_ric_action_definition_format3(e2_sm_kpm_action_definition_format3_s& action_definition_format3) -{ - return false; -} - -bool e2sm_kpm::_process_ric_action_definition_format4(e2_sm_kpm_action_definition_format4_s& action_definition_format4) -{ - return false; -} - -bool e2sm_kpm::_process_ric_action_definition_format5(e2_sm_kpm_action_definition_format5_s& action_definition_format5) -{ - return false; -} - bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action_t& action_entry) { if (registered_actions_data.count(action_entry.sm_local_ric_action_id)) { + delete registered_actions_data.at(action_entry.sm_local_ric_action_id); registered_actions_data.erase(action_entry.sm_local_ric_action_id); return true; } @@ -445,86 +245,19 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr action_entry.sm_local_ric_action_id); return false; } - E2SM_KPM_action_data_t& action_data = registered_actions_data.at(action_id); - ric_indication.indication_type = ri_cind_type_opts::report; + e2sm_kpm_report_service* report_service = registered_actions_data.at(action_id); + ric_indication.indication_type = ri_cind_type_opts::report; // header is the same for all RIC service styles, i.e., type 1 ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); - this->_generate_indication_header(action_data.ric_ind_header, ric_indication.ri_cind_hdr); + this->_generate_indication_header(report_service->get_ind_hdr(), ric_indication.ri_cind_hdr); logger.info("Generating E2-SM-KPM Indication Message"); ric_indication.ri_cind_msg = srsran::make_byte_buffer(); - this->_generate_indication_message(action_data.ric_ind_message, ric_indication.ri_cind_msg); + this->_generate_indication_message(report_service->get_ind_msg(), ric_indication.ri_cind_msg); // clear data collected for this action - _clear_action_data(action_data); - return true; -} - -bool e2sm_kpm::_initialize_ric_ind_msg_style1(uint32_t action_id, - e2_sm_kpm_action_definition_format1_s& action, - e2_sm_kpm_ind_msg_format1_s& ric_ind_msg) -{ - meas_info_list_l action_meas_info_list = action.meas_info_list; - - // ric_ind_message.granul_period = action.granul_period; // not implemented by flexric and crashes it - ric_ind_msg.granul_period = 0; - ric_ind_msg.meas_info_list.resize(action_meas_info_list.size()); - ric_ind_msg.meas_data.resize(action_meas_info_list.size()); - - // add measurement info - for (uint32_t i = 0; i < ric_ind_msg.meas_info_list.size(); i++) { - // structs to fill - meas_info_item_s& meas_info_item = ric_ind_msg.meas_info_list[i]; - - // measurements definition - meas_info_item_s meas_def_item = action_meas_info_list[i]; - std::string meas_name = meas_def_item.meas_type.meas_name().to_string(); - - meas_info_item.meas_type.set_meas_name().from_string(meas_name.c_str()); - meas_info_item.label_info_list.resize(meas_def_item.label_info_list.size()); - - // TODO: add all labels defined in e2sm_kpm doc - for (uint32_t l = 0; l < meas_def_item.label_info_list.size(); l++) { - if (meas_def_item.label_info_list[l].meas_label.no_label_present) { - meas_info_item.label_info_list[l].meas_label.no_label_present = true; - meas_info_item.label_info_list[l].meas_label.no_label = meas_label_s::no_label_opts::true_value; - } - if (meas_def_item.label_info_list[l].meas_label.min_present) { - meas_info_item.label_info_list[l].meas_label.min_present = true; - meas_info_item.label_info_list[l].meas_label.min = meas_label_s::min_opts::true_value; - } - if (meas_def_item.label_info_list[l].meas_label.max_present) { - meas_info_item.label_info_list[l].meas_label.max_present = true; - meas_info_item.label_info_list[l].meas_label.max = meas_label_s::max_opts::true_value; - } - if (meas_def_item.label_info_list[l].meas_label.avg_present) { - meas_info_item.label_info_list[l].meas_label.avg_present = true; - meas_info_item.label_info_list[l].meas_label.avg = meas_label_s::avg_opts::true_value; - } - if (meas_def_item.label_info_list[l].meas_label.sum_present) { - meas_info_item.label_info_list[l].meas_label.sum_present = true; - meas_info_item.label_info_list[l].meas_label.sum = meas_label_s::sum_opts::true_value; - } - } - } - - return true; -} - -bool e2sm_kpm::_clear_action_data(E2SM_KPM_action_data_t& action_data) -{ - switch (action_data.action_definition.ric_style_type) { - case 1: - action_data.ric_ind_header.ind_hdr_formats.ind_hdr_format1().collet_start_time.from_number(std::time(0)); - for (uint32_t i = 0; i < action_data.ric_ind_message.ind_msg_formats.ind_msg_format1().meas_data.size(); ++i) { - action_data.ric_ind_message.ind_msg_formats.ind_msg_format1().meas_data[i].meas_record.clear(); - } - break; - default: - break; - } - + report_service->clear_collected_data(); return true; } @@ -540,97 +273,6 @@ bool e2sm_kpm::_get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& de return true; } -meas_data_item_s& e2sm_kpm::_get_meas_data_item_style1(e2_sm_kpm_ind_msg_s& ric_ind_msg_generic, - std::string meas_name, - e2sm_kpm_label_enum label, - uint32_t ue_id, - bool& ref_found) -{ - e2_sm_kpm_ind_msg_format1_s& ric_ind_msg = ric_ind_msg_generic.ind_msg_formats.ind_msg_format1(); - meas_info_list_l& meas_info_list = ric_ind_msg.meas_info_list; - ref_found = false; - // find proper index of the metric - for (uint32_t i = 0; i < meas_info_list.size(); i++) { - // measurements definition - meas_info_item_s meas_def_item = meas_info_list[i]; - std::string meas_def_name = meas_def_item.meas_type.meas_name().to_string(); - - // TODO: check if UE_ID matches (for format2 and 3) - // check if the metric name matches - if (meas_def_name != meas_name.c_str()) { - continue; - } - - // check if the metric label matches - // TODO: add all labels defined in e2sm_kpm doc - for (uint32_t l = 0; l < meas_def_item.label_info_list.size(); l++) { - if (meas_def_item.label_info_list[l].meas_label.no_label_present and label == NO_LABEL) { - ref_found = true; - return ric_ind_msg.meas_data[i]; - } - if (meas_def_item.label_info_list[l].meas_label.min_present and label == MIN_LABEL) { - ref_found = true; - return ric_ind_msg.meas_data[i]; - } - if (meas_def_item.label_info_list[l].meas_label.max_present and label == MAX_LABEL) { - ref_found = true; - return ric_ind_msg.meas_data[i]; - } - if (meas_def_item.label_info_list[l].meas_label.avg_present and label == AVG_LABEL) { - ref_found = true; - return ric_ind_msg.meas_data[i]; - } - if (meas_def_item.label_info_list[l].meas_label.sum_present and label == SUM_LABEL) { - ref_found = true; - return ric_ind_msg.meas_data[i]; - } - } - } - // TODO assert if match == false, has to be present as was created during initialization - ref_found = false; - return ric_ind_msg.meas_data[0]; -} - -meas_record_item_c::types -e2sm_kpm::_get_meas_data_type(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list) -{ - meas_record_item_c::types data_type = meas_record_item_c::types::options::nulltype; - // if no data collected check the type using metric definition - if (meas_record_list.size() == 0) { - E2SM_KPM_metric_t metric_definition; - if (not _get_meas_definition(meas_name, metric_definition)) { - logger.debug("No definition for measurement type \"%s\"", metric_definition.name); - return data_type; - } - if (metric_definition.data_type == INTEGER) { - data_type = meas_record_item_c::types::options::integer; - } else { - data_type = meas_record_item_c::types::options::real; - } - } else { - // check the data type of the first element in the list - data_type = meas_record_list[0].type(); - } - return data_type; -} - -void e2sm_kpm::_add_measurement_record(E2SM_KPM_meas_value_t& meas_value, meas_record_l& meas_record_list) -{ - if (meas_value.data_type == meas_record_item_c::types::options::integer) { - meas_record_item_c item; - item.set_integer() = meas_value.integer_value; - meas_record_list.push_back(item); - } else { - // data_type == meas_record_item_c::types::options::real; - meas_record_item_c item; - real_s real_value; - // TODO: real value seems to be not supported in asn1??? - // real_value.value = meas_value.real_value; - item.set_real() = real_value; - meas_record_list.push_back(item); - } -} - bool e2sm_kpm::_generate_indication_header(e2_sm_kpm_ind_hdr_s& hdr, srsran::unique_byte_buffer_t& buf) { asn1::bit_ref bref(buf->msg, buf->get_tailroom()); diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc new file mode 100644 index 000000000..fc31945ee --- /dev/null +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -0,0 +1,338 @@ +/** + * + * \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 "srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h" + +e2sm_kpm_report_service::e2sm_kpm_report_service(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + parent(e2sm_kpm), + action_id(action_id), + action_def_generic(action_definition), + ric_ind_header_generic(), + ric_ind_header(ric_ind_header_generic.ind_hdr_formats.ind_hdr_format1()) +{ +} + +std::vector +e2sm_kpm_report_service::_get_present_labels(const meas_info_item_s& action_meas_info_item) +{ + std::vector labels; + // TODO: add all labels defined in e2sm_kpm doc + for (uint32_t l = 0; l < action_meas_info_item.label_info_list.size(); l++) { + if (action_meas_info_item.label_info_list[l].meas_label.no_label_present) { + labels.push_back(NO_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.min_present) { + labels.push_back(MIN_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.max_present) { + labels.push_back(MAX_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.avg_present) { + labels.push_back(AVG_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.sum_present) { + labels.push_back(SUM_LABEL); + } + } + return labels; +} + +bool e2sm_kpm_report_service::_initialize_ric_ind_hdr() +{ + // TODO: set the remaining fields properly (they are optional) + ric_ind_header.collet_start_time.from_number(std::time(0)); + // ric_ind_header.file_formatversion.from_string(hdr.file_formatversion); + // ric_ind_header.sender_name.from_string(hdr.sender_name); + // ric_ind_header.sender_type.from_string(hdr.sender_type); + // ric_ind_header.vendor_name.from_string(hdr.vendor_name); + return true; +} + +meas_record_item_c::types e2sm_kpm_report_service::_get_meas_data_type(std::string meas_name, + e2sm_kpm_label_enum label, + meas_record_l& meas_record_list) +{ + meas_record_item_c::types data_type = meas_record_item_c::types::options::nulltype; + // if no data collected check the type using metric definition + if (meas_record_list.size() == 0) { + E2SM_KPM_metric_t metric_definition; + if (not parent->_get_meas_definition(meas_name, metric_definition)) { + parent->logger.debug("No definition for measurement type \"%s\"", metric_definition.name); + return data_type; + } + if (metric_definition.data_type == INTEGER) { + data_type = meas_record_item_c::types::options::integer; + } else { + data_type = meas_record_item_c::types::options::real; + } + } else { + // check the data type of the first element in the list + data_type = meas_record_list[0].type(); + } + return data_type; +} + +void e2sm_kpm_report_service::_add_measurement_record(E2SM_KPM_meas_value_t& meas_value, + meas_record_l& meas_record_list) +{ + if (meas_value.data_type == meas_record_item_c::types::options::integer) { + meas_record_item_c item; + item.set_integer() = meas_value.integer_value; + meas_record_list.push_back(item); + } else { + // data_type == meas_record_item_c::types::options::real; + meas_record_item_c item; + real_s real_value; + // TODO: real value seems to be not supported in asn1??? + // real_value.value = meas_value.real_value; + item.set_real() = real_value; + meas_record_list.push_back(item); + } +} + +e2sm_kpm_report_service_style1::e2sm_kpm_report_service_style1(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + e2sm_kpm_report_service(e2sm_kpm, action_id, action_definition), + action_def(action_def_generic.action_definition_formats.action_definition_format1()), + ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format1()) +{ + ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + this->_initialize_ric_ind_hdr(); + this->_initialize_ric_ind_msg(); +} + +bool e2sm_kpm_report_service_style1::_initialize_ric_ind_msg() +{ + meas_info_list_l action_meas_info_list = action_def.meas_info_list; + + // ric_ind_message.granul_period = action.granul_period; // not implemented by flexric and crashes it + ric_ind_message.granul_period = 0; + ric_ind_message.meas_info_list.resize(action_meas_info_list.size()); + ric_ind_message.meas_data.resize(action_meas_info_list.size()); + + // add measurement info + for (uint32_t i = 0; i < ric_ind_message.meas_info_list.size(); i++) { + // structs to fill + meas_info_item_s& meas_info_item = ric_ind_message.meas_info_list[i]; + + // measurements definition + meas_info_item_s& meas_def_item = action_meas_info_list[i]; + std::string meas_name = meas_def_item.meas_type.meas_name().to_string(); + + meas_info_item.meas_type.set_meas_name().from_string(meas_name.c_str()); + meas_info_item.label_info_list.resize(meas_def_item.label_info_list.size()); + + // TODO: add all labels defined in e2sm_kpm doc, make this part generic and put to the base class + for (uint32_t l = 0; l < meas_def_item.label_info_list.size(); l++) { + if (meas_def_item.label_info_list[l].meas_label.no_label_present) { + meas_info_item.label_info_list[l].meas_label.no_label_present = true; + meas_info_item.label_info_list[l].meas_label.no_label = meas_label_s::no_label_opts::true_value; + } + if (meas_def_item.label_info_list[l].meas_label.min_present) { + meas_info_item.label_info_list[l].meas_label.min_present = true; + meas_info_item.label_info_list[l].meas_label.min = meas_label_s::min_opts::true_value; + } + if (meas_def_item.label_info_list[l].meas_label.max_present) { + meas_info_item.label_info_list[l].meas_label.max_present = true; + meas_info_item.label_info_list[l].meas_label.max = meas_label_s::max_opts::true_value; + } + if (meas_def_item.label_info_list[l].meas_label.avg_present) { + meas_info_item.label_info_list[l].meas_label.avg_present = true; + meas_info_item.label_info_list[l].meas_label.avg = meas_label_s::avg_opts::true_value; + } + if (meas_def_item.label_info_list[l].meas_label.sum_present) { + meas_info_item.label_info_list[l].meas_label.sum_present = true; + meas_info_item.label_info_list[l].meas_label.sum = meas_label_s::sum_opts::true_value; + } + } + } + + return true; +} + +bool e2sm_kpm_report_service_style1::process_ric_action_definition(e2sm_kpm* e2sm_kpm, + e2_sm_kpm_action_definition_s& action_def_generic) +{ + e2_sm_kpm_action_definition_format1_s& action_definition = + action_def_generic.action_definition_formats.action_definition_format1(); + + uint64_t granul_period; + uint64_t eutra_cell_id; + uint64_t plmn_id; + ueid_c ue_id; + meas_info_list_l meas_info_list; + + granul_period = action_definition.granul_period; + + if (granul_period == 0) { + e2sm_kpm->logger.debug("Action granularity period of %i is not supported -> do not admitted action\n", + granul_period); + return false; + } + + if (action_definition.cell_global_id_present) { + if (action_definition.cell_global_id.type() == cgi_c::types_opts::eutra_cgi) { + eutra_cell_id = action_definition.cell_global_id.eutra_cgi().eutra_cell_id.to_number(); + plmn_id = action_definition.cell_global_id.eutra_cgi().plmn_id.to_number(); + e2sm_kpm->logger.debug("plmn_id 0x%x, eutra_cell_id %i", plmn_id, eutra_cell_id); + // TODO: check if E2 node has cell_id and plmn_id + } + } + + meas_info_list = action_definition.meas_info_list; + for (uint32_t i = 0; i < meas_info_list.size(); i++) { + std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); + E2SM_KPM_metric_t metric_definition; + if (not e2sm_kpm->_get_meas_definition(meas_name, metric_definition)) { + printf("Unsupported measurement name: \"%s\" --> do not admit action\n", meas_name.c_str()); + return false; + } + + printf("Admitted action: measurement name: \"%s\" with the following labels: \n", meas_name.c_str()); + // TODO: add all labels defined in e2sm_kpm doc, if at least one label not supported do not admit action? + for (uint32_t l = 0; l < meas_info_list[i].label_info_list.size(); l++) { + if (meas_info_list[i].label_info_list[l].meas_label.no_label_present) { + if (metric_definition.supported_labels & NO_LABEL) { + printf("--- Label %i: NO LABEL\n", i); + } + } + if (meas_info_list[i].label_info_list[l].meas_label.min_present) { + if (metric_definition.supported_labels & MIN_LABEL) { + printf("--- Label %i: MIN\n", i); + } + } + if (meas_info_list[i].label_info_list[l].meas_label.max_present) { + if (metric_definition.supported_labels & MAX_LABEL) { + printf("--- Label %i: MAX\n", i); + } + } + if (meas_info_list[i].label_info_list[l].meas_label.avg_present) { + if (metric_definition.supported_labels & AVG_LABEL) { + printf("--- Label %i: AVG\n", i); + } + } + } + } + + return true; +} + +meas_data_item_s& e2sm_kpm_report_service_style1::_get_meas_data_item(std::string meas_name, + e2sm_kpm_label_enum label, + uint32_t ue_id, + bool& ref_found) +{ + meas_info_list_l& meas_info_list = ric_ind_message.meas_info_list; + ref_found = false; + // find proper index of the metric + for (uint32_t i = 0; i < meas_info_list.size(); i++) { + // measurements definition + meas_info_item_s meas_def_item = meas_info_list[i]; + std::string meas_def_name = meas_def_item.meas_type.meas_name().to_string(); + + // check if the metric name matches + if (meas_def_name != meas_name.c_str()) { + continue; + } + + // check if the metric label matches + // TODO: add all labels defined in e2sm_kpm doc + for (uint32_t l = 0; l < meas_def_item.label_info_list.size(); l++) { + if (meas_def_item.label_info_list[l].meas_label.no_label_present and label == NO_LABEL) { + ref_found = true; + return ric_ind_message.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.min_present and label == MIN_LABEL) { + ref_found = true; + return ric_ind_message.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.max_present and label == MAX_LABEL) { + ref_found = true; + return ric_ind_message.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.avg_present and label == AVG_LABEL) { + ref_found = true; + return ric_ind_message.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.sum_present and label == SUM_LABEL) { + ref_found = true; + return ric_ind_message.meas_data[i]; + } + } + } + // TODO assert if match == false, has to be present as was created during initialization + ref_found = false; + return ric_ind_message.meas_data[0]; +} + +bool e2sm_kpm_report_service_style1::collect_data(const enb_metrics_t& enb_metrics) +{ + meas_info_list_l& meas_info_list = ric_ind_message.meas_info_list; + for (uint32_t i = 0; i < meas_info_list.size(); i++) { + meas_info_item_s& meas_def_item = meas_info_list[i]; + std::string meas_name = meas_def_item.meas_type.meas_name().to_string(); + std::vector labels = _get_present_labels(meas_def_item); + + for (const auto& label : labels) { + // TODO: probably some labels need a special processing (e.g., use bin width that needs to be stored) + // get a proper record list + bool ref_found = false; + meas_data_item_s& meas_data_item = _get_meas_data_item(meas_name, label, 0, ref_found); + if (not ref_found) { + parent->logger.info("Cannot find a meas record list, action_id %i, metric \"%s\" label: %i", + action_id, + meas_name.c_str(), + label); + return false; + } + + // get data type + meas_record_item_c::types data_type = _get_meas_data_type(meas_name, label, meas_data_item.meas_record); + + // extract a needed value from enb metrics and add to the proper meas record list + E2SM_KPM_meas_value_t meas_value; + meas_value.name = meas_name; + meas_value.label = label; + // meas_values.scope = ...; + meas_value.data_type = data_type; + + if (meas_value.data_type == meas_record_item_c::types::options::integer) { + if (not parent->_extract_last_integer_type_meas_value(meas_value, enb_metrics)) { + parent->logger.info("Cannot extract value \"%s\" label: %i", meas_name.c_str(), label); + return false; + } + } else { + // data_type == meas_record_item_c::types::options::real; + if (not parent->_extract_last_real_type_meas_value(meas_value, enb_metrics)) { + parent->logger.info("Cannot extract value \"%s\" label %i", meas_name.c_str(), label); + return false; + } + } + // save meas value in the proper record list + _add_measurement_record(meas_value, meas_data_item.meas_record); + } + } + return true; +} + +bool e2sm_kpm_report_service_style1::clear_collected_data() +{ + ric_ind_header.collet_start_time.from_number(std::time(0)); + for (uint32_t i = 0; i < ric_ind_message.meas_data.size(); ++i) { + ric_ind_message.meas_data[i].meas_record.clear(); + } + return true; +} \ No newline at end of file From bce8d65ec08174f58610eed1deee529ef6fe6865 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 30 Mar 2023 18:09:29 +0200 Subject: [PATCH 098/167] e2sm_kpm: change function order --- srsgnb/src/stack/ric/e2sm_kpm.cc | 47 ++++++++++++++++---------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 9d2ad9ec0..e6184553c 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -48,17 +48,6 @@ e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_d } } -void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) -{ - last_enb_metrics = m; - logger.debug("e2sm_kpm received new enb metrics, CPU0 Load: %.1f", last_enb_metrics.sys.cpu_load[0]); - - for (auto& it : registered_actions_data) { - e2sm_kpm_report_service* report_service = it.second; - report_service->collect_data(m); - } -} - bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func) { desc.function_shortname = short_name; @@ -261,18 +250,6 @@ bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entr return true; } -bool e2sm_kpm::_get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def) -{ - // TODO: we need a generic string comparison, why do we need c_str() here? - auto name_matches = [&meas_name](const E2SM_KPM_metric_t& x) { return x.name == meas_name.c_str(); }; - auto it = std::find_if(supported_meas_types.begin(), supported_meas_types.end(), name_matches); - if (it == supported_meas_types.end()) { - return false; - } - def = *it; - return true; -} - bool e2sm_kpm::_generate_indication_header(e2_sm_kpm_ind_hdr_s& hdr, srsran::unique_byte_buffer_t& buf) { asn1::bit_ref bref(buf->msg, buf->get_tailroom()); @@ -298,6 +275,30 @@ bool e2sm_kpm::_generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::un return true; } +bool e2sm_kpm::_get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def) +{ + auto name_matches = [&meas_name](const E2SM_KPM_metric_t& x) { + return (x.name == meas_name.c_str() or x.name == meas_name); + }; + auto it = std::find_if(supported_meas_types.begin(), supported_meas_types.end(), name_matches); + if (it == supported_meas_types.end()) { + return false; + } + def = *it; + return true; +} + +void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) +{ + last_enb_metrics = m; + logger.debug("e2sm_kpm received new enb metrics, CPU0 Load: %.1f", last_enb_metrics.sys.cpu_load[0]); + + for (auto& it : registered_actions_data) { + e2sm_kpm_report_service* report_service = it.second; + report_service->collect_data(m); + } +} + bool e2sm_kpm::_extract_last_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics) { From 62d1ba059f151d2da2f5c35a5d51cf2c874e6026 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 30 Mar 2023 18:12:08 +0200 Subject: [PATCH 099/167] e2sm: change function name to generate_ric_indication_content --- srsgnb/hdr/stack/ric/e2sm.h | 6 +++--- srsgnb/hdr/stack/ric/e2sm_kpm.h | 2 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 2 +- srsgnb/src/stack/ric/ric_subscription.cc | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index bb2cf1ed0..4ea986b08 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -62,12 +62,12 @@ public: uint32_t get_revision() { return _revision; }; virtual bool generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func) = 0; - virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, + virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, RIC_event_trigger_definition_t& event_def) = 0; virtual bool process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, - E2AP_RIC_action_t& action_entry) = 0; + E2AP_RIC_action_t& action_entry) = 0; virtual bool remove_ric_action_definition(E2AP_RIC_action_t& action_entry) = 0; - virtual bool execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication) = 0; + virtual bool generate_ric_indication_content(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication) = 0; virtual void receive_e2_metrics_callback(const enb_metrics_t& m) = 0; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index ea8ba91ca..b622c7f5b 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -41,7 +41,7 @@ public: RIC_event_trigger_definition_t& event_def); virtual bool process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action_t& action_entry); virtual bool remove_ric_action_definition(E2AP_RIC_action_t& action_entry); - virtual bool execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication); + virtual bool generate_ric_indication_content(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication); virtual void receive_e2_metrics_callback(const enb_metrics_t& m); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index e6184553c..bb972e74c 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -224,7 +224,7 @@ bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action_t& action_entry) return false; } -bool e2sm_kpm::execute_action_fill_ric_indication(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication) +bool e2sm_kpm::generate_ric_indication_content(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication) { uint32_t action_id = action_entry.sm_local_ric_action_id; if (!registered_actions_data.count(action_id)) { diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index a754419e6..0b4c3a5bd 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -211,7 +211,7 @@ void ric_client::ric_subscription::send_ric_indication() ric_indication.ri_caction_id = action.ric_action_id; ric_indication.ri_indication_sn_present = true; ric_indication.ri_indication_sn = _generate_ric_indication_sn(); - sm_ptr->execute_action_fill_ric_indication(action, ric_indication); + sm_ptr->generate_ric_indication_content(action, ric_indication); e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(ric_indication); parent->queue_send_e2ap_pdu(send_pdu); From d384916b6831886d1594c60b9bf324c152b7e32b Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 30 Mar 2023 18:14:12 +0200 Subject: [PATCH 100/167] e2sm_kpm: change function names --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 4 ++-- srsgnb/src/stack/ric/e2sm_kpm.cc | 4 ++-- srsgnb/src/stack/ric/e2sm_kpm_report_service.cc | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index b622c7f5b..57c5458a0 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -46,8 +46,8 @@ public: virtual void receive_e2_metrics_callback(const enb_metrics_t& m); bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); - bool _extract_last_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); - bool _extract_last_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); + bool _extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); + bool _extract_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); srslog::basic_logger& logger; private: diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index bb972e74c..eeda72db0 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -299,7 +299,7 @@ void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) } } -bool e2sm_kpm::_extract_last_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, +bool e2sm_kpm::_extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics) { // TODO: maybe add ID to metric types in e2sm_kpm_metrics definitions, so we do not have to compare strings? @@ -332,7 +332,7 @@ bool e2sm_kpm::_extract_last_integer_type_meas_value(E2SM_KPM_meas_value_t& meas return false; } -bool e2sm_kpm::_extract_last_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics) +bool e2sm_kpm::_extract_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics) { // all real type measurements // cpu0_load: no_label diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index fc31945ee..35d8f0e99 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -310,13 +310,13 @@ bool e2sm_kpm_report_service_style1::collect_data(const enb_metrics_t& enb_metri meas_value.data_type = data_type; if (meas_value.data_type == meas_record_item_c::types::options::integer) { - if (not parent->_extract_last_integer_type_meas_value(meas_value, enb_metrics)) { + if (not parent->_extract_integer_type_meas_value(meas_value, enb_metrics)) { parent->logger.info("Cannot extract value \"%s\" label: %i", meas_name.c_str(), label); return false; } } else { // data_type == meas_record_item_c::types::options::real; - if (not parent->_extract_last_real_type_meas_value(meas_value, enb_metrics)) { + if (not parent->_extract_real_type_meas_value(meas_value, enb_metrics)) { parent->logger.info("Cannot extract value \"%s\" label %i", meas_name.c_str(), label); return false; } From d6534b633903009ea3d9463a9d74e6206c037fac Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 30 Mar 2023 18:14:41 +0200 Subject: [PATCH 101/167] e2sm_kpm: clean process_ric_action_definition func --- srsgnb/hdr/stack/ric/e2sm.h | 3 ++- srsgnb/src/stack/ric/e2sm_kpm.cc | 34 ++++++++------------------------ 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index 4ea986b08..c3e975ed6 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -72,7 +72,8 @@ public: virtual void receive_e2_metrics_callback(const enb_metrics_t& m) = 0; protected: - uint32_t _generate_local_action_id() { return _registered_action_id_gen++; }; + uint32_t _get_local_action_id() { return _registered_action_id_gen; }; + uint32_t _generate_new_local_action_id() { return _registered_action_id_gen++; }; private: const std::string _short_name; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index eeda72db0..5fea232ef 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -153,9 +153,16 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a return false; } + action_entry.sm_local_ric_action_id = _get_local_action_id(); + e2sm_kpm_report_service* report_service; + switch (e2sm_kpm_action_def.ric_style_type) { case 1: admit_action = e2sm_kpm_report_service_style1::process_ric_action_definition(this, e2sm_kpm_action_def); + if (admit_action) { + report_service = + new e2sm_kpm_report_service_style1(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); + } break; case 2: admit_action = false; @@ -181,32 +188,7 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a return false; } - action_entry.sm_local_ric_action_id = _generate_local_action_id(); - e2sm_kpm_report_service* report_service; - switch (e2sm_kpm_action_def.ric_style_type) { - case 1: - report_service = - new e2sm_kpm_report_service_style1(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); - break; - case 2: - admit_action = false; - break; - case 3: - admit_action = false; - break; - case 4: - admit_action = false; - break; - case 5: - admit_action = false; - break; - default: - logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", - e2sm_kpm_action_def.ric_style_type, - ric_action.ric_action_id, - ric_action.ric_action_type); - return false; - } + _generate_new_local_action_id(); registered_actions_data.insert( std::pair(action_entry.sm_local_ric_action_id, report_service)); From ea8886ced6ed69f5e51b7835f4fcc3b32e6f9750 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 30 Mar 2023 18:29:53 +0200 Subject: [PATCH 102/167] e2sm_kpm: add empty classes for all report service styles --- .../hdr/stack/ric/e2sm_kpm_report_service.h | 77 +++++++++ srsgnb/src/stack/ric/e2sm_kpm.cc | 24 ++- .../src/stack/ric/e2sm_kpm_report_service.cc | 148 ++++++++++++++++++ 3 files changed, 245 insertions(+), 4 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h index e746190ea..f449db264 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h @@ -61,6 +61,7 @@ public: e2sm_kpm_report_service_style1(e2sm_kpm* e2sm_kpm, uint16_t action_id, e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service_style1() = default; static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); @@ -76,4 +77,80 @@ private: e2_sm_kpm_ind_msg_format1_s& ric_ind_message; }; +class e2sm_kpm_report_service_style2 : public e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service_style2(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service_style2() = default; + + static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); + + virtual bool _initialize_ric_ind_msg(); + virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool clear_collected_data(); + +private: + e2_sm_kpm_action_definition_format2_s& action_def; + e2_sm_kpm_ind_msg_format1_s& ric_ind_message; +}; + +class e2sm_kpm_report_service_style3 : public e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service_style3(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service_style3() = default; + + static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); + + virtual bool _initialize_ric_ind_msg(); + virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool clear_collected_data(); + +private: + e2_sm_kpm_action_definition_format3_s& action_def; + e2_sm_kpm_ind_msg_format2_s& ric_ind_message; +}; + +class e2sm_kpm_report_service_style4 : public e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service_style4(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service_style4() = default; + + static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); + + virtual bool _initialize_ric_ind_msg(); + virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool clear_collected_data(); + +private: + e2_sm_kpm_action_definition_format4_s& action_def; + e2_sm_kpm_ind_msg_format3_s& ric_ind_message; +}; + +class e2sm_kpm_report_service_style5 : public e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service_style5(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service_style5() = default; + + static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); + + virtual bool _initialize_ric_ind_msg(); + virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool clear_collected_data(); + +private: + e2_sm_kpm_action_definition_format5_s& action_def; + e2_sm_kpm_ind_msg_format3_s& ric_ind_message; +}; + #endif // SRSRAN_E2SM_KPM_ACTION_DATA_H diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 5fea232ef..c67759022 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -165,16 +165,32 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a } break; case 2: - admit_action = false; + admit_action = e2sm_kpm_report_service_style2::process_ric_action_definition(this, e2sm_kpm_action_def); + if (admit_action) { + report_service = + new e2sm_kpm_report_service_style2(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); + } break; case 3: - admit_action = false; + admit_action = e2sm_kpm_report_service_style3::process_ric_action_definition(this, e2sm_kpm_action_def); + if (admit_action) { + report_service = + new e2sm_kpm_report_service_style3(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); + } break; case 4: - admit_action = false; + admit_action = e2sm_kpm_report_service_style4::process_ric_action_definition(this, e2sm_kpm_action_def); + if (admit_action) { + report_service = + new e2sm_kpm_report_service_style4(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); + } break; case 5: - admit_action = false; + admit_action = e2sm_kpm_report_service_style5::process_ric_action_definition(this, e2sm_kpm_action_def); + if (admit_action) { + report_service = + new e2sm_kpm_report_service_style5(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); + } break; default: logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index 35d8f0e99..d31d35d52 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -335,4 +335,152 @@ bool e2sm_kpm_report_service_style1::clear_collected_data() ric_ind_message.meas_data[i].meas_record.clear(); } return true; +} + +e2sm_kpm_report_service_style2::e2sm_kpm_report_service_style2(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + e2sm_kpm_report_service(e2sm_kpm, action_id, action_definition), + action_def(action_def_generic.action_definition_formats.action_definition_format2()), + ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format1()) +{ + ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + this->_initialize_ric_ind_hdr(); + this->_initialize_ric_ind_msg(); +} + +bool e2sm_kpm_report_service_style2::_initialize_ric_ind_msg() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style2::process_ric_action_definition(e2sm_kpm* e2sm_kpm, + e2_sm_kpm_action_definition_s& action_def_generic) +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style2::collect_data(const enb_metrics_t& enb_metrics) +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style2::clear_collected_data() +{ + // TODO: implement + return false; +} + +e2sm_kpm_report_service_style3::e2sm_kpm_report_service_style3(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + e2sm_kpm_report_service(e2sm_kpm, action_id, action_definition), + action_def(action_def_generic.action_definition_formats.action_definition_format3()), + ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format2()) +{ + ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + this->_initialize_ric_ind_hdr(); + this->_initialize_ric_ind_msg(); +} + +bool e2sm_kpm_report_service_style3::_initialize_ric_ind_msg() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style3::process_ric_action_definition(e2sm_kpm* e2sm_kpm, + e2_sm_kpm_action_definition_s& action_def_generic) +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style3::collect_data(const enb_metrics_t& enb_metrics) +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style3::clear_collected_data() +{ + // TODO: implement + return false; +} + +e2sm_kpm_report_service_style4::e2sm_kpm_report_service_style4(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + e2sm_kpm_report_service(e2sm_kpm, action_id, action_definition), + action_def(action_def_generic.action_definition_formats.action_definition_format4()), + ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format3()) +{ + ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + this->_initialize_ric_ind_hdr(); + this->_initialize_ric_ind_msg(); +} + +bool e2sm_kpm_report_service_style4::_initialize_ric_ind_msg() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style4::process_ric_action_definition(e2sm_kpm* e2sm_kpm, + e2_sm_kpm_action_definition_s& action_def_generic) +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style4::collect_data(const enb_metrics_t& enb_metrics) +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style4::clear_collected_data() +{ + // TODO: implement + return false; +} + +e2sm_kpm_report_service_style5::e2sm_kpm_report_service_style5(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + e2sm_kpm_report_service(e2sm_kpm, action_id, action_definition), + action_def(action_def_generic.action_definition_formats.action_definition_format5()), + ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format3()) +{ + ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + this->_initialize_ric_ind_hdr(); + this->_initialize_ric_ind_msg(); +} + +bool e2sm_kpm_report_service_style5::_initialize_ric_ind_msg() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style5::process_ric_action_definition(e2sm_kpm* e2sm_kpm, + e2_sm_kpm_action_definition_s& action_def_generic) +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style5::collect_data(const enb_metrics_t& enb_metrics) +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style5::clear_collected_data() +{ + // TODO: implement + return false; } \ No newline at end of file From b6e8f85333bc2589d542ddf68432aff38ee36187 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 30 Mar 2023 18:36:15 +0200 Subject: [PATCH 103/167] e2sm_kpm: make e2sm_kpm_report_service classes friend of e2sm_kpm --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 57c5458a0..5ae9fb599 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -45,15 +45,21 @@ public: virtual void receive_e2_metrics_callback(const enb_metrics_t& m); - bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); - bool _extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); - bool _extract_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); - srslog::basic_logger& logger; + friend class e2sm_kpm_report_service; + friend class e2sm_kpm_report_service_style1; + friend class e2sm_kpm_report_service_style2; + friend class e2sm_kpm_report_service_style3; + friend class e2sm_kpm_report_service_style4; + friend class e2sm_kpm_report_service_style5; private: bool _generate_indication_header(e2_sm_kpm_ind_hdr_s& hdr, srsran::unique_byte_buffer_t& buf); bool _generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::unique_byte_buffer_t& buf); + bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); + bool _extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); + bool _extract_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); + srslog::basic_logger& logger; std::vector supported_meas_types; std::map registered_actions_data; From c526870381f74ca242f6249dbfa843906cfc616d Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 31 Mar 2023 10:21:58 +0200 Subject: [PATCH 104/167] ric_subscription refactor func name --- srsgnb/hdr/stack/ric/ric_subscription.h | 4 ++-- srsgnb/src/stack/ric/ric_subscription.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index 48798e83c..24d45567a 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -42,7 +42,7 @@ public: private: void _send_subscription_response(); void _send_subscription_failure(); - void send_ric_indication(); + void _send_ric_indication(); uint32_t _generate_ric_indication_sn(); ric_client* parent = nullptr; @@ -57,7 +57,7 @@ private: srsran::unique_timer reporting_timer; // for RIC indication reporting std::vector admitted_actions; - std::vector not_admitted_actions; + std::vector not_admitted_actions; uint32_t _ric_indication_sn_gen = 0; }; diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 0b4c3a5bd..2a30071cb 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -98,7 +98,7 @@ void ric_client::ric_subscription::start_subscription() if (reporting_period) { printf("Start sending RIC indication msgs every %i ms\n", reporting_period); parent->logger.debug("Start sending RIC indication msgs every %i ms", reporting_period); - reporting_timer.set(reporting_period, [this](uint32_t tid) { send_ric_indication(); }); + reporting_timer.set(reporting_period, [this](uint32_t tid) { _send_ric_indication(); }); reporting_timer.run(); } } @@ -195,7 +195,7 @@ uint32_t ric_client::ric_subscription::_generate_ric_indication_sn() return sn; }; -void ric_client::ric_subscription::send_ric_indication() +void ric_client::ric_subscription::_send_ric_indication() { if (sm_ptr == nullptr) { parent->logger.error("SM pointer not set in subscription: %i\n", ric_requestor_id); From 7560948a7d456f19166dd6a252ac8a99a5a25eea Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 31 Mar 2023 10:30:52 +0200 Subject: [PATCH 105/167] ric_subscription: if indication data not ready, do not send --- .../hdr/stack/ric/e2sm_kpm_report_service.h | 6 ++++ srsgnb/src/stack/ric/e2sm_kpm.cc | 5 ++++ .../src/stack/ric/e2sm_kpm_report_service.cc | 30 +++++++++++++++++++ srsgnb/src/stack/ric/ric_subscription.cc | 8 ++--- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h index f449db264..6a68949a6 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h @@ -34,6 +34,7 @@ public: virtual bool _initialize_ric_ind_hdr(); virtual bool _initialize_ric_ind_msg() = 0; virtual bool collect_data(const enb_metrics_t& enb_metrics) = 0; + virtual bool is_ric_ind_ready() = 0; virtual bool clear_collected_data() = 0; std::vector _get_present_labels(const meas_info_item_s& action_meas_info_item); @@ -67,6 +68,7 @@ public: virtual bool _initialize_ric_ind_msg(); virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); private: @@ -89,6 +91,7 @@ public: virtual bool _initialize_ric_ind_msg(); virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); private: @@ -108,6 +111,7 @@ public: virtual bool _initialize_ric_ind_msg(); virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); private: @@ -127,6 +131,7 @@ public: virtual bool _initialize_ric_ind_msg(); virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); private: @@ -146,6 +151,7 @@ public: virtual bool _initialize_ric_ind_msg(); virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); private: diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index c67759022..b8be3f4de 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -233,6 +233,11 @@ bool e2sm_kpm::generate_ric_indication_content(E2AP_RIC_action_t& action_entry, return false; } e2sm_kpm_report_service* report_service = registered_actions_data.at(action_id); + + if (not report_service->is_ric_ind_ready()) { + return false; + } + ric_indication.indication_type = ri_cind_type_opts::report; // header is the same for all RIC service styles, i.e., type 1 diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index d31d35d52..d019b8d67 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -328,6 +328,12 @@ bool e2sm_kpm_report_service_style1::collect_data(const enb_metrics_t& enb_metri return true; } +bool e2sm_kpm_report_service_style1::is_ric_ind_ready() +{ + // TODO: check if only NO_VALUES, if so then skip + return true; +} + bool e2sm_kpm_report_service_style1::clear_collected_data() { ric_ind_header.collet_start_time.from_number(std::time(0)); @@ -368,6 +374,12 @@ bool e2sm_kpm_report_service_style2::collect_data(const enb_metrics_t& enb_metri return false; } +bool e2sm_kpm_report_service_style2::is_ric_ind_ready() +{ + // TODO: check if only NO_VALUES, if so then skip + return false; +} + bool e2sm_kpm_report_service_style2::clear_collected_data() { // TODO: implement @@ -405,6 +417,12 @@ bool e2sm_kpm_report_service_style3::collect_data(const enb_metrics_t& enb_metri return false; } +bool e2sm_kpm_report_service_style3::is_ric_ind_ready() +{ + // TODO: check if only NO_VALUES, if so then skip + return false; +} + bool e2sm_kpm_report_service_style3::clear_collected_data() { // TODO: implement @@ -442,6 +460,12 @@ bool e2sm_kpm_report_service_style4::collect_data(const enb_metrics_t& enb_metri return false; } +bool e2sm_kpm_report_service_style4::is_ric_ind_ready() +{ + // TODO: check if only NO_VALUES, if so then skip + return false; +} + bool e2sm_kpm_report_service_style4::clear_collected_data() { // TODO: implement @@ -479,6 +503,12 @@ bool e2sm_kpm_report_service_style5::collect_data(const enb_metrics_t& enb_metri return false; } +bool e2sm_kpm_report_service_style5::is_ric_ind_ready() +{ + // TODO: check if only NO_VALUES, if so then skip + return false; +} + bool e2sm_kpm_report_service_style5::clear_collected_data() { // TODO: implement diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 2a30071cb..5c8d5e430 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -211,10 +211,10 @@ void ric_client::ric_subscription::_send_ric_indication() ric_indication.ri_caction_id = action.ric_action_id; ric_indication.ri_indication_sn_present = true; ric_indication.ri_indication_sn = _generate_ric_indication_sn(); - sm_ptr->generate_ric_indication_content(action, ric_indication); - - e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(ric_indication); - parent->queue_send_e2ap_pdu(send_pdu); + if (sm_ptr->generate_ric_indication_content(action, ric_indication)) { + e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(ric_indication); + parent->queue_send_e2ap_pdu(send_pdu); + } } // reschedule sending RIC indication From ffe16f363f903bdcd22b6061cb2be3beb505e0de Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 31 Mar 2023 11:22:33 +0200 Subject: [PATCH 106/167] e2sm_kpm: do not admit action if at least one label not supported or if more than 1 label per metric requested --- srsgnb/hdr/stack/ric/e2sm_kpm_common.h | 2 + srsgnb/src/stack/ric/CMakeLists.txt | 2 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 2 +- srsgnb/src/stack/ric/e2sm_kpm_common.cc | 32 ++++++++++++++ .../src/stack/ric/e2sm_kpm_report_service.cc | 44 ++++++++++++++++--- 5 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 srsgnb/src/stack/ric/e2sm_kpm_common.cc diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h index 9a2a873f6..086a82ed1 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h @@ -49,6 +49,8 @@ enum e2sm_kpm_label_enum { UNKNOWN_LABEL = 0x8000 }; +std::string e2sm_kpm_label_2_str(e2sm_kpm_label_enum label); + /* Scopes supported for a metric */ enum e2sm_kpm_metric_scope_enum { ENB_LEVEL = 0x0001, diff --git a/srsgnb/src/stack/ric/CMakeLists.txt b/srsgnb/src/stack/ric/CMakeLists.txt index 0082f7333..86ba74dbd 100644 --- a/srsgnb/src/stack/ric/CMakeLists.txt +++ b/srsgnb/src/stack/ric/CMakeLists.txt @@ -1,4 +1,4 @@ -set(SOURCES ric_client.cc ric_subscription.cc e2ap.cc e2sm_kpm.cc e2sm_kpm_report_service.cc) +set(SOURCES ric_client.cc ric_subscription.cc e2ap.cc e2sm_kpm_common.cc e2sm_kpm.cc e2sm_kpm_report_service.cc) add_library(srsgnb_ric STATIC ${SOURCES}) target_link_libraries(srsgnb_ric srsran_asn1 ric_e2) diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index b8be3f4de..5696bcaa5 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -238,7 +238,7 @@ bool e2sm_kpm::generate_ric_indication_content(E2AP_RIC_action_t& action_entry, return false; } - ric_indication.indication_type = ri_cind_type_opts::report; + ric_indication.indication_type = ri_cind_type_opts::report; // header is the same for all RIC service styles, i.e., type 1 ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); diff --git a/srsgnb/src/stack/ric/e2sm_kpm_common.cc b/srsgnb/src/stack/ric/e2sm_kpm_common.cc new file mode 100644 index 000000000..49f808381 --- /dev/null +++ b/srsgnb/src/stack/ric/e2sm_kpm_common.cc @@ -0,0 +1,32 @@ +/** + * + * \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 "srsgnb/hdr/stack/ric/e2sm_kpm_common.h" + +std::string e2sm_kpm_label_2_str(e2sm_kpm_label_enum label) +{ + switch (label) { + case NO_LABEL: + return "NO_LABEL"; + case MIN_LABEL: + return "MIN_LABEL"; + case MAX_LABEL: + return "MAX_LABEL"; + case AVG_LABEL: + return "AVG_LABEL"; + case SUM_LABEL: + return "SUM_LABEL"; + default: + return "UNKNOWN_LABEL"; + } +} \ No newline at end of file diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index d019b8d67..8633c8f0a 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -192,6 +192,7 @@ bool e2sm_kpm_report_service_style1::process_ric_action_definition(e2sm_kpm* } } + std::map admitted_metrics; meas_info_list = action_definition.meas_info_list; for (uint32_t i = 0; i < meas_info_list.size(); i++) { std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); @@ -201,30 +202,61 @@ bool e2sm_kpm_report_service_style1::process_ric_action_definition(e2sm_kpm* return false; } - printf("Admitted action: measurement name: \"%s\" with the following labels: \n", meas_name.c_str()); - // TODO: add all labels defined in e2sm_kpm doc, if at least one label not supported do not admit action? + uint32_t nof_labels = 0; + // TODO: add all labels defined in e2sm_kpm doc, make this part generic and put to base class for (uint32_t l = 0; l < meas_info_list[i].label_info_list.size(); l++) { if (meas_info_list[i].label_info_list[l].meas_label.no_label_present) { if (metric_definition.supported_labels & NO_LABEL) { - printf("--- Label %i: NO LABEL\n", i); + nof_labels++; + admitted_metrics[meas_name] = NO_LABEL; + } else { + printf("Unsupported label: NO_LABEL for metric \"%s\" --> do not admit action\n", meas_name.c_str()); + return false; } } if (meas_info_list[i].label_info_list[l].meas_label.min_present) { if (metric_definition.supported_labels & MIN_LABEL) { - printf("--- Label %i: MIN\n", i); + nof_labels++; + admitted_metrics[meas_name] = MIN_LABEL; + } else { + printf("Unsupported label: MIN_LABEL for metric \"%s\" --> do not admit action\n", meas_name.c_str()); + return false; } } if (meas_info_list[i].label_info_list[l].meas_label.max_present) { if (metric_definition.supported_labels & MAX_LABEL) { - printf("--- Label %i: MAX\n", i); + nof_labels++; + admitted_metrics[meas_name] = MAX_LABEL; + } else { + printf("Unsupported label: MAX_LABEL for metric \"%s\" --> do not admit action\n", meas_name.c_str()); + return false; } } if (meas_info_list[i].label_info_list[l].meas_label.avg_present) { if (metric_definition.supported_labels & AVG_LABEL) { - printf("--- Label %i: AVG\n", i); + nof_labels++; + admitted_metrics[meas_name] = AVG_LABEL; + } else { + printf("Unsupported label: AVG_LABEL for metric \"%s\" --> do not admit action\n", meas_name.c_str()); + return false; } } } + + // Note: currently we use labels as choice (i.e., only one can be present) as documentation is not clear about it + if (nof_labels > 1) { + printf("Only one label per metric can be present, meas: \"%s\" has %i labels --> do not admit action\n", + meas_name.c_str(), + nof_labels); + return false; + } + } + + printf("Admitted action with the following metrics and labels: \n"); + for (const auto& it : admitted_metrics) { + std::string meas_name = it.first; + std::string label_str = e2sm_kpm_label_2_str(it.second); + printf("--- Metric: \"%s\" with label: %s\n", meas_name.c_str(), label_str.c_str()); } return true; From 01886a2d6d22deb65b7c707f0e378d600413e898 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 31 Mar 2023 11:45:40 +0200 Subject: [PATCH 107/167] e2sm_kpm: do not pass enb_metrics to e2sm_kpm_report_service --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 9 +++- .../hdr/stack/ric/e2sm_kpm_report_service.h | 18 +++---- srsgnb/src/stack/ric/e2sm_kpm.cc | 50 ++++++++++++++----- .../src/stack/ric/e2sm_kpm_report_service.cc | 14 +++--- 4 files changed, 60 insertions(+), 31 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 5ae9fb599..264533241 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -56,8 +56,13 @@ private: bool _generate_indication_header(e2_sm_kpm_ind_hdr_s& hdr, srsran::unique_byte_buffer_t& buf); bool _generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::unique_byte_buffer_t& buf); bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); - bool _extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); - bool _extract_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics); + + bool _collect_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value); + bool _collect_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value); + bool _extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, + const enb_metrics_t& enb_metrics, + uint32_t& value); + bool _extract_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics, float& value); srslog::basic_logger& logger; std::vector supported_meas_types; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h index 6a68949a6..11169e948 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h @@ -32,10 +32,10 @@ public: virtual ~e2sm_kpm_report_service() = default; virtual bool _initialize_ric_ind_hdr(); - virtual bool _initialize_ric_ind_msg() = 0; - virtual bool collect_data(const enb_metrics_t& enb_metrics) = 0; - virtual bool is_ric_ind_ready() = 0; - virtual bool clear_collected_data() = 0; + virtual bool _initialize_ric_ind_msg() = 0; + virtual bool collect_meas_data() = 0; + virtual bool is_ric_ind_ready() = 0; + virtual bool clear_collected_data() = 0; std::vector _get_present_labels(const meas_info_item_s& action_meas_info_item); meas_record_item_c::types @@ -67,7 +67,7 @@ public: static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); virtual bool _initialize_ric_ind_msg(); - virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool collect_meas_data(); virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); @@ -90,7 +90,7 @@ public: static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); virtual bool _initialize_ric_ind_msg(); - virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool collect_meas_data(); virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); @@ -110,7 +110,7 @@ public: static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); virtual bool _initialize_ric_ind_msg(); - virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool collect_meas_data(); virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); @@ -130,7 +130,7 @@ public: static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); virtual bool _initialize_ric_ind_msg(); - virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool collect_meas_data(); virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); @@ -150,7 +150,7 @@ public: static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); virtual bool _initialize_ric_ind_msg(); - virtual bool collect_data(const enb_metrics_t& enb_metrics); + virtual bool collect_meas_data(); virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 5696bcaa5..e9a6aecba 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -298,12 +298,35 @@ void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) for (auto& it : registered_actions_data) { e2sm_kpm_report_service* report_service = it.second; - report_service->collect_data(m); + report_service->collect_meas_data(); } } +bool e2sm_kpm::_collect_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value) +{ + // here we implement logic of measurement data collection, currently we only read from enb_metrics + uint32_t value; + if (_extract_integer_type_meas_value(meas_value, last_enb_metrics, value)) { + meas_value.integer_value = value; + return true; + } + return false; +} + +bool e2sm_kpm::_collect_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value) +{ + // here we implement logic of measurement data collection, currently we only read from enb_metrics + float value; + if (_extract_real_type_meas_value(meas_value, last_enb_metrics, value)) { + meas_value.real_value = value; + return true; + } + return false; +} + bool e2sm_kpm::_extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, - const enb_metrics_t& enb_metrics) + const enb_metrics_t& enb_metrics, + uint32_t& value) { // TODO: maybe add ID to metric types in e2sm_kpm_metrics definitions, so we do not have to compare strings? // TODO: make string comparison case insensitive @@ -312,8 +335,8 @@ bool e2sm_kpm::_extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_valu if (meas_value.name.c_str() == std::string("test")) { switch (meas_value.label) { case NO_LABEL: - meas_value.integer_value = (int32_t)enb_metrics.sys.cpu_load[0]; - printf("extract last \"test\" value as int, (filled with CPU0_load) value %i \n", meas_value.integer_value); + value = (int32_t)enb_metrics.sys.cpu_load[0]; + printf("extract last \"test\" value as int, (filled with CPU0_load) value %i \n", value); return true; default: return false; @@ -324,8 +347,8 @@ bool e2sm_kpm::_extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_valu if (meas_value.name.c_str() == std::string("random_int")) { switch (meas_value.label) { case NO_LABEL: - meas_value.integer_value = srsran_random_uniform_int_dist(random_gen, 0, 100); - printf("extract last \"random_int\" value as int, random value %i \n", meas_value.integer_value); + value = srsran_random_uniform_int_dist(random_gen, 0, 100); + printf("extract last \"random_int\" value as int, random value %i \n", value); return true; default: return false; @@ -335,14 +358,16 @@ bool e2sm_kpm::_extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_valu return false; } -bool e2sm_kpm::_extract_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics) +bool e2sm_kpm::_extract_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, + const enb_metrics_t& enb_metrics, + float& value) { // all real type measurements // cpu0_load: no_label if (meas_value.name.c_str() == std::string("cpu0_load")) { switch (meas_value.label) { case NO_LABEL: - meas_value.real_value = enb_metrics.sys.cpu_load[0]; + value = enb_metrics.sys.cpu_load[0]; return true; default: return false; @@ -354,15 +379,14 @@ bool e2sm_kpm::_extract_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, uint32_t size; switch (meas_value.label) { case MIN_LABEL: - meas_value.real_value = *std::min_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); + value = *std::min_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); return true; case MAX_LABEL: - meas_value.real_value = *std::max_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); + value = *std::max_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); return true; case AVG_LABEL: - size = enb_metrics.sys.cpu_load.size(); - meas_value.real_value = - std::accumulate(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end(), 0.0 / size); + size = enb_metrics.sys.cpu_load.size(); + value = std::accumulate(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end(), 0.0 / size); return true; default: return false; diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index 8633c8f0a..139b7b4c7 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -310,7 +310,7 @@ meas_data_item_s& e2sm_kpm_report_service_style1::_get_meas_data_item(std::strin return ric_ind_message.meas_data[0]; } -bool e2sm_kpm_report_service_style1::collect_data(const enb_metrics_t& enb_metrics) +bool e2sm_kpm_report_service_style1::collect_meas_data() { meas_info_list_l& meas_info_list = ric_ind_message.meas_info_list; for (uint32_t i = 0; i < meas_info_list.size(); i++) { @@ -342,13 +342,13 @@ bool e2sm_kpm_report_service_style1::collect_data(const enb_metrics_t& enb_metri meas_value.data_type = data_type; if (meas_value.data_type == meas_record_item_c::types::options::integer) { - if (not parent->_extract_integer_type_meas_value(meas_value, enb_metrics)) { + if (not parent->_collect_integer_type_meas_value(meas_value)) { parent->logger.info("Cannot extract value \"%s\" label: %i", meas_name.c_str(), label); return false; } } else { // data_type == meas_record_item_c::types::options::real; - if (not parent->_extract_real_type_meas_value(meas_value, enb_metrics)) { + if (not parent->_collect_real_type_meas_value(meas_value)) { parent->logger.info("Cannot extract value \"%s\" label %i", meas_name.c_str(), label); return false; } @@ -400,7 +400,7 @@ bool e2sm_kpm_report_service_style2::process_ric_action_definition(e2sm_kpm* return false; } -bool e2sm_kpm_report_service_style2::collect_data(const enb_metrics_t& enb_metrics) +bool e2sm_kpm_report_service_style2::collect_meas_data() { // TODO: implement return false; @@ -443,7 +443,7 @@ bool e2sm_kpm_report_service_style3::process_ric_action_definition(e2sm_kpm* return false; } -bool e2sm_kpm_report_service_style3::collect_data(const enb_metrics_t& enb_metrics) +bool e2sm_kpm_report_service_style3::collect_meas_data() { // TODO: implement return false; @@ -486,7 +486,7 @@ bool e2sm_kpm_report_service_style4::process_ric_action_definition(e2sm_kpm* return false; } -bool e2sm_kpm_report_service_style4::collect_data(const enb_metrics_t& enb_metrics) +bool e2sm_kpm_report_service_style4::collect_meas_data() { // TODO: implement return false; @@ -529,7 +529,7 @@ bool e2sm_kpm_report_service_style5::process_ric_action_definition(e2sm_kpm* return false; } -bool e2sm_kpm_report_service_style5::collect_data(const enb_metrics_t& enb_metrics) +bool e2sm_kpm_report_service_style5::collect_meas_data() { // TODO: implement return false; From 0c8b5430dc9f6e2fa0f555dbcc5afed1ea17903d Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 31 Mar 2023 11:58:49 +0200 Subject: [PATCH 108/167] e2sm_kpm: simplify collection of meas data --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 11 ++++---- srsgnb/hdr/stack/ric/e2sm_kpm_common.h | 4 +-- .../hdr/stack/ric/e2sm_kpm_report_service.h | 3 +-- srsgnb/src/stack/ric/e2sm_kpm.cc | 23 +++++++++------- .../src/stack/ric/e2sm_kpm_report_service.cc | 27 ++++--------------- 5 files changed, 25 insertions(+), 43 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 264533241..cc087e3f0 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -57,12 +57,11 @@ private: bool _generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::unique_byte_buffer_t& buf); bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); - bool _collect_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value); - bool _collect_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value); - bool _extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, - const enb_metrics_t& enb_metrics, - uint32_t& value); - bool _extract_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, const enb_metrics_t& enb_metrics, float& value); + bool _collect_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item); + bool _collect_real_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item); + bool + _extract_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, uint32_t& value); + bool _extract_real_type_meas_value(E2SM_KPM_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, float& value); srslog::basic_logger& logger; std::vector supported_meas_types; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h index 086a82ed1..5968c9459 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h @@ -65,8 +65,6 @@ typedef struct { e2sm_kpm_label_enum label; e2sm_kpm_metric_scope_enum scope; meas_record_item_c::types data_type; - int32_t integer_value; - float real_value; -} E2SM_KPM_meas_value_t; +} E2SM_KPM_meas_def_t; #endif // SRSRAN_E2SM_KPM_COMMON_H diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h index 11169e948..20735202d 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h @@ -39,8 +39,7 @@ public: std::vector _get_present_labels(const meas_info_item_s& action_meas_info_item); meas_record_item_c::types - _get_meas_data_type(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list); - void _add_measurement_record(E2SM_KPM_meas_value_t& meas_value, meas_record_l& meas_record_list); + _get_meas_data_type(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list); e2_sm_kpm_ind_hdr_s& get_ind_hdr() { return ric_ind_header_generic; }; e2_sm_kpm_ind_msg_s& get_ind_msg() { return ric_ind_message_generic; }; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index e9a6aecba..7fd53a621 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -302,31 +302,34 @@ void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) } } -bool e2sm_kpm::_collect_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value) +bool e2sm_kpm::_collect_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item) { // here we implement logic of measurement data collection, currently we only read from enb_metrics uint32_t value; if (_extract_integer_type_meas_value(meas_value, last_enb_metrics, value)) { - meas_value.integer_value = value; + item.set_integer() = value; return true; } return false; } -bool e2sm_kpm::_collect_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value) +bool e2sm_kpm::_collect_real_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item) { // here we implement logic of measurement data collection, currently we only read from enb_metrics float value; if (_extract_real_type_meas_value(meas_value, last_enb_metrics, value)) { - meas_value.real_value = value; + real_s real_value; + // TODO: real value seems to be not supported in asn1??? + // real_value.value = value; + item.set_real() = real_value; return true; } return false; } -bool e2sm_kpm::_extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_value, - const enb_metrics_t& enb_metrics, - uint32_t& value) +bool e2sm_kpm::_extract_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, + const enb_metrics_t& enb_metrics, + uint32_t& value) { // TODO: maybe add ID to metric types in e2sm_kpm_metrics definitions, so we do not have to compare strings? // TODO: make string comparison case insensitive @@ -358,9 +361,9 @@ bool e2sm_kpm::_extract_integer_type_meas_value(E2SM_KPM_meas_value_t& meas_valu return false; } -bool e2sm_kpm::_extract_real_type_meas_value(E2SM_KPM_meas_value_t& meas_value, - const enb_metrics_t& enb_metrics, - float& value) +bool e2sm_kpm::_extract_real_type_meas_value(E2SM_KPM_meas_def_t& meas_value, + const enb_metrics_t& enb_metrics, + float& value) { // all real type measurements // cpu0_load: no_label diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index 139b7b4c7..86f99569a 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -84,24 +84,6 @@ meas_record_item_c::types e2sm_kpm_report_service::_get_meas_data_type(std::stri return data_type; } -void e2sm_kpm_report_service::_add_measurement_record(E2SM_KPM_meas_value_t& meas_value, - meas_record_l& meas_record_list) -{ - if (meas_value.data_type == meas_record_item_c::types::options::integer) { - meas_record_item_c item; - item.set_integer() = meas_value.integer_value; - meas_record_list.push_back(item); - } else { - // data_type == meas_record_item_c::types::options::real; - meas_record_item_c item; - real_s real_value; - // TODO: real value seems to be not supported in asn1??? - // real_value.value = meas_value.real_value; - item.set_real() = real_value; - meas_record_list.push_back(item); - } -} - e2sm_kpm_report_service_style1::e2sm_kpm_report_service_style1(e2sm_kpm* e2sm_kpm, uint16_t action_id, e2_sm_kpm_action_definition_s action_definition) : @@ -335,26 +317,27 @@ bool e2sm_kpm_report_service_style1::collect_meas_data() meas_record_item_c::types data_type = _get_meas_data_type(meas_name, label, meas_data_item.meas_record); // extract a needed value from enb metrics and add to the proper meas record list - E2SM_KPM_meas_value_t meas_value; + E2SM_KPM_meas_def_t meas_value; meas_value.name = meas_name; meas_value.label = label; // meas_values.scope = ...; meas_value.data_type = data_type; + meas_record_item_c item; if (meas_value.data_type == meas_record_item_c::types::options::integer) { - if (not parent->_collect_integer_type_meas_value(meas_value)) { + if (not parent->_collect_integer_type_meas_value(meas_value, item)) { parent->logger.info("Cannot extract value \"%s\" label: %i", meas_name.c_str(), label); return false; } } else { // data_type == meas_record_item_c::types::options::real; - if (not parent->_collect_real_type_meas_value(meas_value)) { + if (not parent->_collect_real_type_meas_value(meas_value, item)) { parent->logger.info("Cannot extract value \"%s\" label %i", meas_name.c_str(), label); return false; } } // save meas value in the proper record list - _add_measurement_record(meas_value, meas_data_item.meas_record); + meas_data_item.meas_record.push_back(item); } } return true; From cf3d88b0151eed85454a6a5c601d1bc84399a030 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 31 Mar 2023 12:25:08 +0200 Subject: [PATCH 109/167] e2sm_kpm: add examples of CELL and UE level measurements --- srsgnb/hdr/stack/ric/e2sm_kpm_common.h | 2 ++ srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h | 6 +++--- .../hdr/stack/ric/e2sm_kpm_report_service.h | 4 ++++ srsgnb/src/stack/ric/e2sm_kpm.cc | 21 ++++++++++++++++--- .../src/stack/ric/e2sm_kpm_report_service.cc | 14 ++++++++++++- 5 files changed, 40 insertions(+), 7 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h index 5968c9459..78e36bee8 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h @@ -65,6 +65,8 @@ typedef struct { e2sm_kpm_label_enum label; e2sm_kpm_metric_scope_enum scope; meas_record_item_c::types data_type; + uint32_t ue_id; // TODO: do we need to use type ueid_c? or we translate to local RNTI? + uint32_t cell_id; // TODO: do we need to use type cgi_c? or we translate to local cell_id? } E2SM_KPM_meas_def_t; #endif // SRSRAN_E2SM_KPM_COMMON_H diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h index 160dfc84e..50dcdba5e 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h @@ -52,10 +52,10 @@ std::vector e2sm_kpm_custom_metrics() { std::vector metrics; // supported metrics - metrics.push_back({"test", true, INTEGER, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL | UE_LEVEL }); + metrics.push_back({"test", true, INTEGER, "", true, 0, true, 100, NO_LABEL, ENB_LEVEL | CELL_LEVEL | UE_LEVEL }); metrics.push_back({"random_int", true, INTEGER, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL }); - metrics.push_back({"cpu0_load", true, REAL, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL }); - metrics.push_back({"cpu_load", true, REAL, "", true, 0, true, 100, MIN_LABEL|MAX_LABEL|AVG_LABEL, CELL_LEVEL }); + metrics.push_back({"cpu0_load", true, REAL, "", true, 0, true, 100, NO_LABEL, ENB_LEVEL }); + metrics.push_back({"cpu_load", true, REAL, "", true, 0, true, 100, MIN_LABEL|MAX_LABEL|AVG_LABEL, ENB_LEVEL }); // not supported metrics metrics.push_back({"test123", false, REAL, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL | UE_LEVEL }); return metrics; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h index 20735202d..6463b77bd 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h @@ -51,6 +51,10 @@ public: e2_sm_kpm_ind_hdr_s ric_ind_header_generic; e2_sm_kpm_ind_msg_s ric_ind_message_generic; + uint64_t granul_period = 0; + bool cell_global_id_present = false; + cgi_c cell_global_id; + // hdr format 1 in base class, as all types use it e2_sm_kpm_ind_hdr_format1_s& ric_ind_header; }; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 7fd53a621..da5873feb 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -338,9 +338,24 @@ bool e2sm_kpm::_extract_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, if (meas_value.name.c_str() == std::string("test")) { switch (meas_value.label) { case NO_LABEL: - value = (int32_t)enb_metrics.sys.cpu_load[0]; - printf("extract last \"test\" value as int, (filled with CPU0_load) value %i \n", value); - return true; + if (meas_value.scope & ENB_LEVEL) { + value = (int32_t)enb_metrics.sys.cpu_load[0]; + printf("extract last \"test\" value as int, (filled with ENB_LEVEL metric: CPU0_load) value %i \n", value); + return true; + } + if (meas_value.scope & CELL_LEVEL) { + uint32_t cell_id = meas_value.cell_id; + value = (int32_t)enb_metrics.stack.mac.cc_info[cell_id].cc_rach_counter; + printf("extract last \"test\" value as int, (filled with CELL_LEVEL metric: cc_rach_counter) value %i \n", + value); + return true; + } + if (meas_value.scope & UE_LEVEL) { + uint32_t ue_id = meas_value.ue_id; + value = (int32_t)enb_metrics.stack.mac.ues[ue_id].ul_rssi; + printf("extract last \"test\" value as int, (filled with UE_LEVEL metric: ul_rssi) value %i \n", value); + return true; + } default: return false; } diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index 86f99569a..89ed9dfcc 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -92,6 +92,12 @@ e2sm_kpm_report_service_style1::e2sm_kpm_report_service_style1(e2sm_kpm* ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format1()) { ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + granul_period = action_def.granul_period; + cell_global_id_present = action_def.cell_global_id_present; + if (cell_global_id_present) { + cell_global_id = action_def.cell_global_id; + } + this->_initialize_ric_ind_hdr(); this->_initialize_ric_ind_msg(); } @@ -320,7 +326,11 @@ bool e2sm_kpm_report_service_style1::collect_meas_data() E2SM_KPM_meas_def_t meas_value; meas_value.name = meas_name; meas_value.label = label; - // meas_values.scope = ...; + meas_value.scope = ENB_LEVEL; + if (cell_global_id_present) { + meas_value.scope = CELL_LEVEL; + meas_value.cell_id = 0; + } meas_value.data_type = data_type; meas_record_item_c item; @@ -380,6 +390,8 @@ bool e2sm_kpm_report_service_style2::process_ric_action_definition(e2sm_kpm* e2_sm_kpm_action_definition_s& action_def_generic) { // TODO: implement + // note: similar to e2sm_kpm_report_service_style1::process_ric_action_definition but in addition + // we need to check whether measurement is supported at UE_LEVEL return false; } From d976a0dff8112f8f190dd4f115ba73289019b2db Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 31 Mar 2023 12:31:37 +0200 Subject: [PATCH 110/167] e2sm_kpm: add TODO to check if metric is supported at the requested level --- srsgnb/src/stack/ric/e2sm_kpm_report_service.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index 89ed9dfcc..c55a6bea3 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -91,7 +91,7 @@ e2sm_kpm_report_service_style1::e2sm_kpm_report_service_style1(e2sm_kpm* action_def(action_def_generic.action_definition_formats.action_definition_format1()), ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format1()) { - ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; granul_period = action_def.granul_period; cell_global_id_present = action_def.cell_global_id_present; if (cell_global_id_present) { @@ -157,6 +157,7 @@ bool e2sm_kpm_report_service_style1::process_ric_action_definition(e2sm_kpm* e2_sm_kpm_action_definition_format1_s& action_definition = action_def_generic.action_definition_formats.action_definition_format1(); + bool cell_global_id_present = false; uint64_t granul_period; uint64_t eutra_cell_id; uint64_t plmn_id; @@ -172,6 +173,7 @@ bool e2sm_kpm_report_service_style1::process_ric_action_definition(e2sm_kpm* } if (action_definition.cell_global_id_present) { + cell_global_id_present = true; if (action_definition.cell_global_id.type() == cgi_c::types_opts::eutra_cgi) { eutra_cell_id = action_definition.cell_global_id.eutra_cgi().eutra_cell_id.to_number(); plmn_id = action_definition.cell_global_id.eutra_cgi().plmn_id.to_number(); @@ -192,6 +194,8 @@ bool e2sm_kpm_report_service_style1::process_ric_action_definition(e2sm_kpm* uint32_t nof_labels = 0; // TODO: add all labels defined in e2sm_kpm doc, make this part generic and put to base class + // TODO: check if metric is supported at the requested level, i.e., CELL_LEVEL if cell_global_id_present == true, + // and ENB_LEVEL otherwise for (uint32_t l = 0; l < meas_info_list[i].label_info_list.size(); l++) { if (meas_info_list[i].label_info_list[l].meas_label.no_label_present) { if (metric_definition.supported_labels & NO_LABEL) { From ad63115f310477038dd5b3198ef6b68940446ba8 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 31 Mar 2023 13:15:36 +0200 Subject: [PATCH 111/167] e2sm_kpm: measurement collection triggered by timer every granul_period from action def --- srsgnb/hdr/stack/ric/e2sm.h | 15 +++++- srsgnb/hdr/stack/ric/e2sm_kpm.h | 2 +- .../hdr/stack/ric/e2sm_kpm_report_service.h | 14 ++++-- srsgnb/src/stack/ric/e2ap.cc | 2 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 9 ++-- .../src/stack/ric/e2sm_kpm_report_service.cc | 49 ++++++++++++++++++- 6 files changed, 76 insertions(+), 15 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index c3e975ed6..5fcb50e10 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -13,6 +13,7 @@ #include "srsran/asn1/e2ap.h" #include "srsran/common/byte_buffer.h" +#include "srsran/common/task_scheduler.h" #include "srsran/interfaces/enb_metrics_interface.h" #include "srsran/srsran.h" @@ -52,8 +53,16 @@ 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){}; + e2sm(std::string short_name, + std::string oid, + std::string func_description, + uint32_t revision, + srsran::task_scheduler* _task_sched_ptr) : + _short_name(short_name), + _oid(oid), + _func_description(func_description), + _revision(revision), + task_sched_ptr(_task_sched_ptr){}; virtual ~e2sm() = default; std::string get_short_name() { return _short_name; }; @@ -75,6 +84,8 @@ protected: uint32_t _get_local_action_id() { return _registered_action_id_gen; }; uint32_t _generate_new_local_action_id() { return _registered_action_id_gen++; }; + srsran::task_scheduler* task_sched_ptr = nullptr; + private: const std::string _short_name; const std::string _oid; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index cc087e3f0..f36ceba83 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -33,7 +33,7 @@ public: static const std::string func_description; static const uint32_t revision; - e2sm_kpm(srslog::basic_logger& logger_); + e2sm_kpm(srslog::basic_logger& logger_, srsran::task_scheduler* _task_sched_ptr); ~e2sm_kpm() = default; virtual bool generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func); diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h index 6463b77bd..65b4d66cd 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h @@ -16,6 +16,7 @@ #include "srsran/asn1/e2ap.h" #include "srsran/asn1/e2sm.h" #include "srsran/asn1/e2sm_kpm_v2.h" +#include "srsran/common/timers.h" #include "srsran/srsran.h" #ifndef SRSRAN_E2SM_KPM_ACTION_DATA_H @@ -37,6 +38,11 @@ public: virtual bool is_ric_ind_ready() = 0; virtual bool clear_collected_data() = 0; + virtual bool _start_meas_collection(); + bool stop(); + virtual bool _stop_meas_collection(); + virtual bool _reschedule_meas_collection(); + std::vector _get_present_labels(const meas_info_item_s& action_meas_info_item); meas_record_item_c::types _get_meas_data_type(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list); @@ -51,12 +57,14 @@ public: e2_sm_kpm_ind_hdr_s ric_ind_header_generic; e2_sm_kpm_ind_msg_s ric_ind_message_generic; - uint64_t granul_period = 0; - bool cell_global_id_present = false; - cgi_c cell_global_id; + bool cell_global_id_present = false; + cgi_c cell_global_id; // hdr format 1 in base class, as all types use it e2_sm_kpm_ind_hdr_format1_s& ric_ind_header; + + uint32_t granul_period = 0; + srsran::unique_timer meas_collection_timer; // for measurements collection }; class e2sm_kpm_report_service_style1 : public e2sm_kpm_report_service diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 6b8b40dbc..5e20e795a 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -5,7 +5,7 @@ e2ap::e2ap(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics, srsran::task_scheduler* _task_sched_ptr) : - logger(logger), e2sm_(logger), task_sched_ptr(_task_sched_ptr) + logger(logger), e2sm_(logger, _task_sched_ptr), task_sched_ptr(_task_sched_ptr) { gnb_metrics = _gnb_metrics; e2_procedure_timeout = task_sched_ptr->get_unique_timer(); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index da5873feb..2ae84f57d 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -21,7 +21,8 @@ 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; -e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_) : e2sm(short_name, oid, func_description, revision), logger(logger_) +e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_, srsran::task_scheduler* _task_sched_ptr) : + e2sm(short_name, oid, func_description, revision, _task_sched_ptr), logger(logger_) { random_gen = srsran_random_init(1234); @@ -215,6 +216,7 @@ bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_a bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action_t& action_entry) { if (registered_actions_data.count(action_entry.sm_local_ric_action_id)) { + registered_actions_data.at(action_entry.sm_local_ric_action_id)->stop(); delete registered_actions_data.at(action_entry.sm_local_ric_action_id); registered_actions_data.erase(action_entry.sm_local_ric_action_id); return true; @@ -295,11 +297,6 @@ void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) { last_enb_metrics = m; logger.debug("e2sm_kpm received new enb metrics, CPU0 Load: %.1f", last_enb_metrics.sys.cpu_load[0]); - - for (auto& it : registered_actions_data) { - e2sm_kpm_report_service* report_service = it.second; - report_service->collect_meas_data(); - } } bool e2sm_kpm::_collect_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item) diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index c55a6bea3..d342bcaae 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -20,7 +20,8 @@ e2sm_kpm_report_service::e2sm_kpm_report_service(e2sm_kpm* e action_id(action_id), action_def_generic(action_definition), ric_ind_header_generic(), - ric_ind_header(ric_ind_header_generic.ind_hdr_formats.ind_hdr_format1()) + ric_ind_header(ric_ind_header_generic.ind_hdr_formats.ind_hdr_format1()), + meas_collection_timer(parent->task_sched_ptr->get_unique_timer()) { } @@ -84,6 +85,43 @@ meas_record_item_c::types e2sm_kpm_report_service::_get_meas_data_type(std::stri return data_type; } +bool e2sm_kpm_report_service::_start_meas_collection() +{ + if (granul_period) { + printf("Start collecting measurements every %i ms\n", granul_period); + parent->logger.debug("Start collecting measurements every every %i ms", granul_period); + meas_collection_timer.set(granul_period, [this](uint32_t tid) { this->collect_meas_data(); }); + meas_collection_timer.run(); + return true; + } + return false; +} + +bool e2sm_kpm_report_service::stop() +{ + return _stop_meas_collection(); +} + +bool e2sm_kpm_report_service::_stop_meas_collection() +{ + if (meas_collection_timer.is_running()) { + printf("Stop collecting measurements every %i ms\n", granul_period); + parent->logger.debug("Stop collecting measurements every %i ms\n", granul_period); + meas_collection_timer.stop(); + return true; + } + return false; +} + +bool e2sm_kpm_report_service::_reschedule_meas_collection() +{ + if (granul_period) { + meas_collection_timer.run(); + return true; + } + return false; +} + e2sm_kpm_report_service_style1::e2sm_kpm_report_service_style1(e2sm_kpm* e2sm_kpm, uint16_t action_id, e2_sm_kpm_action_definition_s action_definition) : @@ -100,13 +138,17 @@ e2sm_kpm_report_service_style1::e2sm_kpm_report_service_style1(e2sm_kpm* this->_initialize_ric_ind_hdr(); this->_initialize_ric_ind_msg(); + + granul_period = 1000; // TODO: overwrite for testing + _start_meas_collection(); } bool e2sm_kpm_report_service_style1::_initialize_ric_ind_msg() { meas_info_list_l action_meas_info_list = action_def.meas_info_list; - // ric_ind_message.granul_period = action.granul_period; // not implemented by flexric and crashes it + // ric_ind_message.granul_period_present = true; + // ric_ind_message.granul_period = granul_period; // TODO: our asn1 has some issues with this field ric_ind_message.granul_period = 0; ric_ind_message.meas_info_list.resize(action_meas_info_list.size()); ric_ind_message.meas_data.resize(action_meas_info_list.size()); @@ -354,6 +396,9 @@ bool e2sm_kpm_report_service_style1::collect_meas_data() meas_data_item.meas_record.push_back(item); } } + + // reschedule measurement collection + _reschedule_meas_collection(); return true; } From 68bfba527307a8f6f284a40234d0e62647ffb1a7 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 31 Mar 2023 13:25:49 +0200 Subject: [PATCH 112/167] e2sm_kpm: refactor function name --- srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h | 12 ++++++------ srsgnb/src/stack/ric/e2sm_kpm_report_service.cc | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h index 65b4d66cd..cd3af4e4a 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h @@ -34,7 +34,7 @@ public: virtual bool _initialize_ric_ind_hdr(); virtual bool _initialize_ric_ind_msg() = 0; - virtual bool collect_meas_data() = 0; + virtual bool _collect_meas_data() = 0; virtual bool is_ric_ind_ready() = 0; virtual bool clear_collected_data() = 0; @@ -78,7 +78,7 @@ public: static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); virtual bool _initialize_ric_ind_msg(); - virtual bool collect_meas_data(); + virtual bool _collect_meas_data(); virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); @@ -101,7 +101,7 @@ public: static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); virtual bool _initialize_ric_ind_msg(); - virtual bool collect_meas_data(); + virtual bool _collect_meas_data(); virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); @@ -121,7 +121,7 @@ public: static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); virtual bool _initialize_ric_ind_msg(); - virtual bool collect_meas_data(); + virtual bool _collect_meas_data(); virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); @@ -141,7 +141,7 @@ public: static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); virtual bool _initialize_ric_ind_msg(); - virtual bool collect_meas_data(); + virtual bool _collect_meas_data(); virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); @@ -161,7 +161,7 @@ public: static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); virtual bool _initialize_ric_ind_msg(); - virtual bool collect_meas_data(); + virtual bool _collect_meas_data(); virtual bool is_ric_ind_ready(); virtual bool clear_collected_data(); diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index d342bcaae..554893ed4 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -90,7 +90,7 @@ bool e2sm_kpm_report_service::_start_meas_collection() if (granul_period) { printf("Start collecting measurements every %i ms\n", granul_period); parent->logger.debug("Start collecting measurements every every %i ms", granul_period); - meas_collection_timer.set(granul_period, [this](uint32_t tid) { this->collect_meas_data(); }); + meas_collection_timer.set(granul_period, [this](uint32_t tid) { this->_collect_meas_data(); }); meas_collection_timer.run(); return true; } @@ -344,7 +344,7 @@ meas_data_item_s& e2sm_kpm_report_service_style1::_get_meas_data_item(std::strin return ric_ind_message.meas_data[0]; } -bool e2sm_kpm_report_service_style1::collect_meas_data() +bool e2sm_kpm_report_service_style1::_collect_meas_data() { meas_info_list_l& meas_info_list = ric_ind_message.meas_info_list; for (uint32_t i = 0; i < meas_info_list.size(); i++) { @@ -444,7 +444,7 @@ bool e2sm_kpm_report_service_style2::process_ric_action_definition(e2sm_kpm* return false; } -bool e2sm_kpm_report_service_style2::collect_meas_data() +bool e2sm_kpm_report_service_style2::_collect_meas_data() { // TODO: implement return false; @@ -487,7 +487,7 @@ bool e2sm_kpm_report_service_style3::process_ric_action_definition(e2sm_kpm* return false; } -bool e2sm_kpm_report_service_style3::collect_meas_data() +bool e2sm_kpm_report_service_style3::_collect_meas_data() { // TODO: implement return false; @@ -530,7 +530,7 @@ bool e2sm_kpm_report_service_style4::process_ric_action_definition(e2sm_kpm* return false; } -bool e2sm_kpm_report_service_style4::collect_meas_data() +bool e2sm_kpm_report_service_style4::_collect_meas_data() { // TODO: implement return false; @@ -573,7 +573,7 @@ bool e2sm_kpm_report_service_style5::process_ric_action_definition(e2sm_kpm* return false; } -bool e2sm_kpm_report_service_style5::collect_meas_data() +bool e2sm_kpm_report_service_style5::_collect_meas_data() { // TODO: implement return false; From 6090033a3838dd2ce0774a1fba26da30eafdcf5f Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 31 Mar 2023 17:36:34 +0200 Subject: [PATCH 113/167] e2sm_kpm: report supported metrics in setup_request msg --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 1 + srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h | 6 +-- srsgnb/src/stack/ric/e2sm_kpm.cc | 57 ++++++++++++++++++++----- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index f36ceba83..0a535fa1d 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -56,6 +56,7 @@ private: bool _generate_indication_header(e2_sm_kpm_ind_hdr_s& hdr, srsran::unique_byte_buffer_t& buf); bool _generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::unique_byte_buffer_t& buf); bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); + std::vector _get_supported_meas(uint32_t level_mask); bool _collect_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item); bool _collect_real_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item); diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h index 50dcdba5e..9bf016b21 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h @@ -23,9 +23,9 @@ std::vector get_e2sm_kpm_28_552_metrics() { // TODO: add all metrics from 3GPP TS 28.552 std::vector metrics; - // supported metrics - metrics.push_back({"RRU.PrbTotDl", true, REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, CELL_LEVEL | UE_LEVEL }); - metrics.push_back({"RRU.PrbTotUl", true, REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, CELL_LEVEL | UE_LEVEL }); + // not supported metrics + metrics.push_back({"RRU.PrbTotDl", false, REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, CELL_LEVEL | UE_LEVEL }); + metrics.push_back({"RRU.PrbTotUl", false, REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, CELL_LEVEL | UE_LEVEL }); // not supported metrics metrics.push_back({"RRU.RachPreambleDedMean", false, REAL, "-", false, 0, false, 100, NO_LABEL, CELL_LEVEL | UE_LEVEL }); return metrics; diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 2ae84f57d..adfd19860 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -72,45 +72,65 @@ bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, 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 - /* TODO: seems that flexric does not like this part and crashes auto& report_style_list = e2sm_kpm_ra_nfunction_description.ric_report_style_list; - report_style_list.resize(5); + report_style_list.resize(1); 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; + std::vector supported_enb_meas = _get_supported_meas(ENB_LEVEL | CELL_LEVEL); + for (const auto& metric : supported_enb_meas) { + meas_info_action_item_s meas_info_item; + meas_info_item.meas_name.from_string(metric.c_str()); + report_style_list[0].meas_info_action_list.push_back(meas_info_item); + break; // TODO: add only one as flexric does not like long setup_request msg and crashes + } + + /* TODO: seems that flexric does not like long setup_request msg and crashes, note: wireshark decodes it correctly + // see: nearRT-RIC: flexric/src/ric/msg_handler_ric.c:88: + // generate_setup_response: Assertion `req->ran_func_item[i].def.len < 127' failed 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_action_format_type = 2; report_style_list[1].ric_ind_hdr_format_type = 1; report_style_list[1].ric_ind_msg_format_type = 1; + // TODO: add all supported UE LEVEL metrics + report_style_list[1].meas_info_action_list.resize(1); + report_style_list[1].meas_info_action_list[0].meas_name.from_string("RRU.PrbTotDl"); + // 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[1].meas_info_action_list[0].meas_id = 123; 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; + // TODO: add all supported UE LEVEL metrics + report_style_list[2].meas_info_action_list.resize(1); + report_style_list[2].meas_info_action_list[0].meas_name.from_string("RRU.PrbTotDl"); 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; + // TODO: add all supported UE LEVEL metrics + report_style_list[3].meas_info_action_list.resize(1); + report_style_list[3].meas_info_action_list[0].meas_name.from_string("RRU.PrbTotDl"); 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; + // TODO: add all supported UE LEVEL metrics + report_style_list[4].meas_info_action_list.resize(1); + report_style_list[4].meas_info_action_list[0].meas_name.from_string("RRU.PrbTotDl"); */ logger.info("Generating RAN function description"); srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); @@ -122,7 +142,6 @@ bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, buf->N_bytes = bref.distance_bytes(); ran_func.ran_function_definition.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.ran_function_definition.data()); return true; @@ -293,6 +312,24 @@ bool e2sm_kpm::_get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& de return true; } +std::vector e2sm_kpm::_get_supported_meas(uint32_t level_mask) +{ + std::vector supported_meas; + for (auto& metric : supported_meas_types) { + if ((level_mask & ENB_LEVEL) and (metric.supported_scopes & ENB_LEVEL)) { + supported_meas.push_back(metric.name); + } else if ((level_mask & CELL_LEVEL) and (metric.supported_scopes & CELL_LEVEL)) { + supported_meas.push_back(metric.name); + } else if ((level_mask & UE_LEVEL) and (metric.supported_scopes & UE_LEVEL)) { + supported_meas.push_back(metric.name); + } else if ((level_mask & BEARER_LEVEL) and (metric.supported_scopes & BEARER_LEVEL)) { + supported_meas.push_back(metric.name); + } + } + + return supported_meas; +} + void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) { last_enb_metrics = m; From 11532aa66cc3778d7f644b521f7c1c2b6a9db3ee Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 4 Apr 2023 10:26:17 +0200 Subject: [PATCH 114/167] e2ap: move ric_subscription from ric_client to e2ap --- srsgnb/hdr/stack/ric/e2ap.h | 38 ++++++++++++------ srsgnb/hdr/stack/ric/ric_client.h | 7 +--- srsgnb/hdr/stack/ric/ric_subscription.h | 13 +++--- srsgnb/src/stack/ric/e2ap.cc | 51 +++++++++++++++++++++--- srsgnb/src/stack/ric/ric_client.cc | 33 +++++---------- srsgnb/src/stack/ric/ric_subscription.cc | 46 +++++++++------------ srsgnb/src/stack/ric/test/e2ap_test.cc | 8 ++-- 7 files changed, 113 insertions(+), 83 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 0ff57e664..6c7e707ef 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -22,6 +22,7 @@ #ifndef RIC_E2AP_H #define RIC_E2AP_H +namespace srsenb { using namespace asn1::e2ap; using namespace asn1::e2sm_kpm; @@ -45,16 +46,22 @@ typedef struct { std::vector not_admitted_actions; } ric_subscription_reponse_t; +class ric_client; + class e2ap { public: e2ap(srslog::basic_logger& logger, + ric_client* _ric_client, srsenb::e2_interface_metrics* _gnb_metrics, srsran::task_scheduler* _task_sched_ptr); + ~e2ap(); + e2_ap_pdu_c generate_setup_request(); int process_setup_response(e2setup_resp_s setup_response); int process_setup_failure(); int process_subscription_request(ricsubscription_request_s subscription_request); + int process_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request); e2_ap_pdu_c generate_subscription_response(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_subscription_failure(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_subscription_delete_response(ric_subscription_reponse_t ric_subscription_reponse); @@ -75,19 +82,24 @@ public: int process_e2_node_config_update_failure(e2node_cfg_upd_fail_s e2node_config_update_failure); int process_e2_removal_failure(e2_removal_fail_s e2_remove_failure); - int get_reset_id(); - bool get_func_desc(uint32_t ran_func_id, RANfunction_description& fdesc); - bool send_setup_request() { return !e2_established && pending_e2_setup; } + bool queue_send_e2ap_pdu(e2_ap_pdu_c e2ap_pdu); + + int get_reset_id(); + bool get_func_desc(uint32_t ran_func_id, RANfunction_description& fdesc); + bool send_setup_request() { return !e2_established && pending_e2_setup; } + + class ric_subscription; private: - srslog::basic_logger& logger; - e2sm_kpm e2sm_; - bool e2_established = false; - srsran::unique_timer e2_procedure_timeout; - bool pending_e2_setup = true; - bool pending_e2_node_config_update = false; - bool pending_ric_service_update = false; - bool pending_e2_removal = false; + srslog::basic_logger& logger; + ric_client* _ric_client; + e2sm_kpm e2sm_; + bool e2_established = false; + srsran::unique_timer e2_procedure_timeout; + bool pending_e2_setup = true; + bool pending_e2_node_config_update = false; + bool pending_ric_service_update = false; + bool pending_e2_removal = false; int setup_procedure_transaction_id = 0; uint64_t plmn_id = 0x05f510; @@ -100,6 +112,8 @@ private: int reset_transaction_id = 1; cause_c reset_cause = cause_c(); int reset_id = 1; -}; + std::vector > active_subscriptions; +}; +} // namespace srsenb #endif /* RIC_E2AP_H */ diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index c99821539..28c998d66 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -43,6 +43,7 @@ class ric_client : public srsran::thread { public: ric_client(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics); + ~ric_client() = default; // Initiate and Stop bool init(ric_args_t args); @@ -69,8 +70,6 @@ public: bool handle_reset_response(reset_resp_s& reset_response); bool handle_reset_request(reset_request_s& reset_request); - class ric_subscription; - private: srsran::task_scheduler task_sched; srsran::task_queue_handle ric_rece_task_queue; @@ -80,10 +79,8 @@ private: struct sockaddr_in ric_addr = {}; // RIC address bool running = false; - e2ap e2ap_; srsenb::e2_interface_metrics* gnb_metrics = nullptr; - - std::vector > active_subscriptions; + e2ap e2ap_; }; } // namespace srsenb diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/ric_subscription.h index 24d45567a..7ebbc79e9 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/ric_subscription.h @@ -14,19 +14,18 @@ #ifndef SRSRAN_RIC_SUBSCRIPTION_H #define SRSRAN_RIC_SUBSCRIPTION_H -#include "srsgnb/hdr/stack/ric/e2ap.h" -#include "srsgnb/hdr/stack/ric/ric_client.h" +#include "e2ap.h" #include "srsran/common/task_scheduler.h" #include "srsran/common/threads.h" #include "srsran/srsran.h" namespace srsenb { -class ric_client::ric_subscription +class e2ap::ric_subscription { public: - ric_subscription(ric_client* ric_client, ricsubscription_request_s ric_subscription_request); - virtual ~ric_subscription() = default; + ric_subscription(e2ap* e2ap, ricsubscription_request_s ric_subscription_request); + virtual ~ric_subscription() { parent = nullptr; }; uint32_t get_ric_requestor_id() { return ric_requestor_id; }; uint32_t get_ric_instance_id() { return ric_instance_id; }; @@ -45,8 +44,8 @@ private: void _send_ric_indication(); uint32_t _generate_ric_indication_sn(); - ric_client* parent = nullptr; - bool initialized = false; + e2ap* parent = nullptr; + bool initialized = false; uint32_t ric_requestor_id; uint32_t ric_instance_id; diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 5e20e795a..9b08a4f2e 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -1,13 +1,15 @@ #include "srsgnb/hdr/stack/ric/e2ap.h" -#include "stdint.h" +#include "srsgnb/hdr/stack/ric/ric_client.h" +#include "srsgnb/hdr/stack/ric/ric_subscription.h" e2ap::e2ap(srslog::basic_logger& logger, + ric_client* _ric_client, srsenb::e2_interface_metrics* _gnb_metrics, srsran::task_scheduler* _task_sched_ptr) : - logger(logger), e2sm_(logger, _task_sched_ptr), task_sched_ptr(_task_sched_ptr) + logger(logger), _ric_client(_ric_client), e2sm_(logger, _task_sched_ptr), task_sched_ptr(_task_sched_ptr) { - gnb_metrics = _gnb_metrics; + gnb_metrics = _gnb_metrics; e2_procedure_timeout = task_sched_ptr->get_unique_timer(); // register SM to receive enb metrics @@ -21,6 +23,8 @@ e2ap::e2ap(srslog::basic_logger& logger, ran_functions[local_ran_function_id] = add_func; } +e2ap::~e2ap(){}; + bool e2ap::get_func_desc(uint32_t ran_func_id, RANfunction_description& fdesc) { if (ran_functions.count(ran_func_id)) { @@ -30,6 +34,14 @@ bool e2ap::get_func_desc(uint32_t ran_func_id, RANfunction_description& fdesc) return false; } +bool e2ap::queue_send_e2ap_pdu(e2_ap_pdu_c e2ap_pdu) +{ + if (_ric_client) { + _ric_client->queue_send_e2ap_pdu(e2ap_pdu); + } + return true; +} + e2_ap_pdu_c e2ap::generate_setup_request() { e2_ap_pdu_c pdu; @@ -233,9 +245,38 @@ int e2ap::process_setup_response(e2setup_resp_s setup_response) return SRSRAN_SUCCESS; } -int e2ap::process_subscription_request(ricsubscription_request_s subscription_request) +int e2ap::process_subscription_request(ricsubscription_request_s ric_subscription_request) +{ + std::unique_ptr new_ric_subs = + std::make_unique(this, ric_subscription_request); + + if (new_ric_subs->is_initialized()) { + new_ric_subs->start_subscription(); + active_subscriptions.push_back(std::move(new_ric_subs)); + } else { + return false; + } + + return SRSRAN_SUCCESS; +} + +int e2ap::process_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request) { - // TODO: this function seems to be not needed + bool ric_subs_found = false; + for (auto it = active_subscriptions.begin(); it != active_subscriptions.end(); it++) { + if ((**it).get_ric_requestor_id() == ricsubscription_delete_request->ri_crequest_id->ric_requestor_id and + (**it).get_ric_instance_id() == ricsubscription_delete_request->ri_crequest_id->ric_instance_id) { + ric_subs_found = true; + (**it).delete_subscription(); + active_subscriptions.erase(it); + break; + } + } + + if (not ric_subs_found) { + // TODO: send failure + } + return SRSRAN_SUCCESS; } diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 010dea651..6d6257c1f 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -11,13 +11,15 @@ */ #include "srsgnb/hdr/stack/ric/ric_client.h" -#include "srsgnb/hdr/stack/ric/ric_subscription.h" #include "srsran/asn1/e2ap.h" -#include "stdint.h" using namespace srsenb; ric_client::ric_client(srslog::basic_logger& logger, e2_interface_metrics* _gnb_metrics) : - task_sched(), logger(logger), rx_sockets(), thread("RIC_CLIENT_THREAD"), e2ap_(logger, _gnb_metrics, &task_sched) + task_sched(), + logger(logger), + rx_sockets(), + thread("RIC_CLIENT_THREAD"), + e2ap_(logger, this, _gnb_metrics, &task_sched) { gnb_metrics = _gnb_metrics; } @@ -299,13 +301,8 @@ bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_s ric_subscription_request->ri_crequest_id->ric_instance_id, ric_subscription_request->ra_nfunction_id->value); - std::unique_ptr new_ric_subs = - std::make_unique(this, ric_subscription_request); - - if (new_ric_subs->is_initialized()) { - new_ric_subs->start_subscription(); - active_subscriptions.push_back(std::move(new_ric_subs)); - } else { + if (e2ap_.process_subscription_request(ric_subscription_request)) { + logger.error("Failed to process RIC subscription request \n"); return false; } @@ -319,19 +316,9 @@ bool ric_client::handle_ric_subscription_delete_request(ricsubscription_delete_r ricsubscription_delete_request->ri_crequest_id->ric_instance_id, ricsubscription_delete_request->ra_nfunction_id->value); - bool ric_subs_found = false; - for (auto it = active_subscriptions.begin(); it != active_subscriptions.end(); it++) { - if ((**it).get_ric_requestor_id() == ricsubscription_delete_request->ri_crequest_id->ric_requestor_id and - (**it).get_ric_instance_id() == ricsubscription_delete_request->ri_crequest_id->ric_instance_id) { - ric_subs_found = true; - (**it).delete_subscription(); - active_subscriptions.erase(it); - break; - } - } - - if (not ric_subs_found) { - // TODO: send failure + if (e2ap_.process_ric_subscription_delete_request(ricsubscription_delete_request)) { + logger.error("Failed to process RIC subscription delete request \n"); + return false; } return true; diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/ric_subscription.cc index 5c8d5e430..301c870d5 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/ric_subscription.cc @@ -13,19 +13,16 @@ #include "srsgnb/hdr/stack/ric/ric_subscription.h" -namespace srsenb { - -ric_client::ric_subscription::ric_subscription(ric_client* ric_client, - ricsubscription_request_s ric_subscription_request) : - parent(ric_client), +e2ap::ric_subscription::ric_subscription(e2ap* e2ap, ricsubscription_request_s ric_subscription_request) : + parent(e2ap), initialized(false), ric_requestor_id(ric_subscription_request->ri_crequest_id->ric_requestor_id), ric_instance_id(ric_subscription_request->ri_crequest_id->ric_instance_id), ra_nfunction_id(ric_subscription_request->ra_nfunction_id->value), - reporting_timer(parent->task_sched.get_unique_timer()) + reporting_timer(parent->task_sched_ptr->get_unique_timer()) { RANfunction_description ran_func_desc; - if (!parent->e2ap_.get_func_desc(ra_nfunction_id, ran_func_desc)) { + if (!parent->get_func_desc(ra_nfunction_id, ran_func_desc)) { parent->logger.debug("Cannot find RAN function with ID: %i\n", ra_nfunction_id); this->_send_subscription_failure(); return; @@ -91,7 +88,7 @@ ric_client::ric_subscription::ric_subscription(ric_client* ric_cli initialized = true; } -void ric_client::ric_subscription::start_subscription() +void e2ap::ric_subscription::start_subscription() { this->_send_subscription_response(); @@ -103,7 +100,7 @@ void ric_client::ric_subscription::start_subscription() } } -void ric_client::ric_subscription::_send_subscription_response() +void e2ap::ric_subscription::_send_subscription_response() { parent->logger.debug("Send RIC Subscription Response to RIC Requestor ID: %i\n", ric_requestor_id); ric_subscription_reponse_t ric_subscription_reponse; @@ -119,11 +116,11 @@ void ric_client::ric_subscription::_send_subscription_response() ric_subscription_reponse.not_admitted_actions.push_back(action); } - e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_response(ric_subscription_reponse); + e2_ap_pdu_c send_pdu = parent->generate_subscription_response(ric_subscription_reponse); parent->queue_send_e2ap_pdu(send_pdu); } -void ric_client::ric_subscription::_send_subscription_failure() +void e2ap::ric_subscription::_send_subscription_failure() { parent->logger.debug("Send RIC Subscription Failure Response to RIC Requestor ID: %i\n", ric_requestor_id); ric_subscription_reponse_t ric_subscription_reponse; @@ -131,11 +128,11 @@ void ric_client::ric_subscription::_send_subscription_failure() ric_subscription_reponse.ric_instance_id = ric_instance_id; ric_subscription_reponse.ra_nfunction_id = ra_nfunction_id; - e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_failure(ric_subscription_reponse); + e2_ap_pdu_c send_pdu = parent->generate_subscription_failure(ric_subscription_reponse); parent->queue_send_e2ap_pdu(send_pdu); } -void ric_client::ric_subscription::delete_subscription() +void e2ap::ric_subscription::delete_subscription() { if (reporting_timer.is_running()) { parent->logger.debug("Stop sending RIC indication msgs"); @@ -153,39 +150,36 @@ void ric_client::ric_subscription::delete_subscription() sm_ptr->remove_ric_action_definition(action); } } else { - e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_delete_failure(ric_subscription_reponse); + e2_ap_pdu_c send_pdu = parent->generate_subscription_delete_failure(ric_subscription_reponse); parent->queue_send_e2ap_pdu(send_pdu); return; } parent->logger.debug("Send RIC Subscription Delete Response to RIC Requestor ID: %i\n", ric_requestor_id); - e2_ap_pdu_c send_pdu = parent->e2ap_.generate_subscription_delete_response(ric_subscription_reponse); + e2_ap_pdu_c send_pdu = parent->generate_subscription_delete_response(ric_subscription_reponse); parent->queue_send_e2ap_pdu(send_pdu); } -bool ric_client::ric_subscription::handle_subscription_modification_request( - uint32_t ric_subscription_modification_request) +bool e2ap::ric_subscription::handle_subscription_modification_request(uint32_t ric_subscription_modification_request) { // TODO: available in e2ap-v3 return false; } -bool ric_client::ric_subscription::handle_subscription_modification_confirm( - uint32_t ric_subscription_modification_confirm) +bool e2ap::ric_subscription::handle_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm) { // TODO: available in e2ap-v3 return false; } -bool ric_client::ric_subscription::handle_subscription_modification_refuse( - uint32_t ric_subscription_modification_refuse) +bool e2ap::ric_subscription::handle_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse) { // TODO: available in e2ap-v3 return false; } -uint32_t ric_client::ric_subscription::_generate_ric_indication_sn() +uint32_t e2ap::ric_subscription::_generate_ric_indication_sn() { uint32_t sn = _ric_indication_sn_gen; _ric_indication_sn_gen++; @@ -195,7 +189,7 @@ uint32_t ric_client::ric_subscription::_generate_ric_indication_sn() return sn; }; -void ric_client::ric_subscription::_send_ric_indication() +void e2ap::ric_subscription::_send_ric_indication() { if (sm_ptr == nullptr) { parent->logger.error("SM pointer not set in subscription: %i\n", ric_requestor_id); @@ -212,7 +206,7 @@ void ric_client::ric_subscription::_send_ric_indication() ric_indication.ri_indication_sn_present = true; ric_indication.ri_indication_sn = _generate_ric_indication_sn(); if (sm_ptr->generate_ric_indication_content(action, ric_indication)) { - e2_ap_pdu_c send_pdu = parent->e2ap_.generate_indication(ric_indication); + e2_ap_pdu_c send_pdu = parent->generate_indication(ric_indication); parent->queue_send_e2ap_pdu(send_pdu); } } @@ -221,6 +215,4 @@ void ric_client::ric_subscription::_send_ric_indication() if (reporting_period) { reporting_timer.run(); } -} - -} // namespace srsenb \ No newline at end of file +} \ No newline at end of file diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index 4a8e3ebe9..d34dfc6ba 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -105,7 +105,7 @@ void test_native_e2ap_setup_request() e2_ap_pdu_c pdu, pdu2; srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); dummy_metrics_interface dummy_metrics; - e2ap e2ap_(logger, &dummy_metrics, NULL); + e2ap e2ap_(logger, nullptr, &dummy_metrics, NULL); pdu = e2ap_.generate_setup_request(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); @@ -141,7 +141,7 @@ void test_native_e2ap_subscription_response() e2_ap_pdu_c pdu, pdu2; srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); dummy_metrics_interface dummy_metrics; - e2ap e2ap_(logger, &dummy_metrics, NULL); + e2ap e2ap_(logger, nullptr, &dummy_metrics, NULL); ric_subscription_reponse_t ric_subscription_reponse; ric_subscription_reponse.ric_requestor_id = 1021; @@ -169,7 +169,7 @@ void test_native_e2ap_reset_request() e2_ap_pdu_c pdu, pdu2; srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); dummy_metrics_interface dummy_metrics; - e2ap e2ap_(logger, &dummy_metrics, NULL); + e2ap e2ap_(logger, nullptr, &dummy_metrics, NULL); pdu = e2ap_.generate_reset_request(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); @@ -190,7 +190,7 @@ void test_native_e2ap_reset_response() e2_ap_pdu_c pdu, pdu2; srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); dummy_metrics_interface dummy_metrics; - e2ap e2ap_(logger, &dummy_metrics, NULL); + e2ap e2ap_(logger, nullptr, &dummy_metrics, NULL); pdu = e2ap_.generate_reset_response(); asn1::bit_ref bref(buf->msg, buf->get_tailroom()); From d2b42039e13493ce809c3699e2bba4bd2cd4fc0d Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 4 Apr 2023 10:45:11 +0200 Subject: [PATCH 115/167] e2ap: rename ric_subscription to e2ap_ric_subscription --- srsenb/hdr/enb.h | 2 +- .../ric/{ric_subscription.h => e2ap_ric_subscription.h} | 6 +++--- srsgnb/src/stack/ric/CMakeLists.txt | 2 +- srsgnb/src/stack/ric/e2ap.cc | 2 +- .../ric/{ric_subscription.cc => e2ap_ric_subscription.cc} | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) rename srsgnb/hdr/stack/ric/{ric_subscription.h => e2ap_ric_subscription.h} (93%) rename srsgnb/src/stack/ric/{ric_subscription.cc => e2ap_ric_subscription.cc} (99%) diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index c2defb76e..5c30752db 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -33,8 +33,8 @@ #include "srsenb/hdr/stack/mac/sched_interface.h" #include "srsgnb/hdr/stack/gnb_stack_nr.h" +#include "srsgnb/hdr/stack/ric/e2ap_ric_subscription.h" #include "srsgnb/hdr/stack/ric/ric_client.h" -#include "srsgnb/hdr/stack/ric/ric_subscription.h" #include "srsran/common/bcd_helpers.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/interfaces_common.h" diff --git a/srsgnb/hdr/stack/ric/ric_subscription.h b/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h similarity index 93% rename from srsgnb/hdr/stack/ric/ric_subscription.h rename to srsgnb/hdr/stack/ric/e2ap_ric_subscription.h index 7ebbc79e9..180f08dae 100644 --- a/srsgnb/hdr/stack/ric/ric_subscription.h +++ b/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h @@ -11,8 +11,8 @@ * */ -#ifndef SRSRAN_RIC_SUBSCRIPTION_H -#define SRSRAN_RIC_SUBSCRIPTION_H +#ifndef SRSRAN_E2AP_RIC_SUBSCRIPTION_H +#define SRSRAN_E2AP_RIC_SUBSCRIPTION_H #include "e2ap.h" #include "srsran/common/task_scheduler.h" @@ -62,4 +62,4 @@ private: }; } // namespace srsenb -#endif // SRSRAN_RIC_SUBSCRIPTION_H +#endif // SRSRAN_E2AP_RIC_SUBSCRIPTION_H diff --git a/srsgnb/src/stack/ric/CMakeLists.txt b/srsgnb/src/stack/ric/CMakeLists.txt index 86ba74dbd..75c6c2a73 100644 --- a/srsgnb/src/stack/ric/CMakeLists.txt +++ b/srsgnb/src/stack/ric/CMakeLists.txt @@ -1,4 +1,4 @@ -set(SOURCES ric_client.cc ric_subscription.cc e2ap.cc e2sm_kpm_common.cc e2sm_kpm.cc e2sm_kpm_report_service.cc) +set(SOURCES ric_client.cc e2ap_ric_subscription.cc e2ap.cc e2sm_kpm_common.cc e2sm_kpm.cc e2sm_kpm_report_service.cc) add_library(srsgnb_ric STATIC ${SOURCES}) target_link_libraries(srsgnb_ric srsran_asn1 ric_e2) diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 9b08a4f2e..8efd7d593 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -1,7 +1,7 @@ #include "srsgnb/hdr/stack/ric/e2ap.h" +#include "srsgnb/hdr/stack/ric/e2ap_ric_subscription.h" #include "srsgnb/hdr/stack/ric/ric_client.h" -#include "srsgnb/hdr/stack/ric/ric_subscription.h" e2ap::e2ap(srslog::basic_logger& logger, ric_client* _ric_client, diff --git a/srsgnb/src/stack/ric/ric_subscription.cc b/srsgnb/src/stack/ric/e2ap_ric_subscription.cc similarity index 99% rename from srsgnb/src/stack/ric/ric_subscription.cc rename to srsgnb/src/stack/ric/e2ap_ric_subscription.cc index 301c870d5..79e54cc1b 100644 --- a/srsgnb/src/stack/ric/ric_subscription.cc +++ b/srsgnb/src/stack/ric/e2ap_ric_subscription.cc @@ -11,7 +11,7 @@ * */ -#include "srsgnb/hdr/stack/ric/ric_subscription.h" +#include "srsgnb/hdr/stack/ric/e2ap_ric_subscription.h" e2ap::ric_subscription::ric_subscription(e2ap* e2ap, ricsubscription_request_s ric_subscription_request) : parent(e2ap), From c7c4fb85e30898a5e553054488eee7dc9df75b18 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 4 Apr 2023 11:12:35 +0200 Subject: [PATCH 116/167] e2ap: unify names of e2ap_ric_subscription related functions --- srsgnb/hdr/stack/ric/e2ap.h | 7 +++-- srsgnb/hdr/stack/ric/e2ap_ric_subscription.h | 6 ++--- srsgnb/hdr/stack/ric/ric_client.h | 4 +++ srsgnb/src/stack/ric/e2ap.cc | 20 +++++++++++++- srsgnb/src/stack/ric/e2ap_ric_subscription.cc | 12 ++++----- srsgnb/src/stack/ric/ric_client.cc | 27 ++++++++++++++++++- 6 files changed, 63 insertions(+), 13 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index 6c7e707ef..afb10ada8 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -60,8 +60,11 @@ public: e2_ap_pdu_c generate_setup_request(); int process_setup_response(e2setup_resp_s setup_response); int process_setup_failure(); - int process_subscription_request(ricsubscription_request_s subscription_request); - int process_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request); + int process_subscription_request(ricsubscription_request_s ric_subscription_request); + int process_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request); + int process_subscription_modification_request(uint32_t ric_subscription_modification_request); + int process_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm); + int process_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse); e2_ap_pdu_c generate_subscription_response(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_subscription_failure(ric_subscription_reponse_t ric_subscription_reponse); e2_ap_pdu_c generate_subscription_delete_response(ric_subscription_reponse_t ric_subscription_reponse); diff --git a/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h b/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h index 180f08dae..4c192effc 100644 --- a/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h +++ b/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h @@ -34,9 +34,9 @@ public: void start_subscription(); void delete_subscription(); - bool handle_subscription_modification_request(uint32_t ric_subscription_modification_request); - bool handle_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm); - bool handle_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse); + bool process_subscription_modification_request(uint32_t ric_subscription_modification_request); + bool process_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm); + bool process_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse); private: void _send_subscription_response(); diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index 28c998d66..ef754985d 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -67,6 +67,10 @@ public: bool handle_e2_setup_response(e2setup_resp_s setup_response); bool handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request); bool handle_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request); + bool handle_subscription_modification_request(uint32_t ric_subscription_modification_request); + bool handle_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm); + bool handle_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse); + bool handle_reset_response(reset_resp_s& reset_response); bool handle_reset_request(reset_request_s& reset_request); diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 8efd7d593..53d2a59c2 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -260,7 +260,7 @@ int e2ap::process_subscription_request(ricsubscription_request_s ric_subscriptio return SRSRAN_SUCCESS; } -int e2ap::process_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request) +int e2ap::process_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request) { bool ric_subs_found = false; for (auto it = active_subscriptions.begin(); it != active_subscriptions.end(); it++) { @@ -280,6 +280,24 @@ int e2ap::process_ric_subscription_delete_request(ricsubscription_delete_request return SRSRAN_SUCCESS; } +int e2ap::process_subscription_modification_request(uint32_t ric_subscription_modification_request) +{ + // TODO: implement, here only placeholder + return SRSRAN_SUCCESS; +} + +int e2ap::process_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm) +{ + // TODO: implement, here only placeholder + return SRSRAN_SUCCESS; +} + +int e2ap::process_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse) +{ + // TODO: implement, here only placeholder + return SRSRAN_SUCCESS; +} + e2_ap_pdu_c e2ap::generate_indication(ric_indication_t& ric_indication) { using namespace asn1::e2ap; diff --git a/srsgnb/src/stack/ric/e2ap_ric_subscription.cc b/srsgnb/src/stack/ric/e2ap_ric_subscription.cc index 79e54cc1b..3ee8f5a22 100644 --- a/srsgnb/src/stack/ric/e2ap_ric_subscription.cc +++ b/srsgnb/src/stack/ric/e2ap_ric_subscription.cc @@ -161,21 +161,21 @@ void e2ap::ric_subscription::delete_subscription() parent->queue_send_e2ap_pdu(send_pdu); } -bool e2ap::ric_subscription::handle_subscription_modification_request(uint32_t ric_subscription_modification_request) +bool e2ap::ric_subscription::process_subscription_modification_request(uint32_t ric_subscription_modification_request) { - // TODO: available in e2ap-v3 + // TODO: implement, currently not supported in ans1 return false; } -bool e2ap::ric_subscription::handle_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm) +bool e2ap::ric_subscription::process_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm) { - // TODO: available in e2ap-v3 + // TODO: implement, currently not supported in ans1 return false; } -bool e2ap::ric_subscription::handle_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse) +bool e2ap::ric_subscription::process_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse) { - // TODO: available in e2ap-v3 + // TODO: implement, currently not supported in ans1 return false; } diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index 6d6257c1f..f56d177d7 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -316,7 +316,7 @@ bool ric_client::handle_ric_subscription_delete_request(ricsubscription_delete_r ricsubscription_delete_request->ri_crequest_id->ric_instance_id, ricsubscription_delete_request->ra_nfunction_id->value); - if (e2ap_.process_ric_subscription_delete_request(ricsubscription_delete_request)) { + if (e2ap_.process_subscription_delete_request(ricsubscription_delete_request)) { logger.error("Failed to process RIC subscription delete request \n"); return false; } @@ -324,6 +324,31 @@ bool ric_client::handle_ric_subscription_delete_request(ricsubscription_delete_r return true; } +bool ric_client::handle_subscription_modification_request(uint32_t ric_subscription_modification_request) +{ + if (e2ap_.process_subscription_modification_request(ric_subscription_modification_request)) { + logger.error("Failed to process RIC subscription delete request \n"); + return false; + } + return true; +} +bool ric_client::handle_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm) +{ + if (e2ap_.process_subscription_modification_confirm(ric_subscription_modification_confirm)) { + logger.error("Failed to process RIC subscription delete request \n"); + return false; + } + return true; +} +bool ric_client::handle_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse) +{ + if (e2ap_.process_subscription_modification_refuse(ric_subscription_modification_refuse)) { + logger.error("Failed to process RIC subscription delete request \n"); + return false; + } + return true; +} + bool ric_client::handle_reset_request(reset_request_s& reset_request) { printf("Received E2AP E2 Reset Request \n"); From 14c1ed97d37f715b73220f45669ce5ed3e9b3152 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Tue, 4 Apr 2023 11:34:25 +0200 Subject: [PATCH 117/167] e2sm_kpm: simplify metric collection in e2sm_kpm_report_service --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 3 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 35 +++++++++---------- .../src/stack/ric/e2sm_kpm_report_service.cc | 15 +++----- 3 files changed, 22 insertions(+), 31 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 0a535fa1d..79b80bf24 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -58,8 +58,7 @@ private: bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); std::vector _get_supported_meas(uint32_t level_mask); - bool _collect_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item); - bool _collect_real_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item); + bool _collect_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item); bool _extract_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, uint32_t& value); bool _extract_real_type_meas_value(E2SM_KPM_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, float& value); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index adfd19860..49358b116 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -336,28 +336,27 @@ void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) logger.debug("e2sm_kpm received new enb metrics, CPU0 Load: %.1f", last_enb_metrics.sys.cpu_load[0]); } -bool e2sm_kpm::_collect_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item) +bool e2sm_kpm::_collect_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item) { // here we implement logic of measurement data collection, currently we only read from enb_metrics - uint32_t value; - if (_extract_integer_type_meas_value(meas_value, last_enb_metrics, value)) { - item.set_integer() = value; - return true; + if (meas_value.data_type == meas_record_item_c::types::options::integer) { + uint32_t value; + if (_extract_integer_type_meas_value(meas_value, last_enb_metrics, value)) { + item.set_integer() = value; + return true; + } + } else { + // data_type == meas_record_item_c::types::options::real; + float value; + if (_extract_real_type_meas_value(meas_value, last_enb_metrics, value)) { + real_s real_value; + // TODO: real value seems to be not supported in asn1??? + // real_value.value = value; + item.set_real() = real_value; + return true; + } } - return false; -} -bool e2sm_kpm::_collect_real_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item) -{ - // here we implement logic of measurement data collection, currently we only read from enb_metrics - float value; - if (_extract_real_type_meas_value(meas_value, last_enb_metrics, value)) { - real_s real_value; - // TODO: real value seems to be not supported in asn1??? - // real_value.value = value; - item.set_real() = real_value; - return true; - } return false; } diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index 554893ed4..aa065c5ed 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -380,18 +380,11 @@ bool e2sm_kpm_report_service_style1::_collect_meas_data() meas_value.data_type = data_type; meas_record_item_c item; - if (meas_value.data_type == meas_record_item_c::types::options::integer) { - if (not parent->_collect_integer_type_meas_value(meas_value, item)) { - parent->logger.info("Cannot extract value \"%s\" label: %i", meas_name.c_str(), label); - return false; - } - } else { - // data_type == meas_record_item_c::types::options::real; - if (not parent->_collect_real_type_meas_value(meas_value, item)) { - parent->logger.info("Cannot extract value \"%s\" label %i", meas_name.c_str(), label); - return false; - } + if (not parent->_collect_type_meas_value(meas_value, item)) { + parent->logger.info("Cannot extract value \"%s\" label: %i", meas_name.c_str(), label); + return false; } + // save meas value in the proper record list meas_data_item.meas_record.push_back(item); } From e3e5c84ea421a4fe016cc6aa98e6dead69889448 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 5 Apr 2023 08:58:27 +0200 Subject: [PATCH 118/167] e2: fix metrics_e2 description --- srsenb/hdr/metrics_e2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/hdr/metrics_e2.h b/srsenb/hdr/metrics_e2.h index 873c41883..fd45670cb 100644 --- a/srsenb/hdr/metrics_e2.h +++ b/srsenb/hdr/metrics_e2.h @@ -11,8 +11,8 @@ */ /****************************************************************************** - * File: metrics_stdout.h - * Description: Metrics class printing to stdout. + * File: metrics_e2.h + * Description: Metrics class passing to E2 agent. *****************************************************************************/ #ifndef SRSENB_METRICS_E2_H From 2d95884920405696089d4125b99a99033918dd70 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 5 Apr 2023 09:00:26 +0200 Subject: [PATCH 119/167] e2: fix formating in main::parse_args --- srsenb/src/main.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 39b2f177f..019a8ab96 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -232,7 +232,8 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("ric_client.enable", bpo::value(&args->ric_client.enable)->default_value(false), "Enables the RIC client") ("ric_client.ric_ip", bpo::value(&args->ric_client.ric_ip)->default_value("127.0.0.1"), "RIC IP address") ("ric_client.ric_port", bpo::value(&args->ric_client.ric_port)->default_value(36421), "RIC port") - /* Expert section */ + + /* Expert section */ ("expert.metrics_period_secs", bpo::value(&args->general.metrics_period_secs)->default_value(1.0), "Periodicity for metrics in seconds.") ("expert.metrics_csv_enable", bpo::value(&args->general.metrics_csv_enable)->default_value(false), "Write metrics to CSV file.") ("expert.metrics_csv_filename", bpo::value(&args->general.metrics_csv_filename)->default_value("/tmp/enb_metrics.csv"), "Metrics CSV filename.") From 826aa46682da478649e8c25e4f2f2bbeac1e9645 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 5 Apr 2023 09:14:06 +0200 Subject: [PATCH 120/167] e2: update year in copyright section --- lib/include/srsran/interfaces/e2_metrics_interface.h | 2 +- srsenb/hdr/metrics_e2.h | 2 +- srsenb/src/metrics_e2.cc | 2 +- srsgnb/hdr/stack/ric/e2ap.h | 2 +- srsgnb/hdr/stack/ric/e2ap_ric_subscription.h | 2 +- srsgnb/hdr/stack/ric/e2sm.h | 2 +- srsgnb/hdr/stack/ric/e2sm_kpm.h | 3 ++- srsgnb/hdr/stack/ric/e2sm_kpm_common.h | 2 +- srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h | 2 +- srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h | 2 +- srsgnb/hdr/stack/ric/ric_client.h | 2 +- srsgnb/src/stack/ric/CMakeLists.txt | 8 ++++++++ srsgnb/src/stack/ric/e2ap.cc | 11 +++++++++++ srsgnb/src/stack/ric/e2ap_ric_subscription.cc | 2 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 2 +- srsgnb/src/stack/ric/e2sm_kpm_common.cc | 2 +- srsgnb/src/stack/ric/e2sm_kpm_report_service.cc | 2 +- srsgnb/src/stack/ric/ric_client.cc | 2 +- srsgnb/src/stack/ric/test/CMakeLists.txt | 2 +- srsgnb/src/stack/ric/test/e2ap_test.cc | 12 ++++++++++++ 20 files changed, 49 insertions(+), 17 deletions(-) diff --git a/lib/include/srsran/interfaces/e2_metrics_interface.h b/lib/include/srsran/interfaces/e2_metrics_interface.h index d09a8d53b..5dc37e602 100644 --- a/lib/include/srsran/interfaces/e2_metrics_interface.h +++ b/lib/include/srsran/interfaces/e2_metrics_interface.h @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsenb/hdr/metrics_e2.h b/srsenb/hdr/metrics_e2.h index fd45670cb..b6d1d1fbe 100644 --- a/srsenb/hdr/metrics_e2.h +++ b/srsenb/hdr/metrics_e2.h @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsenb/src/metrics_e2.cc b/srsenb/src/metrics_e2.cc index 4be8cb701..ad35b4d0b 100644 --- a/srsenb/src/metrics_e2.cc +++ b/srsenb/src/metrics_e2.cc @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index afb10ada8..e32076259 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h b/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h index 4c192effc..6f5f206fa 100644 --- a/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h +++ b/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index 5fcb50e10..f89c894d0 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 79b80bf24..6686243ad 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 @@ -10,6 +10,7 @@ * * */ + #include "e2sm.h" #include "e2sm_kpm_common.h" #include "srsran/asn1/e2ap.h" diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h index 78e36bee8..6669b002c 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h index 9bf016b21..535275189 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h index cd3af4e4a..49c573f5c 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index ef754985d..ee8596281 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/src/stack/ric/CMakeLists.txt b/srsgnb/src/stack/ric/CMakeLists.txt index 75c6c2a73..915907e14 100644 --- a/srsgnb/src/stack/ric/CMakeLists.txt +++ b/srsgnb/src/stack/ric/CMakeLists.txt @@ -1,3 +1,11 @@ +# +# Copyright 2013-2023 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. +# + set(SOURCES ric_client.cc e2ap_ric_subscription.cc e2ap.cc e2sm_kpm_common.cc e2sm_kpm.cc e2sm_kpm_report_service.cc) add_library(srsgnb_ric STATIC ${SOURCES}) target_link_libraries(srsgnb_ric srsran_asn1 ric_e2) diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 53d2a59c2..ac6b9d9a9 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -1,3 +1,14 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2023 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 "srsgnb/hdr/stack/ric/e2ap.h" #include "srsgnb/hdr/stack/ric/e2ap_ric_subscription.h" diff --git a/srsgnb/src/stack/ric/e2ap_ric_subscription.cc b/srsgnb/src/stack/ric/e2ap_ric_subscription.cc index 3ee8f5a22..ef8dafb0a 100644 --- a/srsgnb/src/stack/ric/e2ap_ric_subscription.cc +++ b/srsgnb/src/stack/ric/e2ap_ric_subscription.cc @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 49358b116..43c1d26e4 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/src/stack/ric/e2sm_kpm_common.cc b/srsgnb/src/stack/ric/e2sm_kpm_common.cc index 49f808381..20f98a698 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_common.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_common.cc @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index aa065c5ed..0d08be268 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index f56d177d7..f9bdf0444 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -2,7 +2,7 @@ * * \section COPYRIGHT * - * Copyright 2013-2022 Software Radio Systems Limited + * Copyright 2013-2023 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 diff --git a/srsgnb/src/stack/ric/test/CMakeLists.txt b/srsgnb/src/stack/ric/test/CMakeLists.txt index a29d444f0..9350f2169 100644 --- a/srsgnb/src/stack/ric/test/CMakeLists.txt +++ b/srsgnb/src/stack/ric/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 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 diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index d34dfc6ba..3aa9982e1 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -1,3 +1,15 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2023 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 "srsgnb/hdr/stack/ric/e2ap.h" #include "srsran/asn1/e2ap.h" #include "srsran/common/test_common.h" From f48a80a06e25b307a37e2c77080d3bca516804a2 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 5 Apr 2023 09:32:20 +0200 Subject: [PATCH 121/167] e2sm: initialize class members --- srsgnb/hdr/stack/ric/e2sm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h index f89c894d0..1cbfe064e 100644 --- a/srsgnb/hdr/stack/ric/e2sm.h +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -90,7 +90,7 @@ private: const std::string _short_name; const std::string _oid; const std::string _func_description; - const uint32_t _revision; + const uint32_t _revision = 0; uint32_t _registered_action_id_gen = 1000; }; @@ -98,7 +98,7 @@ private: struct RANfunction_description { bool accepted = false; int function_instance = 0; - e2sm* sm_ptr; + e2sm* sm_ptr = nullptr; std::string function_shortname; std::string function_e2_sm_oid; std::string function_desc; From 79c3cb600b398798631f9bd63b83b02ac67d95f8 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 5 Apr 2023 10:21:02 +0200 Subject: [PATCH 122/167] e2: rename class ric_client to e2_agent --- srsenb/enb.conf.example | 2 +- srsenb/hdr/enb.h | 6 ++-- srsenb/src/enb.cc | 20 +++++------ srsenb/src/main.cc | 14 ++++---- srsgnb/hdr/stack/ric/e2ap.h | 6 ++-- srsgnb/hdr/stack/ric/ric_client.h | 10 +++--- srsgnb/src/stack/ric/e2ap.cc | 10 +++--- srsgnb/src/stack/ric/ric_client.cc | 58 ++++++++++++++---------------- 8 files changed, 61 insertions(+), 65 deletions(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index e34503e16..985e0fab5 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -371,7 +371,7 @@ enable = false #ema_alpha = 0.0143 ##################################################################### -[ric_client] +[e2_agent] enable = true #ric_ip = 127.0.0.1 #ric_port = 36421 diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 5c30752db..bfe0bad07 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -114,7 +114,7 @@ struct all_args_t { general_args_t general; phy_args_t phy; stack_args_t stack; - ric_args_t ric_client; + e2_agent_args_t e2_agent; gnb_stack_args_t nr_stack; }; @@ -139,7 +139,7 @@ public: void print_pool(); - bool enable_ric_client(srsenb::e2_interface_metrics* e2_metrics); + bool enable_e2_agent(srsenb::e2_interface_metrics* e2_metrics); // eNodeB metrics interface bool get_metrics(enb_metrics_t* m) override; @@ -174,7 +174,7 @@ private: std::unique_ptr nr_stack = nullptr; std::unique_ptr radio = nullptr; std::unique_ptr phy = nullptr; - std::unique_ptr ric = nullptr; + std::unique_ptr _e2_agent = nullptr; // System metrics processor. srsran::sys_metrics_processor sys_proc; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 51b727f3a..2c5299db7 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -190,19 +190,19 @@ void enb::start_plot() phy->start_plot(); } -bool enb::enable_ric_client(srsenb::e2_interface_metrics* e2_metrics) +bool enb::enable_e2_agent(srsenb::e2_interface_metrics* e2_metrics) { - std::unique_ptr tmp_ric_client = std::unique_ptr( - new srsenb::ric_client(srslog::fetch_basic_logger("RIC", log_sink, false), e2_metrics)); - if (tmp_ric_client == nullptr) { - srsran::console("Error creating RIC client instance.\n"); + std::unique_ptr tmp_e2_agent = std::unique_ptr( + new srsenb::e2_agent(srslog::fetch_basic_logger("E2_AGENT", log_sink, false), e2_metrics)); + if (tmp_e2_agent == nullptr) { + srsran::console("Error creating e2_agent instance.\n"); return SRSRAN_ERROR; } - if (tmp_ric_client->init(args.ric_client)) { - srsran::console("Error initializing RIC client.\n"); + if (tmp_e2_agent->init(args.e2_agent)) { + srsran::console("Error initializing e2_agent client.\n"); return SRSRAN_ERROR; } - ric = std::move(tmp_ric_client); + _e2_agent = std::move(tmp_e2_agent); return SRSRAN_SUCCESS; } @@ -275,8 +275,8 @@ void enb::tti_clock() return; } - if (ric) { - ric->tic(); + if (_e2_agent) { + _e2_agent->tic(); } if (eutra_stack) { diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 019a8ab96..58ac1c9a1 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -229,9 +229,9 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("cfr.ema_alpha", bpo::value(&args->phy.cfr_args.ema_alpha)->default_value(args->phy.cfr_args.ema_alpha), "Alpha coefficient for the power average in auto_ema mode (0 to 1)") /* RIC section */ - ("ric_client.enable", bpo::value(&args->ric_client.enable)->default_value(false), "Enables the RIC client") - ("ric_client.ric_ip", bpo::value(&args->ric_client.ric_ip)->default_value("127.0.0.1"), "RIC IP address") - ("ric_client.ric_port", bpo::value(&args->ric_client.ric_port)->default_value(36421), "RIC port") + ("e2_agent.enable", bpo::value(&args->e2_agent.enable)->default_value(false), "Enables the E2 agent") + ("e2_agent.ric_ip", bpo::value(&args->e2_agent.ric_ip)->default_value("127.0.0.1"), "RIC IP address") + ("e2_agent.ric_port", bpo::value(&args->e2_agent.ric_port)->default_value(36421), "RIC port") /* Expert section */ ("expert.metrics_period_secs", bpo::value(&args->general.metrics_period_secs)->default_value(1.0), "Periodicity for metrics in seconds.") @@ -684,7 +684,7 @@ int main(int argc, char* argv[]) metricshub.add_listener(&json_metrics); } srsenb::metrics_e2 e2_metrics(enb.get()); - if (args.ric_client.enable) { + if (args.e2_agent.enable) { metricshub.add_listener(&e2_metrics); } @@ -695,9 +695,9 @@ int main(int argc, char* argv[]) if (args.gui.enable) { enb->start_plot(); } - if (args.ric_client.enable) { - if (enb->enable_ric_client(&e2_metrics)) { - srslog::fetch_basic_logger("RIC").error("Failed to enable RIC client"); + if (args.e2_agent.enable) { + if (enb->enable_e2_agent(&e2_metrics)) { + srslog::fetch_basic_logger("E2_AGENT").error("Failed to enable E2 Agent"); } } } diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h index e32076259..dc909533a 100644 --- a/srsgnb/hdr/stack/ric/e2ap.h +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -46,13 +46,13 @@ typedef struct { std::vector not_admitted_actions; } ric_subscription_reponse_t; -class ric_client; +class e2_agent; class e2ap { public: e2ap(srslog::basic_logger& logger, - ric_client* _ric_client, + e2_agent* _e2_agent, srsenb::e2_interface_metrics* _gnb_metrics, srsran::task_scheduler* _task_sched_ptr); ~e2ap(); @@ -95,7 +95,7 @@ public: private: srslog::basic_logger& logger; - ric_client* _ric_client; + e2_agent* _e2_agent; e2sm_kpm e2sm_; bool e2_established = false; srsran::unique_timer e2_procedure_timeout; diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/ric_client.h index ee8596281..b9a03c408 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/ric_client.h @@ -32,21 +32,21 @@ enum e2_msg_type_t { E2_RESET_RESPONSE }; -struct ric_args_t { +struct e2_agent_args_t { bool enable; std::string ric_ip; uint32_t ric_port; }; namespace srsenb { -class ric_client : public srsran::thread +class e2_agent : public srsran::thread { public: - ric_client(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics); - ~ric_client() = default; + e2_agent(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics); + ~e2_agent() = default; // Initiate and Stop - bool init(ric_args_t args); + bool init(e2_agent_args_t args); void stop(); void run_thread(); void tic(); diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index ac6b9d9a9..8aafcf3cc 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -15,10 +15,10 @@ #include "srsgnb/hdr/stack/ric/ric_client.h" e2ap::e2ap(srslog::basic_logger& logger, - ric_client* _ric_client, + e2_agent* _e2_agent, srsenb::e2_interface_metrics* _gnb_metrics, srsran::task_scheduler* _task_sched_ptr) : - logger(logger), _ric_client(_ric_client), e2sm_(logger, _task_sched_ptr), task_sched_ptr(_task_sched_ptr) + logger(logger), _e2_agent(_e2_agent), e2sm_(logger, _task_sched_ptr), task_sched_ptr(_task_sched_ptr) { gnb_metrics = _gnb_metrics; e2_procedure_timeout = task_sched_ptr->get_unique_timer(); @@ -47,8 +47,8 @@ bool e2ap::get_func_desc(uint32_t ran_func_id, RANfunction_description& fdesc) bool e2ap::queue_send_e2ap_pdu(e2_ap_pdu_c e2ap_pdu) { - if (_ric_client) { - _ric_client->queue_send_e2ap_pdu(e2ap_pdu); + if (_e2_agent) { + _e2_agent->queue_send_e2ap_pdu(e2ap_pdu); } return true; } @@ -382,7 +382,7 @@ int e2ap::process_reset_request(reset_request_s reset_request) { reset_id = reset_request->transaction_id.value; - // TO DO: Parse and store the cause for future extension of the ric client + // TODO: Parse and store the cause for future extension of the e2_agent return SRSRAN_SUCCESS; } diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/ric_client.cc index f9bdf0444..61db28922 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/ric_client.cc @@ -14,19 +14,15 @@ #include "srsran/asn1/e2ap.h" using namespace srsenb; -ric_client::ric_client(srslog::basic_logger& logger, e2_interface_metrics* _gnb_metrics) : - task_sched(), - logger(logger), - rx_sockets(), - thread("RIC_CLIENT_THREAD"), - e2ap_(logger, this, _gnb_metrics, &task_sched) +e2_agent::e2_agent(srslog::basic_logger& logger, e2_interface_metrics* _gnb_metrics) : + task_sched(), logger(logger), rx_sockets(), thread("E2_AGENT_THREAD"), e2ap_(logger, this, _gnb_metrics, &task_sched) { gnb_metrics = _gnb_metrics; } -bool ric_client::init(ric_args_t args) +bool e2_agent::init(e2_agent_args_t args) { - printf("RIC_CLIENT: Init\n"); + printf("E2_AGENT: Init\n"); using namespace srsran::net_utils; // Open SCTP socket if (not ric_socket.open_socket(addr_family::ipv4, socket_type::seqpacket, protocol_type::SCTP)) { @@ -63,19 +59,19 @@ bool ric_client::init(ric_args_t args) return SRSRAN_SUCCESS; } -void ric_client::stop() +void e2_agent::stop() { running = false; wait_thread_finish(); } -void ric_client::tic() +void e2_agent::tic() { // get tick every 1ms to advance timers task_sched.tic(); } -void ric_client::run_thread() +void e2_agent::run_thread() { using namespace asn1::e2ap; @@ -88,7 +84,7 @@ void ric_client::run_thread() } } -bool ric_client::send_sctp(srsran::unique_byte_buffer_t& buf) +bool e2_agent::send_sctp(srsran::unique_byte_buffer_t& buf) { ssize_t ret; ret = sctp_sendmsg(ric_socket.fd(), @@ -108,7 +104,7 @@ bool ric_client::send_sctp(srsran::unique_byte_buffer_t& buf) return true; } -bool ric_client::send_e2_msg(e2_msg_type_t msg_type) +bool e2_agent::send_e2_msg(e2_msg_type_t msg_type) { std::string message_name; e2_ap_pdu_c send_pdu; @@ -134,14 +130,14 @@ bool ric_client::send_e2_msg(e2_msg_type_t msg_type) return send_e2ap_pdu(send_pdu); } -bool ric_client::queue_send_e2ap_pdu(e2_ap_pdu_c e2ap_pdu) +bool e2_agent::queue_send_e2ap_pdu(e2_ap_pdu_c e2ap_pdu) { auto send_e2ap_pdu_task = [this, e2ap_pdu]() { send_e2ap_pdu(e2ap_pdu); }; ric_rece_task_queue.push(send_e2ap_pdu_task); return true; } -bool ric_client::send_e2ap_pdu(e2_ap_pdu_c send_pdu) +bool e2_agent::send_e2ap_pdu(e2_ap_pdu_c send_pdu) { srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); if (buf == nullptr) { @@ -162,12 +158,12 @@ bool ric_client::send_e2ap_pdu(e2_ap_pdu_c send_pdu) return true; } -bool ric_client::handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, - const sockaddr_in& from, - const sctp_sndrcvinfo& sri, - int flags) +bool e2_agent::handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, + const sockaddr_in& from, + const sctp_sndrcvinfo& sri, + int flags) { - printf("RIC_CLIENT: Received %d bytes from %s\n", pdu->N_bytes, inet_ntoa(from.sin_addr)); + printf("E2_AGENT: Received %d bytes from %s\n", pdu->N_bytes, inet_ntoa(from.sin_addr)); e2_ap_pdu_c pdu_c; asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); if (pdu_c.unpack(bref) != asn1::SRSASN_SUCCESS) { @@ -189,7 +185,7 @@ bool ric_client::handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, return true; } -bool ric_client::handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg) +bool e2_agent::handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg) { using namespace asn1::e2ap; if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::ricsubscription_request) { @@ -218,7 +214,7 @@ bool ric_client::handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg) return true; } -bool ric_client::handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& successful_outcome) +bool e2_agent::handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& successful_outcome) { using namespace asn1::e2ap; if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::e2setup_resp) { @@ -248,7 +244,7 @@ bool ric_client::handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& return true; } -bool ric_client::handle_e2_setup_response(e2setup_resp_s setup_response) +bool e2_agent::handle_e2_setup_response(e2setup_resp_s setup_response) { if (e2ap_.process_setup_response(setup_response)) { logger.error("Failed to process E2 Setup Response \n"); @@ -257,7 +253,7 @@ bool ric_client::handle_e2_setup_response(e2setup_resp_s setup_response) return true; } -bool ric_client::handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome) +bool e2_agent::handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome) { using namespace asn1::e2ap; if (unsuccessful_outcome.value.type() == e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::e2setup_fail) { @@ -294,7 +290,7 @@ bool ric_client::handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome return true; } -bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request) +bool e2_agent::handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request) { logger.info("Received RIC Subscription Request from RIC ID: %i (instance id %i) to RAN Function ID: %i", ric_subscription_request->ri_crequest_id->ric_requestor_id, @@ -309,7 +305,7 @@ bool ric_client::handle_ric_subscription_request(ricsubscription_request_s ric_s return true; } -bool ric_client::handle_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request) +bool e2_agent::handle_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request) { logger.info("Received RIC Subscription Delete request from RIC ID: %i (instance id %i) to RAN Function ID: %i", ricsubscription_delete_request->ri_crequest_id->ric_requestor_id, @@ -324,7 +320,7 @@ bool ric_client::handle_ric_subscription_delete_request(ricsubscription_delete_r return true; } -bool ric_client::handle_subscription_modification_request(uint32_t ric_subscription_modification_request) +bool e2_agent::handle_subscription_modification_request(uint32_t ric_subscription_modification_request) { if (e2ap_.process_subscription_modification_request(ric_subscription_modification_request)) { logger.error("Failed to process RIC subscription delete request \n"); @@ -332,7 +328,7 @@ bool ric_client::handle_subscription_modification_request(uint32_t ric_subscript } return true; } -bool ric_client::handle_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm) +bool e2_agent::handle_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm) { if (e2ap_.process_subscription_modification_confirm(ric_subscription_modification_confirm)) { logger.error("Failed to process RIC subscription delete request \n"); @@ -340,7 +336,7 @@ bool ric_client::handle_subscription_modification_confirm(uint32_t ric_subscript } return true; } -bool ric_client::handle_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse) +bool e2_agent::handle_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse) { if (e2ap_.process_subscription_modification_refuse(ric_subscription_modification_refuse)) { logger.error("Failed to process RIC subscription delete request \n"); @@ -349,7 +345,7 @@ bool ric_client::handle_subscription_modification_refuse(uint32_t ric_subscripti return true; } -bool ric_client::handle_reset_request(reset_request_s& reset_request) +bool e2_agent::handle_reset_request(reset_request_s& reset_request) { printf("Received E2AP E2 Reset Request \n"); // call process to handle reset request, if it fails log error and return false, else return true - success @@ -367,7 +363,7 @@ bool ric_client::handle_reset_request(reset_request_s& reset_request) return true; } -bool ric_client::handle_reset_response(reset_resp_s& reset_response) +bool e2_agent::handle_reset_response(reset_resp_s& reset_response) { printf("Received E2AP E2 Reset Response \n"); // call process to handle reset reponse, if it fails log error, else return true - success From 9dbd924339cb27e5f7c6420db07d59b7a42e3e18 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 5 Apr 2023 10:30:13 +0200 Subject: [PATCH 123/167] e2: rename file ric_client to e2_agent --- srsenb/hdr/enb.h | 2 +- srsgnb/hdr/stack/ric/{ric_client.h => e2_agent.h} | 6 +++--- srsgnb/src/stack/ric/CMakeLists.txt | 2 +- srsgnb/src/stack/ric/{ric_client.cc => e2_agent.cc} | 2 +- srsgnb/src/stack/ric/e2ap.cc | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) rename srsgnb/hdr/stack/ric/{ric_client.h => e2_agent.h} (97%) rename srsgnb/src/stack/ric/{ric_client.cc => e2_agent.cc} (99%) diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index bfe0bad07..92c6b5d0a 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -33,8 +33,8 @@ #include "srsenb/hdr/stack/mac/sched_interface.h" #include "srsgnb/hdr/stack/gnb_stack_nr.h" +#include "srsgnb/hdr/stack/ric/e2_agent.h" #include "srsgnb/hdr/stack/ric/e2ap_ric_subscription.h" -#include "srsgnb/hdr/stack/ric/ric_client.h" #include "srsran/common/bcd_helpers.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/interfaces_common.h" diff --git a/srsgnb/hdr/stack/ric/ric_client.h b/srsgnb/hdr/stack/ric/e2_agent.h similarity index 97% rename from srsgnb/hdr/stack/ric/ric_client.h rename to srsgnb/hdr/stack/ric/e2_agent.h index b9a03c408..bbe89240a 100644 --- a/srsgnb/hdr/stack/ric/ric_client.h +++ b/srsgnb/hdr/stack/ric/e2_agent.h @@ -11,8 +11,8 @@ * */ -#ifndef RIC_CLIENT_H -#define RIC_CLIENT_H +#ifndef E2_AGENT_H +#define E2_AGENT_H #include "srsgnb/hdr/stack/ric/e2ap.h" #include "srsran/common/network_utils.h" @@ -88,4 +88,4 @@ private: }; } // namespace srsenb -#endif /* RIC_CLIENT_H */ +#endif /* E2_AGENT_H */ diff --git a/srsgnb/src/stack/ric/CMakeLists.txt b/srsgnb/src/stack/ric/CMakeLists.txt index 915907e14..c2980b29e 100644 --- a/srsgnb/src/stack/ric/CMakeLists.txt +++ b/srsgnb/src/stack/ric/CMakeLists.txt @@ -6,7 +6,7 @@ # the distribution. # -set(SOURCES ric_client.cc e2ap_ric_subscription.cc e2ap.cc e2sm_kpm_common.cc e2sm_kpm.cc e2sm_kpm_report_service.cc) +set(SOURCES e2_agent.cc e2ap_ric_subscription.cc e2ap.cc e2sm_kpm_common.cc e2sm_kpm.cc e2sm_kpm_report_service.cc) add_library(srsgnb_ric STATIC ${SOURCES}) target_link_libraries(srsgnb_ric srsran_asn1 ric_e2) diff --git a/srsgnb/src/stack/ric/ric_client.cc b/srsgnb/src/stack/ric/e2_agent.cc similarity index 99% rename from srsgnb/src/stack/ric/ric_client.cc rename to srsgnb/src/stack/ric/e2_agent.cc index 61db28922..bb683efa2 100644 --- a/srsgnb/src/stack/ric/ric_client.cc +++ b/srsgnb/src/stack/ric/e2_agent.cc @@ -10,7 +10,7 @@ * */ -#include "srsgnb/hdr/stack/ric/ric_client.h" +#include "srsgnb/hdr/stack/ric/e2_agent.h" #include "srsran/asn1/e2ap.h" using namespace srsenb; diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index 8aafcf3cc..ab34e43e3 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -11,8 +11,8 @@ */ #include "srsgnb/hdr/stack/ric/e2ap.h" +#include "srsgnb/hdr/stack/ric/e2_agent.h" #include "srsgnb/hdr/stack/ric/e2ap_ric_subscription.h" -#include "srsgnb/hdr/stack/ric/ric_client.h" e2ap::e2ap(srslog::basic_logger& logger, e2_agent* _e2_agent, From 2fc11141674af503a23d73d34e4e603ab7b02549 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 5 Apr 2023 10:57:05 +0200 Subject: [PATCH 124/167] e2sm_kpm: rename E2SM_KPM_metric_t and E2SM_KPM_meas_def_t --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 10 +++++----- srsgnb/hdr/stack/ric/e2sm_kpm_common.h | 4 ++-- srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h | 16 ++++++++-------- srsgnb/src/stack/ric/e2sm_kpm.cc | 10 +++++----- srsgnb/src/stack/ric/e2sm_kpm_report_service.cc | 6 +++--- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 6686243ad..3abf3aa60 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -56,16 +56,16 @@ public: private: bool _generate_indication_header(e2_sm_kpm_ind_hdr_s& hdr, srsran::unique_byte_buffer_t& buf); bool _generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::unique_byte_buffer_t& buf); - bool _get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def); + bool _get_meas_definition(std::string meas_name, e2sm_kpm_metric_t& def); std::vector _get_supported_meas(uint32_t level_mask); - bool _collect_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item); + bool _collect_type_meas_value(e2sm_kpm_meas_def_t& meas_value, meas_record_item_c& item); bool - _extract_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, uint32_t& value); - bool _extract_real_type_meas_value(E2SM_KPM_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, float& value); + _extract_integer_type_meas_value(e2sm_kpm_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, uint32_t& value); + bool _extract_real_type_meas_value(e2sm_kpm_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, float& value); srslog::basic_logger& logger; - std::vector supported_meas_types; + std::vector supported_meas_types; std::map registered_actions_data; srsran_random_t random_gen; diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h index 6669b002c..bb0b87339 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h @@ -35,7 +35,7 @@ typedef struct { double max_val; uint32_t supported_labels; uint32_t supported_scopes; -} E2SM_KPM_metric_t; +} e2sm_kpm_metric_t; // TODO: define all labels and scopes @@ -67,6 +67,6 @@ typedef struct { meas_record_item_c::types data_type; uint32_t ue_id; // TODO: do we need to use type ueid_c? or we translate to local RNTI? uint32_t cell_id; // TODO: do we need to use type cgi_c? or we translate to local cell_id? -} E2SM_KPM_meas_def_t; +} e2sm_kpm_meas_def_t; #endif // SRSRAN_E2SM_KPM_COMMON_H diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h index 535275189..b9c4d744a 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h @@ -19,10 +19,10 @@ // clang-format off // Measurements defined in 3GPP TS 28.552 -std::vector get_e2sm_kpm_28_552_metrics() +std::vector get_e2sm_kpm_28_552_metrics() { // TODO: add all metrics from 3GPP TS 28.552 - std::vector metrics; + std::vector metrics; // not supported metrics metrics.push_back({"RRU.PrbTotDl", false, REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, CELL_LEVEL | UE_LEVEL }); metrics.push_back({"RRU.PrbTotUl", false, REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, CELL_LEVEL | UE_LEVEL }); @@ -32,25 +32,25 @@ std::vector get_e2sm_kpm_28_552_metrics() } // Measurements defined in 3GPP TS 32.425 -std::vector get_e2sm_kpm_34_425_metrics() +std::vector get_e2sm_kpm_34_425_metrics() { // TODO: add all metrics from 3GPP TS 32.425 - std::vector metrics; + std::vector metrics; return metrics; } // E2SM_KPM O-RAN specific Measurements -std::vector e2sm_kpm_oran_metrics() +std::vector e2sm_kpm_oran_metrics() { // TODO: add all E2SM_KPM O-RAN specific Measurements - std::vector metrics; + std::vector metrics; return metrics; } // Custom Measurements -std::vector e2sm_kpm_custom_metrics() +std::vector e2sm_kpm_custom_metrics() { - std::vector metrics; + std::vector metrics; // supported metrics metrics.push_back({"test", true, INTEGER, "", true, 0, true, 100, NO_LABEL, ENB_LEVEL | CELL_LEVEL | UE_LEVEL }); metrics.push_back({"random_int", true, INTEGER, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL }); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index 43c1d26e4..b98b812f5 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -299,9 +299,9 @@ bool e2sm_kpm::_generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::un return true; } -bool e2sm_kpm::_get_meas_definition(std::string meas_name, E2SM_KPM_metric_t& def) +bool e2sm_kpm::_get_meas_definition(std::string meas_name, e2sm_kpm_metric_t& def) { - auto name_matches = [&meas_name](const E2SM_KPM_metric_t& x) { + auto name_matches = [&meas_name](const e2sm_kpm_metric_t& x) { return (x.name == meas_name.c_str() or x.name == meas_name); }; auto it = std::find_if(supported_meas_types.begin(), supported_meas_types.end(), name_matches); @@ -336,7 +336,7 @@ void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) logger.debug("e2sm_kpm received new enb metrics, CPU0 Load: %.1f", last_enb_metrics.sys.cpu_load[0]); } -bool e2sm_kpm::_collect_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_record_item_c& item) +bool e2sm_kpm::_collect_type_meas_value(e2sm_kpm_meas_def_t& meas_value, meas_record_item_c& item) { // here we implement logic of measurement data collection, currently we only read from enb_metrics if (meas_value.data_type == meas_record_item_c::types::options::integer) { @@ -360,7 +360,7 @@ bool e2sm_kpm::_collect_type_meas_value(E2SM_KPM_meas_def_t& meas_value, meas_re return false; } -bool e2sm_kpm::_extract_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, +bool e2sm_kpm::_extract_integer_type_meas_value(e2sm_kpm_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, uint32_t& value) { @@ -409,7 +409,7 @@ bool e2sm_kpm::_extract_integer_type_meas_value(E2SM_KPM_meas_def_t& meas_value, return false; } -bool e2sm_kpm::_extract_real_type_meas_value(E2SM_KPM_meas_def_t& meas_value, +bool e2sm_kpm::_extract_real_type_meas_value(e2sm_kpm_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, float& value) { diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index 0d08be268..c66057127 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -68,7 +68,7 @@ meas_record_item_c::types e2sm_kpm_report_service::_get_meas_data_type(std::stri meas_record_item_c::types data_type = meas_record_item_c::types::options::nulltype; // if no data collected check the type using metric definition if (meas_record_list.size() == 0) { - E2SM_KPM_metric_t metric_definition; + e2sm_kpm_metric_t metric_definition; if (not parent->_get_meas_definition(meas_name, metric_definition)) { parent->logger.debug("No definition for measurement type \"%s\"", metric_definition.name); return data_type; @@ -228,7 +228,7 @@ bool e2sm_kpm_report_service_style1::process_ric_action_definition(e2sm_kpm* meas_info_list = action_definition.meas_info_list; for (uint32_t i = 0; i < meas_info_list.size(); i++) { std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); - E2SM_KPM_metric_t metric_definition; + e2sm_kpm_metric_t metric_definition; if (not e2sm_kpm->_get_meas_definition(meas_name, metric_definition)) { printf("Unsupported measurement name: \"%s\" --> do not admit action\n", meas_name.c_str()); return false; @@ -369,7 +369,7 @@ bool e2sm_kpm_report_service_style1::_collect_meas_data() meas_record_item_c::types data_type = _get_meas_data_type(meas_name, label, meas_data_item.meas_record); // extract a needed value from enb metrics and add to the proper meas record list - E2SM_KPM_meas_def_t meas_value; + e2sm_kpm_meas_def_t meas_value; meas_value.name = meas_name; meas_value.label = label; meas_value.scope = ENB_LEVEL; From 82d2fd1973682cbb01fc09487760d782d1413b67 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 5 Apr 2023 11:40:44 +0200 Subject: [PATCH 125/167] e2_agent: add parameters for local IP and port to bind for RIC connection --- srsenb/enb.conf.example | 2 ++ srsenb/src/main.cc | 2 ++ srsgnb/hdr/stack/ric/e2_agent.h | 3 ++- srsgnb/src/stack/ric/e2_agent.cc | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 985e0fab5..45db00a7b 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -375,6 +375,8 @@ enable = false enable = true #ric_ip = 127.0.0.1 #ric_port = 36421 +#ric_bind_ip = 127.0.0.1 +#ric_bind_port = 36425 ##################################################################### # Expert configuration options diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 58ac1c9a1..c60bf6c1c 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -232,6 +232,8 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("e2_agent.enable", bpo::value(&args->e2_agent.enable)->default_value(false), "Enables the E2 agent") ("e2_agent.ric_ip", bpo::value(&args->e2_agent.ric_ip)->default_value("127.0.0.1"), "RIC IP address") ("e2_agent.ric_port", bpo::value(&args->e2_agent.ric_port)->default_value(36421), "RIC port") + ("e2_agent.ric_bind_ip", bpo::value(&args->e2_agent.ric_bind_ip)->default_value("127.0.0.1"), "Local IP address to bind for RIC connection") + ("e2_agent.ric_bind_port", bpo::value(&args->e2_agent.ric_bind_port)->default_value(36425), "Local port to bind for RIC connection") /* Expert section */ ("expert.metrics_period_secs", bpo::value(&args->general.metrics_period_secs)->default_value(1.0), "Periodicity for metrics in seconds.") diff --git a/srsgnb/hdr/stack/ric/e2_agent.h b/srsgnb/hdr/stack/ric/e2_agent.h index bbe89240a..70dee9fdd 100644 --- a/srsgnb/hdr/stack/ric/e2_agent.h +++ b/srsgnb/hdr/stack/ric/e2_agent.h @@ -21,7 +21,6 @@ #include "srsran/interfaces/e2_metrics_interface.h" #include "srsran/srsran.h" static const int e2ap_ppid = 70; -static const int e2ap_port = 36421; enum e2_msg_type_t { E2_SETUP_REQUEST, @@ -36,6 +35,8 @@ struct e2_agent_args_t { bool enable; std::string ric_ip; uint32_t ric_port; + std::string ric_bind_ip; + uint32_t ric_bind_port; }; namespace srsenb { diff --git a/srsgnb/src/stack/ric/e2_agent.cc b/srsgnb/src/stack/ric/e2_agent.cc index bb683efa2..7b81ac1b3 100644 --- a/srsgnb/src/stack/ric/e2_agent.cc +++ b/srsgnb/src/stack/ric/e2_agent.cc @@ -35,7 +35,7 @@ bool e2_agent::init(e2_agent_args_t args) } // Bind socket - if (not ric_socket.bind_addr("127.0.0.1", 36425)) { + if (not ric_socket.bind_addr(args.ric_bind_ip.c_str(), args.ric_bind_port)) { ric_socket.close(); return false; } From 346a814498ca46265830a553cedb7f58d9967663 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 5 Apr 2023 22:01:00 +0200 Subject: [PATCH 126/167] e2_agent: add e2 setup procedure that reconnects on failure --- lib/src/common/network_utils.cc | 2 +- srsenb/enb.conf.example | 10 ++ srsenb/src/main.cc | 2 + srsgnb/hdr/stack/ric/e2_agent.h | 48 +++++- srsgnb/src/stack/ric/e2_agent.cc | 282 +++++++++++++++++++++++++++---- srsgnb/src/stack/ric/e2ap.cc | 10 ++ 6 files changed, 319 insertions(+), 35 deletions(-) diff --git a/lib/src/common/network_utils.cc b/lib/src/common/network_utils.cc index b7c5c3b6d..3bf566556 100644 --- a/lib/src/common/network_utils.cc +++ b/lib/src/common/network_utils.cc @@ -225,7 +225,7 @@ bool sctp_subscribe_to_events(int fd) evnts.sctp_data_io_event = 1; evnts.sctp_shutdown_event = 1; evnts.sctp_address_event = 1; - if (setsockopt(fd, SOL_SOCKET, SCTP_EVENTS, &evnts, sizeof(evnts)) != 0) { + if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) != 0) { srslog::fetch_basic_logger(LOGSERVICE).error("Failed to subscribe to SCTP_SHUTDOWN event: %s", strerror(errno)); perror("Could not register socket to SCTP events\n"); close(fd); diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 45db00a7b..55f20045c 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -370,6 +370,14 @@ enable = false #auto_target_papr = 8 #ema_alpha = 0.0143 +# Expert configuration options +# +# ric_ip: IP address of the RIC controller +# ric_port: Port of the RIC controller +# ric_bind_ip: Local IP address to bind for RIC connection +# ric_bind_port: Local port to bind for RIC connection +# max_ric_setup_retries: Maximum amount of retries to setup the RIC connection. If this value is exceeded, an alarm is written to the log. -1 means infinity. +# ric_connect_timer: Connection Retry Timer for RIC connection (seconds) ##################################################################### [e2_agent] enable = true @@ -377,6 +385,8 @@ enable = true #ric_port = 36421 #ric_bind_ip = 127.0.0.1 #ric_bind_port = 36425 +#max_ric_setup_retries = -1 +#ric_connect_timer = 10 ##################################################################### # Expert configuration options diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index c60bf6c1c..441e0ae93 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -234,6 +234,8 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("e2_agent.ric_port", bpo::value(&args->e2_agent.ric_port)->default_value(36421), "RIC port") ("e2_agent.ric_bind_ip", bpo::value(&args->e2_agent.ric_bind_ip)->default_value("127.0.0.1"), "Local IP address to bind for RIC connection") ("e2_agent.ric_bind_port", bpo::value(&args->e2_agent.ric_bind_port)->default_value(36425), "Local port to bind for RIC connection") + ("e2_agent.max_ric_setup_retries", bpo::value(&args->e2_agent.max_ric_setup_retries)->default_value(-1), "Max RIC setup retries") + ("e2_agent.ric_connect_timer", bpo::value(&args->e2_agent.ric_connect_timer)->default_value(10), "Connection Retry Timer for RIC connection (seconds)") /* Expert section */ ("expert.metrics_period_secs", bpo::value(&args->general.metrics_period_secs)->default_value(1.0), "Periodicity for metrics in seconds.") diff --git a/srsgnb/hdr/stack/ric/e2_agent.h b/srsgnb/hdr/stack/ric/e2_agent.h index 70dee9fdd..3e22bdc58 100644 --- a/srsgnb/hdr/stack/ric/e2_agent.h +++ b/srsgnb/hdr/stack/ric/e2_agent.h @@ -16,10 +16,12 @@ #include "srsgnb/hdr/stack/ric/e2ap.h" #include "srsran/common/network_utils.h" +#include "srsran/common/stack_procedure.h" #include "srsran/common/task_scheduler.h" #include "srsran/common/threads.h" #include "srsran/interfaces/e2_metrics_interface.h" #include "srsran/srsran.h" + static const int e2ap_ppid = 70; enum e2_msg_type_t { @@ -37,6 +39,8 @@ struct e2_agent_args_t { uint32_t ric_port; std::string ric_bind_ip; uint32_t ric_bind_port; + int32_t max_ric_setup_retries; + uint32_t ric_connect_timer; }; namespace srsenb { @@ -51,6 +55,7 @@ public: void stop(); void run_thread(); void tic(); + bool is_ric_connected(); // Send messages to RIC bool send_sctp(srsran::unique_byte_buffer_t& buf); @@ -61,7 +66,8 @@ public: // Handle messages received from RIC bool - handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); + handle_ric_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); + bool handle_e2_rx_pdu(srsran::byte_buffer_t* pdu); bool handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg); bool handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& successful_outcome); bool handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome); @@ -76,16 +82,52 @@ public: bool handle_reset_request(reset_request_s& reset_request); private: + bool connect_ric(); + bool setup_e2(); + + e2_agent_args_t _args; srsran::task_scheduler task_sched; srsran::task_queue_handle ric_rece_task_queue; srsran::unique_socket ric_socket; srsran::socket_manager rx_sockets; srslog::basic_logger& logger; - struct sockaddr_in ric_addr = {}; // RIC address - bool running = false; + struct sockaddr_in ric_addr = {}; // RIC address + bool running = false; + bool ric_connected = false; + srsran::unique_timer ric_connect_timer; + srsran::unique_timer e2_setup_timeout; srsenb::e2_interface_metrics* gnb_metrics = nullptr; e2ap e2ap_; + + // procedures + class e2_setup_proc_t + { + public: + struct e2setupresult { + bool success = false; + enum class cause_t { timeout, failure } cause; + }; + struct e2connectresult { + bool success = false; + }; + + explicit e2_setup_proc_t(e2_agent* e2_agent_) : e2_agent_ptr(e2_agent_) {} + srsran::proc_outcome_t init(); + srsran::proc_outcome_t step() { return srsran::proc_outcome_t::yield; } + srsran::proc_outcome_t react(const e2connectresult& event); + srsran::proc_outcome_t react(const e2setupresult& event); + void then(const srsran::proc_state_t& result); + const char* name() const { return "RIC Connection"; } + uint16_t connect_count = 0; + + private: + srsran::proc_outcome_t start_ric_connection(); + + e2_agent* e2_agent_ptr = nullptr; + }; + + srsran::proc_t e2_setup_proc; }; } // namespace srsenb diff --git a/srsgnb/src/stack/ric/e2_agent.cc b/srsgnb/src/stack/ric/e2_agent.cc index 7b81ac1b3..f5b2502cc 100644 --- a/srsgnb/src/stack/ric/e2_agent.cc +++ b/srsgnb/src/stack/ric/e2_agent.cc @@ -12,74 +12,226 @@ #include "srsgnb/hdr/stack/ric/e2_agent.h" #include "srsran/asn1/e2ap.h" +#include "srsran/common/standard_streams.h" using namespace srsenb; + +/********************************************************* + * RIC Connection + *********************************************************/ + +srsran::proc_outcome_t e2_agent::e2_setup_proc_t::init() +{ + e2_agent_ptr->logger.info("Starting new RIC connection."); + connect_count++; + return start_ric_connection(); +} + +srsran::proc_outcome_t e2_agent::e2_setup_proc_t::start_ric_connection() +{ + if (not e2_agent_ptr->running) { + e2_agent_ptr->logger.info("E2 Agent is not running anymore."); + return srsran::proc_outcome_t::error; + } + if (e2_agent_ptr->ric_connected) { + e2_agent_ptr->logger.info("E2 Agent is already connected to RIC"); + return srsran::proc_outcome_t::success; + } + + auto connect_callback = [this]() { + bool connected = e2_agent_ptr->connect_ric(); + + auto notify_result = [this, connected]() { + e2_setup_proc_t::e2connectresult res; + res.success = connected; + e2_agent_ptr->e2_setup_proc.trigger(res); + }; + e2_agent_ptr->task_sched.notify_background_task_result(notify_result); + }; + srsran::get_background_workers().push_task(connect_callback); + e2_agent_ptr->logger.debug("Connection to RIC requested."); + + return srsran::proc_outcome_t::yield; +} + +srsran::proc_outcome_t e2_agent::e2_setup_proc_t::react(const srsenb::e2_agent::e2_setup_proc_t::e2connectresult& event) +{ + if (event.success) { + e2_agent_ptr->logger.info("Connected to RIC. Sending setup request."); + e2_agent_ptr->e2_setup_timeout.run(); + if (not e2_agent_ptr->setup_e2()) { + e2_agent_ptr->logger.error("E2 setup failed. Exiting..."); + srsran::console("E2 setup failed\n"); + e2_agent_ptr->running = false; + return srsran::proc_outcome_t::error; + } + e2_agent_ptr->logger.info("E2 setup request sent. Waiting for response."); + return srsran::proc_outcome_t::yield; + } + + e2_agent_ptr->logger.info("Could not connected to RIC. Aborting"); + return srsran::proc_outcome_t::error; +} + +srsran::proc_outcome_t e2_agent::e2_setup_proc_t::react(const srsenb::e2_agent::e2_setup_proc_t::e2setupresult& event) +{ + if (e2_agent_ptr->e2_setup_timeout.is_running()) { + e2_agent_ptr->e2_setup_timeout.stop(); + } + if (event.success) { + e2_agent_ptr->logger.info("E2 Setup procedure completed successfully"); + return srsran::proc_outcome_t::success; + } + e2_agent_ptr->logger.error("E2 Setup failed."); + srsran::console("E2 setup failed\n"); + return srsran::proc_outcome_t::error; +} + +void e2_agent::e2_setup_proc_t::then(const srsran::proc_state_t& result) +{ + if (result.is_error()) { + e2_agent_ptr->logger.info("Failed to initiate RIC connection. Attempting reconnection in %d seconds", + e2_agent_ptr->ric_connect_timer.duration() / 1000); + srsran::console("Failed to initiate RIC connection. Attempting reconnection in %d seconds\n", + e2_agent_ptr->ric_connect_timer.duration() / 1000); + e2_agent_ptr->rx_sockets.remove_socket(e2_agent_ptr->ric_socket.get_socket()); + e2_agent_ptr->ric_socket.close(); + e2_agent_ptr->logger.info("R2 Agent socket closed."); + e2_agent_ptr->ric_connect_timer.run(); + if (e2_agent_ptr->_args.max_ric_setup_retries > 0 && connect_count > e2_agent_ptr->_args.max_ric_setup_retries) { + srsran_terminate("Error connecting to RIC"); + } + // Try again with in 10 seconds + } else { + connect_count = 0; + } +} + +/********************************************************* + * E2 Agent class + *********************************************************/ + e2_agent::e2_agent(srslog::basic_logger& logger, e2_interface_metrics* _gnb_metrics) : - task_sched(), logger(logger), rx_sockets(), thread("E2_AGENT_THREAD"), e2ap_(logger, this, _gnb_metrics, &task_sched) + task_sched(), + logger(logger), + rx_sockets(), + thread("E2_AGENT_THREAD"), + e2ap_(logger, this, _gnb_metrics, &task_sched), + e2_setup_proc(this) { gnb_metrics = _gnb_metrics; + ric_rece_task_queue = task_sched.make_task_queue(); } bool e2_agent::init(e2_agent_args_t args) { - printf("E2_AGENT: Init\n"); + _args = args; + + // Setup RIC reconnection timer + ric_connect_timer = task_sched.get_unique_timer(); + auto ric_connect_run = [this](uint32_t tid) { + if (e2_setup_proc.is_busy()) { + logger.error("Failed to initiate RIC Setup procedure: procedure is busy."); + } + e2_setup_proc.launch(); + }; + ric_connect_timer.set(_args.ric_connect_timer * 1000, ric_connect_run); + // Setup timeout + e2_setup_timeout = task_sched.get_unique_timer(); + uint32_t ric_setup_timeout_val = 5000; + e2_setup_timeout.set(ric_setup_timeout_val, [this](uint32_t tid) { + e2_setup_proc_t::e2setupresult res; + res.success = false; + res.cause = e2_setup_proc_t::e2setupresult::cause_t::timeout; + e2_setup_proc.trigger(res); + }); + + start(0); + running = true; + // starting RIC connection + if (not e2_setup_proc.launch()) { + logger.error("Failed to initiate RIC Setup procedure: error launching procedure."); + } + + return SRSRAN_SUCCESS; +} + +void e2_agent::stop() +{ + running = false; + wait_thread_finish(); +} + +void e2_agent::tic() +{ + // get tick every 1ms to advance timers + task_sched.tic(); +} + +bool e2_agent::is_ric_connected() +{ + return ric_connected; +} + +bool e2_agent::connect_ric() +{ using namespace srsran::net_utils; + logger.info("Connecting to RIC %s:%d", _args.ric_ip.c_str(), _args.ric_port); // Open SCTP socket if (not ric_socket.open_socket(addr_family::ipv4, socket_type::seqpacket, protocol_type::SCTP)) { return false; } - printf("RIC SCTP socket opened. fd=%d\n", ric_socket.fd()); + + // Subscribe to shutdown events if (not ric_socket.sctp_subscribe_to_events()) { ric_socket.close(); return false; } + // Set SRTO_MAX + if (not ric_socket.sctp_set_rto_opts(6000)) { + return false; + } + + // Set SCTP init options + if (not ric_socket.sctp_set_init_msg_opts(3, 5000)) { + return false; + } + // Bind socket - if (not ric_socket.bind_addr(args.ric_bind_ip.c_str(), args.ric_bind_port)) { + if (not ric_socket.bind_addr(_args.ric_bind_ip.c_str(), _args.ric_bind_port)) { ric_socket.close(); return false; } + logger.info("SCTP socket opened. fd=%d", ric_socket.fd()); // Connect to the AMF address - if (not ric_socket.connect_to(args.ric_ip.c_str(), args.ric_port, &ric_addr)) { + if (not ric_socket.connect_to(_args.ric_ip.c_str(), _args.ric_port, &ric_addr)) { + ric_socket.close(); return false; } + logger.info("SCTP socket connected with RIC. fd=%d", ric_socket.fd()); + // Assign a handler to rx RIC packets - ric_rece_task_queue = task_sched.make_task_queue(); auto rx_callback = [this](srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags) { - handle_e2_rx_msg(std::move(pdu), from, sri, flags); + handle_ric_rx_msg(std::move(pdu), from, sri, flags); }; rx_sockets.add_socket_handler(ric_socket.fd(), srsran::make_sctp_sdu_handler(logger, ric_rece_task_queue, rx_callback)); - printf("SCTP socket connected with RIC. fd=%d \n", ric_socket.fd()); - running = true; - start(0); - return SRSRAN_SUCCESS; -} - -void e2_agent::stop() -{ - running = false; - wait_thread_finish(); + logger.info("SCTP socket connected established with RIC"); + return true; } -void e2_agent::tic() +bool e2_agent::setup_e2() { - // get tick every 1ms to advance timers - task_sched.tic(); + return send_e2_msg(E2_SETUP_REQUEST); } void e2_agent::run_thread() { - using namespace asn1::e2ap; - while (running) { - if (e2ap_.send_setup_request()) { - send_e2_msg(E2_SETUP_REQUEST); - printf("e2 setup request sent\n"); - } task_sched.run_next_task(); } } @@ -132,6 +284,11 @@ bool e2_agent::send_e2_msg(e2_msg_type_t msg_type) bool e2_agent::queue_send_e2ap_pdu(e2_ap_pdu_c e2ap_pdu) { + if (not ric_connected) { + logger.error("Aborting sending msg. Cause: RIC is not connected."); + return false; + } + auto send_e2ap_pdu_task = [this, e2ap_pdu]() { send_e2ap_pdu(e2ap_pdu); }; ric_rece_task_queue.push(send_e2ap_pdu_task); return true; @@ -158,12 +315,66 @@ bool e2_agent::send_e2ap_pdu(e2_ap_pdu_c send_pdu) return true; } -bool e2_agent::handle_e2_rx_msg(srsran::unique_byte_buffer_t pdu, - const sockaddr_in& from, - const sctp_sndrcvinfo& sri, - int flags) +bool e2_agent::handle_ric_rx_msg(srsran::unique_byte_buffer_t pdu, + const sockaddr_in& from, + const sctp_sndrcvinfo& sri, + int flags) +{ + // Handle Notification Case + if (flags & MSG_NOTIFICATION) { + // Received notification + union sctp_notification* notification = (union sctp_notification*)pdu->msg; + logger.info("SCTP Notification %04x", notification->sn_header.sn_type); + bool restart_e2 = false; + if (notification->sn_header.sn_type == SCTP_SHUTDOWN_EVENT) { + logger.info("SCTP Association Shutdown. Association: %d", sri.sinfo_assoc_id); + srsran::console("SCTP Association Shutdown. Association: %d\n", sri.sinfo_assoc_id); + restart_e2 = true; + } else if (notification->sn_header.sn_type == SCTP_PEER_ADDR_CHANGE && + notification->sn_paddr_change.spc_state == SCTP_ADDR_UNREACHABLE) { + logger.info("SCTP peer addres unreachable. Association: %d", sri.sinfo_assoc_id); + srsran::console("SCTP peer address unreachable. Association: %d\n", sri.sinfo_assoc_id); + restart_e2 = true; + } else if (notification->sn_header.sn_type == SCTP_REMOTE_ERROR) { + logger.info("SCTP remote error. Association: %d", sri.sinfo_assoc_id); + srsran::console("SCTP remote error. Association: %d\n", sri.sinfo_assoc_id); + restart_e2 = true; + } else if (notification->sn_header.sn_type == SCTP_ASSOC_CHANGE) { + logger.info("SCTP association changed. Association: %d", sri.sinfo_assoc_id); + srsran::console("SCTP association changed. Association: %d\n", sri.sinfo_assoc_id); + } + if (restart_e2) { + logger.info("Restarting E2 connection"); + srsran::console("Restarting E2 connection\n"); + rx_sockets.remove_socket(ric_socket.get_socket()); + ric_socket.close(); + } + } else if (pdu->N_bytes == 0) { + logger.error("SCTP return 0 bytes. Closing socket"); + ric_socket.close(); + } + + // Restart RIC connection procedure if we lost connection + if (not ric_socket.is_open()) { + ric_connected = false; + if (e2_setup_proc.is_busy()) { + logger.error("Failed to initiate RIC connection procedure, as it is already running."); + return false; + } + e2_setup_proc.launch(); + return false; + } + + if ((flags & MSG_NOTIFICATION) == 0 && pdu->N_bytes != 0) { + handle_e2_rx_pdu(pdu.get()); + } + + return true; +} + +bool e2_agent::handle_e2_rx_pdu(srsran::byte_buffer_t* pdu) { - printf("E2_AGENT: Received %d bytes from %s\n", pdu->N_bytes, inet_ntoa(from.sin_addr)); + printf("E2_AGENT: Received %d bytes from RIC\n", pdu->N_bytes); e2_ap_pdu_c pdu_c; asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); if (pdu_c.unpack(bref) != asn1::SRSASN_SUCCESS) { @@ -248,8 +459,17 @@ bool e2_agent::handle_e2_setup_response(e2setup_resp_s setup_response) { if (e2ap_.process_setup_response(setup_response)) { logger.error("Failed to process E2 Setup Response \n"); + ric_connected = false; + e2_setup_proc_t::e2setupresult res; + res.success = false; + e2_setup_proc.trigger(res); return false; } + + ric_connected = true; + e2_setup_proc_t::e2setupresult res; + res.success = true; + e2_setup_proc.trigger(res); return true; } diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index ab34e43e3..b7ff88b1f 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -232,6 +232,11 @@ e2_ap_pdu_c e2ap::generate_subscription_modification_required() int e2ap::process_setup_response(e2setup_resp_s setup_response) { + if (setup_response->transaction_id.value.value == 0) { + // TODO: transaction_id reset? check specs + setup_procedure_transaction_id = 0; + } + if (setup_procedure_transaction_id == setup_response->transaction_id.value.value) { setup_procedure_transaction_id++; e2_established = true; @@ -403,6 +408,11 @@ int e2ap::get_reset_id() // implementation of e2ap failure functions int e2ap::process_e2_setup_failure(e2setup_fail_s e2setup_failure) { + if (e2setup_failure->transaction_id.value.value == 0) { + // TODO: transaction_id reset? check specs + setup_procedure_transaction_id = 0; + } + if (setup_procedure_transaction_id == e2setup_failure->transaction_id.value.value) { setup_procedure_transaction_id++; } else { From 9837997ce17fb6cb09e9c617ee7025e81e30d008 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 6 Apr 2023 10:18:19 +0200 Subject: [PATCH 127/167] e2_agent: fix enb config --- srsenb/enb.conf.example | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 55f20045c..51f7b5806 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -370,7 +370,7 @@ enable = false #auto_target_papr = 8 #ema_alpha = 0.0143 -# Expert configuration options +# E2 Agent configuration options # # ric_ip: IP address of the RIC controller # ric_port: Port of the RIC controller @@ -380,7 +380,7 @@ enable = false # ric_connect_timer: Connection Retry Timer for RIC connection (seconds) ##################################################################### [e2_agent] -enable = true +#enable = false #ric_ip = 127.0.0.1 #ric_port = 36421 #ric_bind_ip = 127.0.0.1 From 70b8d035ce7867aedf097d86120ee410cb26028c Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 6 Apr 2023 12:02:44 +0200 Subject: [PATCH 128/167] e2sm_kpm: fix func name --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 2 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 2 +- srsgnb/src/stack/ric/e2sm_kpm_report_service.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index 3abf3aa60..ba1d88d5b 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -59,7 +59,7 @@ private: bool _get_meas_definition(std::string meas_name, e2sm_kpm_metric_t& def); std::vector _get_supported_meas(uint32_t level_mask); - bool _collect_type_meas_value(e2sm_kpm_meas_def_t& meas_value, meas_record_item_c& item); + bool _collect_meas_value(e2sm_kpm_meas_def_t& meas_value, meas_record_item_c& item); bool _extract_integer_type_meas_value(e2sm_kpm_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, uint32_t& value); bool _extract_real_type_meas_value(e2sm_kpm_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, float& value); diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index b98b812f5..f9ab99b21 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -336,7 +336,7 @@ void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) logger.debug("e2sm_kpm received new enb metrics, CPU0 Load: %.1f", last_enb_metrics.sys.cpu_load[0]); } -bool e2sm_kpm::_collect_type_meas_value(e2sm_kpm_meas_def_t& meas_value, meas_record_item_c& item) +bool e2sm_kpm::_collect_meas_value(e2sm_kpm_meas_def_t& meas_value, meas_record_item_c& item) { // here we implement logic of measurement data collection, currently we only read from enb_metrics if (meas_value.data_type == meas_record_item_c::types::options::integer) { diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc index c66057127..2212ec61a 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -380,7 +380,7 @@ bool e2sm_kpm_report_service_style1::_collect_meas_data() meas_value.data_type = data_type; meas_record_item_c item; - if (not parent->_collect_type_meas_value(meas_value, item)) { + if (not parent->_collect_meas_value(meas_value, item)) { parent->logger.info("Cannot extract value \"%s\" label: %i", meas_name.c_str(), label); return false; } From 0860b2d0742bd28cb2c1438b6c5cc0cdd03028cd Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 12 Apr 2023 09:50:42 +0200 Subject: [PATCH 129/167] e2ap: check if task_shed_ptr was set --- srsgnb/src/stack/ric/e2ap.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc index b7ff88b1f..bc1ab83a2 100644 --- a/srsgnb/src/stack/ric/e2ap.cc +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -21,7 +21,9 @@ e2ap::e2ap(srslog::basic_logger& logger, logger(logger), _e2_agent(_e2_agent), e2sm_(logger, _task_sched_ptr), task_sched_ptr(_task_sched_ptr) { gnb_metrics = _gnb_metrics; - e2_procedure_timeout = task_sched_ptr->get_unique_timer(); + if (task_sched_ptr) { + e2_procedure_timeout = task_sched_ptr->get_unique_timer(); + } // register SM to receive enb metrics gnb_metrics->register_e2sm(&e2sm_); From 9735e5650f338e1b2a70a018b812d6279510bccf Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 12 Apr 2023 09:51:09 +0200 Subject: [PATCH 130/167] e2ap_test: update reference setup request msg --- srsgnb/src/stack/ric/test/e2ap_test.cc | 74 ++++---------------------- 1 file changed, 10 insertions(+), 64 deletions(-) diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc index 3aa9982e1..89d5aa1d2 100644 --- a/srsgnb/src/stack/ric/test/e2ap_test.cc +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -27,69 +27,15 @@ class dummy_metrics_interface : public srsenb::e2_interface_metrics void test_reference_e2ap_setup_request() { uint8_t e2ap_msg_foreign[] = { - 0x00, 0x01, 0x00, 0x82, 0x40, 0x00, 0x00, 0x04, 0x00, 0x31, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x09, 0x00, - 0x37, 0x34, 0x37, 0x38, 0xb5, 0xc6, 0x77, 0x88, 0x00, 0x0a, 0x00, 0x81, 0xff, 0x00, 0x00, 0x08, 0x00, 0x81, 0xf9, - 0x00, 0x00, 0x00, 0x81, 0xe9, 0x20, 0xc0, 0x4f, 0x52, 0x41, 0x4e, 0x2d, 0x45, 0x32, 0x53, 0x4d, 0x2d, 0x4b, 0x50, - 0x4d, 0x00, 0x00, 0x05, 0x4f, 0x49, 0x44, 0x31, 0x32, 0x33, 0x05, 0x00, 0x4b, 0x50, 0x4d, 0x20, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x08, 0xdc, 0x2b, 0xda, 0xe3, 0xae, 0xd1, 0x4d, 0x00, 0x60, 0x00, 0x01, 0x01, 0x07, 0x00, - 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x01, 0x05, 0x14, 0x01, - 0x01, 0x1d, 0x00, 0x4f, 0x2d, 0x44, 0x55, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x35, 0x47, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x1d, 0x00, 0x4f, 0x2d, 0x44, 0x55, 0x20, - 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x01, 0x03, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x43, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, - 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, - 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x35, 0x47, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x04, 0x1e, - 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x43, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, - 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x05, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, - 0x2d, 0x55, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x35, 0x47, 0x43, 0x20, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, - 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x06, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x55, 0x50, 0x20, 0x4d, - 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x02, 0x00, 0x00, 0x05, 0x4f, 0x49, 0x44, 0x31, 0x32, 0x33, 0x00, 0x32, 0x00, 0x22, 0x00, 0x00, 0x00, 0x33, - 0x00, 0x1c, 0x00, 0x00, 0xe0, 0x6e, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x00, 0x07, 0x72, 0x65, 0x71, 0x70, - 0x61, 0x72, 0x74, 0x07, 0x72, 0x65, 0x73, 0x70, 0x61, 0x72, 0x74}; - uint8_t e2ap_msg_self[] = { - 0x00, 0x01, 0x00, 0x82, 0x3c, 0x00, 0x00, 0x04, 0x00, 0x31, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x09, 0x00, - 0x37, 0x34, 0x37, 0x38, 0xb5, 0xc6, 0x77, 0x88, 0x00, 0x0a, 0x00, 0x81, 0xfa, 0x00, 0x00, 0x08, 0x00, 0x81, 0xf4, - 0x00, 0x00, 0x00, 0x81, 0xe9, 0x20, 0xc0, 0x4f, 0x52, 0x41, 0x4e, 0x2d, 0x45, 0x32, 0x53, 0x4d, 0x2d, 0x4b, 0x50, - 0x4d, 0x00, 0x00, 0x05, 0x4f, 0x49, 0x44, 0x31, 0x32, 0x33, 0x05, 0x00, 0x4b, 0x50, 0x4d, 0x20, 0x6d, 0x6f, 0x6e, - 0x69, 0x74, 0x6f, 0x72, 0x08, 0x60, 0x28, 0x38, 0x61, 0xaa, 0xe3, 0x3f, 0x00, 0x60, 0x00, 0x01, 0x01, 0x07, 0x00, - 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x69, 0x63, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x01, 0x05, 0x14, 0x01, - 0x01, 0x1d, 0x00, 0x4f, 0x2d, 0x44, 0x55, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x35, 0x47, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x1d, 0x00, 0x4f, 0x2d, 0x44, 0x55, 0x20, - 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x01, 0x03, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x43, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, - 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, - 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x35, 0x47, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, - 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x04, 0x1e, - 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x43, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, - 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x05, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, - 0x2d, 0x55, 0x50, 0x20, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x35, 0x47, 0x43, 0x20, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, - 0x74, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x06, 0x1e, 0x80, 0x4f, 0x2d, 0x43, 0x55, 0x2d, 0x55, 0x50, 0x20, 0x4d, - 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x45, 0x50, 0x43, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x23, 0x00, 0x00, 0x00, 0x33, 0x00, 0x1d, 0x00, 0x00, 0x03, - 0x80, 0x6e, 0x67, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x00, 0x07, 0x72, 0x65, 0x71, 0x70, 0x61, 0x72, 0x74, 0x07, - 0x72, 0x65, 0x73, 0x70, 0x61, 0x72, 0x74}; + 0x00, 0x01, 0x00, 0x80, 0xa3, 0x00, 0x00, 0x04, 0x00, 0x31, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x09, 0x00, + 0x05, 0xf5, 0x10, 0x30, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x53, 0x00, 0x00, 0x08, 0x00, 0x4e, 0x00, 0x00, + 0x93, 0x38, 0x00, 0x30, 0x4f, 0x52, 0x41, 0x4e, 0x2d, 0x45, 0x32, 0x53, 0x4d, 0x2d, 0x4b, 0x50, 0x4d, 0x00, 0x00, + 0x18, 0x31, 0x2e, 0x33, 0x2e, 0x36, 0x2e, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e, 0x35, 0x33, 0x31, 0x34, 0x38, 0x2e, + 0x31, 0x2e, 0x32, 0x2e, 0x32, 0x2e, 0x32, 0x05, 0x00, 0x4b, 0x50, 0x4d, 0x20, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x4f, 0x52, 0x41, 0x4e, 0x2d, 0x45, 0x32, 0x53, 0x4d, 0x2d, 0x4b, 0x50, 0x4d, + 0x00, 0x32, 0x00, 0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x2c, 0x00, 0x01, 0x80, 0x44, 0x55, 0x4d, 0x4d, 0x59, 0x20, + 0x4f, 0x41, 0x49, 0x2d, 0x41, 0x4d, 0x46, 0x00, 0x0c, 0x46, 0x41, 0x4b, 0x45, 0x20, 0x52, 0x45, 0x51, 0x55, 0x45, + 0x53, 0x54, 0x0d, 0x46, 0x41, 0x4b, 0x45, 0x20, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45}; asn1::cbit_ref bref(&e2ap_msg_foreign[0], sizeof(e2ap_msg_foreign)); e2_ap_pdu_c pdu; @@ -190,7 +136,7 @@ void test_native_e2ap_reset_request() return; } - asn1::cbit_ref bref2(buf->msg, buf->get_tailroom()); + asn1::cbit_ref bref2(buf->msg, buf->get_tailroom()); asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2); TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); printf("Unpacked native E2AP PDU RESET %d\n", (int)unpack_ret); From ab4bc8fdea79b6ffe5a6f24869b05d032b896e12 Mon Sep 17 00:00:00 2001 From: yagoda Date: Fri, 14 Apr 2023 10:07:02 +0200 Subject: [PATCH 131/167] e2,metrics: adding override flag to e2_metrics functions --- srsenb/hdr/metrics_e2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/hdr/metrics_e2.h b/srsenb/hdr/metrics_e2.h index b6d1d1fbe..23f198e24 100644 --- a/srsenb/hdr/metrics_e2.h +++ b/srsenb/hdr/metrics_e2.h @@ -32,9 +32,9 @@ class metrics_e2 : public srsran::metrics_listener, public e2_int { public: metrics_e2(enb_metrics_interface* enb_) : do_print(false) {} - void set_metrics(const enb_metrics_t& m, const uint32_t period_usec); + void set_metrics(const enb_metrics_t& m, const uint32_t period_usec) override; bool pull_metrics(enb_metrics_t* m) override; - void stop(){}; + void stop() override{}; bool register_e2sm(e2sm* sm) override; bool unregister_e2sm(e2sm* sm) override; From d8cfc1b12788752cf2235743ff65247df7586bf1 Mon Sep 17 00:00:00 2001 From: yagoda Date: Mon, 17 Apr 2023 11:06:53 +0200 Subject: [PATCH 132/167] e2ap,metrics: removing unused variable from e2 metrics --- srsenb/hdr/metrics_e2.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/srsenb/hdr/metrics_e2.h b/srsenb/hdr/metrics_e2.h index 23f198e24..affbfd782 100644 --- a/srsenb/hdr/metrics_e2.h +++ b/srsenb/hdr/metrics_e2.h @@ -40,8 +40,7 @@ public: bool unregister_e2sm(e2sm* sm) override; private: - std::atomic do_print = {false}; - uint8_t n_reports = 0; + std::atomic do_print = {false}; std::queue metrics_queue; enb_metrics_interface* enb = nullptr; std::vector e2sm_vec; From 3abf9f8e0b4d8cbde607316e10d604b3678dfa6e Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 12 Jan 2023 12:39:45 +0000 Subject: [PATCH 133/167] Fix for Pluto AD9363 sample rate delta --- lib/examples/npdsch_enodeb.c | 66 ++++++++++++++++++++++-------------- lib/examples/pdsch_enodeb.c | 9 +++-- lib/examples/pdsch_ue.c | 12 ++++--- lib/examples/pssch_ue.c | 9 +++-- 4 files changed, 59 insertions(+), 37 deletions(-) diff --git a/lib/examples/npdsch_enodeb.c b/lib/examples/npdsch_enodeb.c index 89867b21c..283fb56a9 100644 --- a/lib/examples/npdsch_enodeb.c +++ b/lib/examples/npdsch_enodeb.c @@ -35,6 +35,9 @@ #define HAVE_NPDSCH 1 #define NPDCCH_SF_IDX 1 +#define NOF_TX_ANT 1 + +#define MAX_SRATE_DELTA 2 // allowable delta (in Hz) between requested and actual sample rate static const uint8_t dummy_sib1_payload[] = {0x43, 0x4d, 0xd0, 0x92, 0x22, 0x06, 0x04, 0x30, 0x28, 0x6e, 0x87, 0xd0, 0x4b, 0x13, 0x90, 0xb4, 0x12, 0xa1, @@ -65,6 +68,7 @@ static uint32_t i_rep_val = 0; static char* rf_args = ""; static float rf_amp = 0.8, rf_gain = 70.0, rf_freq = 0; static float file_snr = -100.0; +static char* rf_dev = ""; static bool null_file_sink = false; static srsran_random_t* random_gen; @@ -83,22 +87,23 @@ static srsran_ra_nbiot_dl_dci_t ra_dl; static srsran_ra_nbiot_dl_dci_t ra_dl_sib1; static srsran_chest_dl_nbiot_t ch_est; static srsran_mib_nb_t mib_nb; -static uint32_t sched_info_tag = - 0; // according to Table 16.4.1.3-3 in 36.213, 0 means 4 NPDSCH repetitions with TBS 208 +static uint32_t sched_info_tag = 0; + // according to Table 16.4.1.3-3 in 36.213, 0 means 4 NPDSCH repetitions with TBS 208 static cf_t *sf_buffer = NULL, *output_buffer = NULL; static int sf_n_re = 0, sf_n_samples = 0; void usage(char* prog) { - printf("Usage: %s [agmiftlReosncvrpu]\n", prog); + printf("Usage: %s [aeOgfostmirnlRpv]\n", prog); #ifndef DISABLE_RF printf("\t-a RF args [Default %s]\n", rf_args); printf("\t-e RF amplitude [Default %.2f]\n", rf_amp); + printf("\t-O RF device [Default use RF board]\n"); printf("\t-g RF TX gain [Default %.2f dB]\n", rf_gain); printf("\t-f RF TX frequency [Default %.1f MHz]\n", rf_freq / 1000000); #else - printf("\t RF is disabled.\n"); + printf("\t RF is disabled!\n"); #endif printf("\t-o output_file [Default use RF board]\n"); printf("\t-s SNR-10 (only if output to file) [Default %f]\n", file_snr); @@ -116,7 +121,7 @@ void usage(char* prog) void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "aglfmiosncrtvpuR")) != -1) { + while ((opt = getopt(argc, argv, "aeOgfostmirnlRpv")) != -1) { switch (opt) { case 'a': rf_args = argv[optind]; @@ -127,6 +132,9 @@ void parse_args(int argc, char** argv) case 'e': rf_amp = strtof(argv[optind], NULL); break; + case 'O': + rf_dev = argv[optind]; + break; case 'f': rf_freq = strtof(argv[optind], NULL); break; @@ -139,12 +147,12 @@ void parse_args(int argc, char** argv) case 't': sched_info_tag = (uint32_t)strtol(argv[optind], NULL, 10); break; - case 'm': - i_tbs_val = (uint32_t)strtol(argv[optind], NULL, 10); - break; case 'i': i_sf_val = (uint32_t)strtol(argv[optind], NULL, 10); break; + case 'm': + i_tbs_val = (uint32_t)strtol(argv[optind], NULL, 10); + break; case 'r': i_rep_val = (uint32_t)strtol(argv[optind], NULL, 10); break; @@ -171,7 +179,7 @@ void parse_args(int argc, char** argv) if (!output_file_name && rf_freq == 0) { usage(argv[0]); - printf("\nError! Either RF frequency or output filename need to be specified.\n"); + printf("\nError: either RF frequency or output filename needs to be specified\n"); exit(-1); } @@ -188,12 +196,12 @@ void base_init() // init memory sf_buffer = srsran_vec_cf_malloc(sf_n_re); if (!sf_buffer) { - perror("malloc"); + perror("Error: malloc for sf_buffer"); exit(-1); } output_buffer = srsran_vec_cf_malloc(sf_n_samples); if (!output_buffer) { - perror("malloc"); + perror("Error: malloc for output buffer"); exit(-1); } // open file or USRP @@ -209,13 +217,17 @@ void base_init() } } else { #ifndef DISABLE_RF - printf("Opening RF device...\n"); - if (srsran_rf_open(&radio, rf_args)) { - fprintf(stderr, "Error opening rf\n"); - exit(-1); + if (strlen(rf_dev) > 0) { + if (srsran_rf_open_devname(&radio, rf_dev, rf_args, NOF_TX_ANT)) { + fprintf(stderr, "Error opening RF device %s\n", rf_dev); + exit(-1); + } + } else if (srsran_rf_open(&radio, rf_args)) { + fprintf(stderr, "Error opening RF default device\n"); + exit(-1); } #else - printf("Error RF not available. Select an output file\n"); + printf("Error: RF not available - select an output file\n"); exit(-1); #endif } @@ -346,7 +358,7 @@ static int update_radl(void) srsran_ra_nbiot_dl_dci_to_grant(&ra_dl, &dummy_grant, DUMMY_SFN, DUMMY_SFIDX, DUMMY_R_MAX, false, cell.mode); srsran_ra_nbiot_dl_grant_to_nbits(&dummy_grant, cell, 0, &dummy_nbits); srsran_ra_nbiot_dl_grant_fprint(stdout, &dummy_grant); - printf("Type new MCS index and press Enter: "); + printf("Enter new MCS index: "); fflush(stdout); return SRSRAN_SUCCESS; @@ -373,7 +385,7 @@ static int update_control(void) i_tbs_val = atoi(input); bzero(input, sizeof(input)); if (update_radl()) { - printf("Trying with last known MCS index\n"); + printf("Trying last known MCS index\n"); i_tbs_val = last_i_tbs_val; return update_radl(); } @@ -381,7 +393,7 @@ static int update_control(void) return 0; } else if (n < 0) { // error - perror("select"); + perror("Error: select for MCS entry"); return -1; } else { return 0; @@ -450,7 +462,7 @@ int main(int argc, char** argv) } if (srsran_nbiot_ue_dl_set_cell(&ue_dl, cell)) { - fprintf(stderr, "Setting cell in UE DL\n"); + fprintf(stderr, "Error setting cell in UE DL\n"); return -1; } @@ -489,16 +501,17 @@ int main(int argc, char** argv) signal(SIGINT, sig_int_handler); if (!output_file_name) { + /* set sampling frequency */ int srate = srsran_sampling_freq_hz(cell.base.nof_prb); if (srate != -1) { - printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); + printf("Setting tx sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_tx_srate(&radio, (double)srate); - if (srate_rf != srate) { - fprintf(stderr, "Could not set sampling rate\n"); + if (abs(srate - srate_rf) > MAX_SRATE_DELTA) { + ERROR("Could not set tx sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } } else { - fprintf(stderr, "Invalid number of PRB %d\n", cell.base.nof_prb); + fprintf(stderr, "Error: invalid number of PRB %d\n", cell.base.nof_prb); exit(-1); } srsran_rf_set_tx_gain(&radio, rf_gain); @@ -508,6 +521,7 @@ int main(int argc, char** argv) #endif if (update_radl()) { + fprintf(stderr, "Error updating radl\n"); exit(-1); } @@ -590,7 +604,7 @@ int main(int argc, char** argv) } if (srsran_nbiot_ue_dl_is_sib1_sf(&ue_dl, sfn, sf_idx)) { - INFO("%d.%d: Transmitting SIB1-NB.", sfn, sf_idx); + INFO("%d.%d: Transmitting SIB1-NB", sfn, sf_idx); assert(send_data == false); // configure DL grant for SIB1-NB transmission @@ -714,7 +728,7 @@ int main(int argc, char** argv) base_free(); - printf("Done\n"); + printf("%s done\n", argv[0]); return SRSRAN_SUCCESS; } diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index f53400959..46f89ee40 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -50,6 +50,8 @@ static char* output_file_name = NULL; #define CFR_THRES_STEP 0.05f #define CFR_PAPR_STEP 0.1f +#define MAX_SRATE_DELTA 2 // allowable delta (in Hz) between requested and actual sample rate + static srsran_cell_t cell = { 25, // nof_prb 1, // nof_ports @@ -956,12 +958,13 @@ int main(int argc, char** argv) signal(SIGINT, sig_int_handler); if (!output_file_name) { + /* set sampling frequency */ int srate = srsran_sampling_freq_hz(cell.nof_prb); if (srate != -1) { - printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); + printf("Setting tx sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_tx_srate(&radio, (double)srate); - if (srate_rf != srate) { - ERROR("Could not set sampling rate"); + if (abs(srate - srate_rf) > MAX_SRATE_DELTA) { + ERROR("Could not set tx sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } } else { diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index e304ac2fa..eaed11353 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -29,6 +29,8 @@ #define ENABLE_AGC_DEFAULT +#define MAX_SRATE_DELTA 2 // allowable delta (in Hz) between requested and actual sample rate + #ifndef DISABLE_RF #include "srsran/phy/rf/rf.h" @@ -475,7 +477,7 @@ int main(int argc, char** argv) signal(SIGINT, sig_int_handler); /* set receiver frequency */ - printf("Tunning receiver to %.3f MHz\n", (prog_args.rf_freq + prog_args.file_offset_freq) / 1000000); + printf("Tuning receiver to %.3f MHz\n", (prog_args.rf_freq + prog_args.file_offset_freq) / 1000000); srsran_rf_set_rx_freq(&rf, prog_args.rf_nof_rx_ant, prog_args.rf_freq + prog_args.file_offset_freq); uint32_t ntrial = 0; @@ -486,7 +488,7 @@ int main(int argc, char** argv) ERROR("Error searching for cell"); exit(-1); } else if (ret == 0 && !go_exit) { - printf("Cell not found after %d trials. Trying again (Press Ctrl+C to exit)\n", ntrial++); + printf("Cell not found after [%4d] attempts. Trying again... (Ctrl+C to exit)\n", ntrial++); } } while (ret == 0 && !go_exit); @@ -498,10 +500,10 @@ int main(int argc, char** argv) /* set sampling frequency */ int srate = srsran_sampling_freq_hz(cell.nof_prb); if (srate != -1) { - printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); + printf("Setting rx sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_rx_srate(&rf, (double)srate); - if (srate_rf != srate) { - ERROR("Could not set sampling rate"); + if (abs(srate - srate_rf) > MAX_SRATE_DELTA) { + ERROR("Could not set rx sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } } else { diff --git a/lib/examples/pssch_ue.c b/lib/examples/pssch_ue.c index e72e24a01..efddf66d4 100644 --- a/lib/examples/pssch_ue.c +++ b/lib/examples/pssch_ue.c @@ -34,6 +34,8 @@ #define PCAP_FILENAME "/tmp/pssch.pcap" +#define MAX_SRATE_DELTA 2 // allowable delta (in Hz) between requested and actual sample rate + static bool keep_running = true; static srsran_cell_sl_t cell_sl = {.nof_prb = 50, .tm = SRSRAN_SIDELINK_TM4, .cp = SRSRAN_CP_NORM, .N_sl_id = 0}; @@ -254,13 +256,14 @@ int main(int argc, char** argv) printf("Set RX freq: %.6f MHz\n", srsran_rf_set_rx_freq(&radio, prog_args.nof_rx_antennas, prog_args.rf_freq) / 1e6); printf("Set RX gain: %.1f dB\n", prog_args.rf_gain); - int srate = srsran_sampling_freq_hz(cell_sl.nof_prb); + /* set sampling frequency */ + int srate = srsran_sampling_freq_hz(cell_sl.nof_prb); if (srate != -1) { printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_rx_srate(&radio, (double)srate); - if (srate_rf != srate) { - ERROR("Could not set sampling rate"); + if (abs(srate - srate_rf) > MAX_SRATE_DELTA) { + ERROR("Could not set sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } } else { From c4d69677aa5f97e974fcc97bd3c20530d4634a79 Mon Sep 17 00:00:00 2001 From: ikercosta Date: Fri, 10 Mar 2023 15:48:23 +0100 Subject: [PATCH 134/167] FIX: Changed EPS bearer id validation --- lib/include/srsran/common/common_lte.h | 7 +++++++ srsenb/src/stack/upper/gtpu.cc | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/include/srsran/common/common_lte.h b/lib/include/srsran/common/common_lte.h index 5b1ee9cfa..44f324ec2 100644 --- a/lib/include/srsran/common/common_lte.h +++ b/lib/include/srsran/common/common_lte.h @@ -51,9 +51,16 @@ const uint32_t MAX_LTE_SRB_ID = 2; enum class lte_drb { drb1 = 1, drb2, drb3, drb4, drb5, drb6, drb7, drb8, drb9, drb10, drb11, invalid }; const uint32_t MAX_LTE_DRB_ID = 11; const uint32_t MAX_LTE_LCID = 10; // logicalChannelIdentity 3..10 in TS 36.331 v15.3 +const uint32_t MAX_EPS_BEARER_ID = 15; // EPS Bearer ID range [5, 15] in 36 413 +const uint32_t MIN_EPS_BEARER_ID = 5; const uint32_t INVALID_LCID = 99; // random invalid LCID const uint32_t INVALID_EPS_BEARER_ID = 99; // random invalid eps bearer id +constexpr bool is_eps_bearer_id(uint32_t eps_bearer_id) +{ + return eps_bearer_id >= MIN_EPS_BEARER_ID and eps_bearer_id <= MAX_EPS_BEARER_ID; +} + constexpr bool is_lte_rb(uint32_t lcid) { return lcid <= MAX_LTE_LCID; diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index bca2cf6b4..764e7c55b 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -57,7 +57,7 @@ gtpu_tunnel_manager::ue_bearer_tunnel_list* gtpu_tunnel_manager::find_rnti_tunne srsran::span gtpu_tunnel_manager::find_rnti_bearer_tunnels(uint16_t rnti, uint32_t eps_bearer_id) { - if (not is_lte_rb(eps_bearer_id)) { + if (not is_eps_bearer_id(eps_bearer_id)) { logger.warning("Searching for bearer with invalid eps-BearerID=%d", eps_bearer_id); return {}; } @@ -74,7 +74,7 @@ gtpu_tunnel_manager::find_rnti_bearer_tunnels(uint16_t rnti, uint32_t eps_bearer const gtpu_tunnel* gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t eps_bearer_id, uint32_t teidout, uint32_t spgw_addr) { - if (not is_lte_rb(eps_bearer_id)) { + if (not is_eps_bearer_id(eps_bearer_id)) { logger.warning("Adding TEID with invalid eps-BearerID=%d", eps_bearer_id); return nullptr; } From 3cafaec5a879e32e59b67296177dd6514d4fd6a4 Mon Sep 17 00:00:00 2001 From: Matan Perelman Date: Thu, 5 Jan 2023 14:19:36 +0200 Subject: [PATCH 135/167] enb,parser: Fix options formatting --- srsenb/hdr/parser.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/hdr/parser.h b/srsenb/hdr/parser.h index fb71ca7a3..46cb4ae25 100644 --- a/srsenb/hdr/parser.h +++ b/srsenb/hdr/parser.h @@ -443,11 +443,11 @@ int number_to_enum(EnumType& enum_val, Setting& root) ss << val; fprintf(stderr, "Invalid option: %s for enum field \"%s\"\n", ss.str().c_str(), root.getName()); ss.str(""); - ss << EnumType((typename EnumType::options)0).to_number(); + ss << std::to_string(EnumType((typename EnumType::options)0).to_number()); fprintf(stderr, "Valid options: %s", ss.str().c_str()); for (uint32_t i = 1; i < EnumType::nof_types; i++) { ss.str(""); - ss << EnumType((typename EnumType::options)i).to_number(); + ss << std::to_string(EnumType((typename EnumType::options)i).to_number()); fprintf(stderr, ", %s", ss.str().c_str()); } fprintf(stderr, "\n"); From 376b4f0011b9ae826c51568c23c34419887338e0 Mon Sep 17 00:00:00 2001 From: Ghislain Bourgeois Date: Thu, 26 Jan 2023 17:38:52 -0500 Subject: [PATCH 136/167] Enable specifying target architecture --- CMakeLists.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c0e53cddc..61ef69737 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,12 +95,14 @@ option(ENABLE_ALL_TEST "Enable all unit/component test" OFF) # (gcc-ar, gcc-nm, ...). option(BUILD_WITH_LTO "Enable LTO (experimental)" OFF) -if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") - set(GCC_ARCH armv8-a CACHE STRING "GCC compile for specific architecture.") - message(STATUS "Detected aarch64 processor") -else(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") - set(GCC_ARCH native CACHE STRING "GCC compile for specific architecture.") -endif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") +if(NOT GCC_ARCH) + if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + set(GCC_ARCH armv8-a CACHE STRING "GCC compile for specific architecture.") + message(STATUS "Detected aarch64 processor") + else(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + set(GCC_ARCH native CACHE STRING "GCC compile for specific architecture.") + endif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") +endif() # On RAM constrained (embedded) systems it may be useful to limit parallel compilation with, e.g. -DPARALLEL_COMPILE_JOBS=1 if (PARALLEL_COMPILE_JOBS) From 403c5d1cbe845df3812a6d6670979eea69b2d6e3 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 14 Apr 2023 19:36:23 +0200 Subject: [PATCH 137/167] examples: fix compile error when using float value for abs() ./lib/examples/npdsch_enodeb.c:509:11: error: using integer absolute value function 'abs' when argument is of floating point type [-Werror,-Wabsolute-value] if (abs(srate - srate_rf) > MAX_SRATE_DELTA) { --- lib/examples/npdsch_enodeb.c | 2 +- lib/examples/pdsch_enodeb.c | 2 +- lib/examples/pdsch_ue.c | 2 +- lib/examples/pssch_ue.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/examples/npdsch_enodeb.c b/lib/examples/npdsch_enodeb.c index 283fb56a9..c909e110b 100644 --- a/lib/examples/npdsch_enodeb.c +++ b/lib/examples/npdsch_enodeb.c @@ -506,7 +506,7 @@ int main(int argc, char** argv) if (srate != -1) { printf("Setting tx sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_tx_srate(&radio, (double)srate); - if (abs(srate - srate_rf) > MAX_SRATE_DELTA) { + if (abs(srate - (int)srate_rf) > MAX_SRATE_DELTA) { ERROR("Could not set tx sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index 46f89ee40..d39be21af 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -963,7 +963,7 @@ int main(int argc, char** argv) if (srate != -1) { printf("Setting tx sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_tx_srate(&radio, (double)srate); - if (abs(srate - srate_rf) > MAX_SRATE_DELTA) { + if (abs(srate - (int)srate_rf) > MAX_SRATE_DELTA) { ERROR("Could not set tx sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index eaed11353..117315141 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -502,7 +502,7 @@ int main(int argc, char** argv) if (srate != -1) { printf("Setting rx sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_rx_srate(&rf, (double)srate); - if (abs(srate - srate_rf) > MAX_SRATE_DELTA) { + if (abs(srate - (int)srate_rf) > MAX_SRATE_DELTA) { ERROR("Could not set rx sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } diff --git a/lib/examples/pssch_ue.c b/lib/examples/pssch_ue.c index efddf66d4..334430554 100644 --- a/lib/examples/pssch_ue.c +++ b/lib/examples/pssch_ue.c @@ -262,7 +262,7 @@ int main(int argc, char** argv) if (srate != -1) { printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_rx_srate(&radio, (double)srate); - if (abs(srate - srate_rf) > MAX_SRATE_DELTA) { + if (abs(srate - (int)srate_rf) > MAX_SRATE_DELTA) { ERROR("Could not set sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } From 5dc1356d5cab95c9d6aac9eedaadd0fd2d2904d3 Mon Sep 17 00:00:00 2001 From: JCDenton Date: Wed, 7 Dec 2022 03:57:01 +0300 Subject: [PATCH 138/167] Optimize inserts C++11 and code simplify --- lib/include/srsran/rlc/rlc.h | 1 - lib/src/rlc/rlc.cc | 6 +++--- srsepc/src/mme/mme_gtpc.cc | 4 ++-- srsepc/src/mme/s1ap.cc | 12 ++++++------ srsepc/src/spgw/gtpc.cc | 4 ++-- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/include/srsran/rlc/rlc.h b/lib/include/srsran/rlc/rlc.h index cfaa3b830..348901b1f 100644 --- a/lib/include/srsran/rlc/rlc.h +++ b/lib/include/srsran/rlc/rlc.h @@ -97,7 +97,6 @@ private: srsran::timer_handler* timers = nullptr; typedef std::map > rlc_map_t; - typedef std::pair > rlc_map_pair_t; rlc_map_t rlc_array, rlc_array_mrb; pthread_rwlock_t rwlock; diff --git a/lib/src/rlc/rlc.cc b/lib/src/rlc/rlc.cc index bbad52a52..f67302858 100644 --- a/lib/src/rlc/rlc.cc +++ b/lib/src/rlc/rlc.cc @@ -444,7 +444,7 @@ int rlc::add_bearer(uint32_t lcid, const rlc_config_t& cnfg) rlc_entity->set_bsr_callback(bsr_callback); - if (not rlc_array.insert(rlc_map_pair_t(lcid, std::move(rlc_entity))).second) { + if (not rlc_array.emplace(lcid, std::move(rlc_entity)).second) { logger.error("Error inserting RLC entity in to array."); return SRSRAN_ERROR; } @@ -467,7 +467,7 @@ int rlc::add_bearer_mrb(uint32_t lcid) } rlc_entity->set_bsr_callback(bsr_callback); if (rlc_array_mrb.count(lcid) == 0) { - if (not rlc_array_mrb.insert(rlc_map_pair_t(lcid, std::move(rlc_entity))).second) { + if (not rlc_array_mrb.emplace(lcid, std::move(rlc_entity)).second) { logger.error("Error inserting RLC entity in to array."); return SRSRAN_ERROR; } @@ -517,7 +517,7 @@ void rlc::change_lcid(uint32_t old_lcid, uint32_t new_lcid) // insert old rlc entity into new LCID rlc_map_t::iterator it = rlc_array.find(old_lcid); std::unique_ptr rlc_entity = std::move(it->second); - if (not rlc_array.insert(rlc_map_pair_t(new_lcid, std::move(rlc_entity))).second) { + if (not rlc_array.emplace(new_lcid, std::move(rlc_entity)).second) { logger.error("Error inserting RLC entity into array."); return; } diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index e5157f474..6f82b789a 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -174,13 +174,13 @@ bool mme_gtpc::send_create_session_request(uint64_t imsi) } // Save RX Control TEID - m_mme_ctr_teid_to_imsi.insert(std::pair(cs_req->sender_f_teid.teid, imsi)); + m_mme_ctr_teid_to_imsi.emplace(cs_req->sender_f_teid.teid, imsi); // Save GTP-C context gtpc_ctx_t gtpc_ctx; std::memset(>pc_ctx, 0, sizeof(gtpc_ctx_t)); gtpc_ctx.mme_ctr_fteid = cs_req->sender_f_teid; - m_imsi_to_gtpc_ctx.insert(std::pair(imsi, gtpc_ctx)); + m_imsi_to_gtpc_ctx.emplace(imsi, gtpc_ctx); // Send msg to SPGW send_s11_pdu(cs_req_pdu); diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 9917c6583..6462867b9 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -308,9 +308,9 @@ void s1ap::add_new_enb_ctx(const enb_ctx_t& enb_ctx, const struct sctp_sndrcvinf std::set ue_set; enb_ctx_t* enb_ptr = new enb_ctx_t; *enb_ptr = enb_ctx; - m_active_enbs.insert(std::pair(enb_ptr->enb_id, enb_ptr)); - m_sctp_to_enb_id.insert(std::pair(enb_sri->sinfo_assoc_id, enb_ptr->enb_id)); - m_enb_assoc_to_ue_ids.insert(std::pair >(enb_sri->sinfo_assoc_id, ue_set)); + m_active_enbs.emplace(enb_ptr->enb_id, enb_ptr); + m_sctp_to_enb_id.emplace(enb_sri->sinfo_assoc_id, enb_ptr->enb_id); + m_enb_assoc_to_ue_ids.emplace(enb_sri->sinfo_assoc_id, ue_set); } enb_ctx_t* s1ap::find_enb_ctx(uint16_t enb_id) @@ -362,7 +362,7 @@ bool s1ap::add_nas_ctx_to_imsi_map(nas* nas_ctx) return false; } } - m_imsi_to_nas_ctx.insert(std::pair(nas_ctx->m_emm_ctx.imsi, nas_ctx)); + m_imsi_to_nas_ctx.emplace(nas_ctx->m_emm_ctx.imsi, nas_ctx); m_logger.debug("Saved UE context corresponding to IMSI %015" PRIu64 "", nas_ctx->m_emm_ctx.imsi); return true; } @@ -385,7 +385,7 @@ bool s1ap::add_nas_ctx_to_mme_ue_s1ap_id_map(nas* nas_ctx) return false; } } - m_mme_ue_s1ap_id_to_nas_ctx.insert(std::pair(nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_ctx)); + m_mme_ue_s1ap_id_to_nas_ctx.emplace(nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_ctx); m_logger.debug("Saved UE context corresponding to MME UE S1AP Id %d", nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); return true; } @@ -551,7 +551,7 @@ uint32_t s1ap::allocate_m_tmsi(uint64_t imsi) uint32_t m_tmsi = m_next_m_tmsi; m_next_m_tmsi = (m_next_m_tmsi + 1) % UINT32_MAX; - m_tmsi_to_imsi.insert(std::pair(m_tmsi, imsi)); + m_tmsi_to_imsi.emplace(m_tmsi, imsi); m_logger.debug("Allocated M-TMSI 0x%x to IMSI %015" PRIu64 ",", m_tmsi, imsi); return m_tmsi; } diff --git a/srsepc/src/spgw/gtpc.cc b/srsepc/src/spgw/gtpc.cc index 9e3eac3b3..fbfc5a5bd 100644 --- a/srsepc/src/spgw/gtpc.cc +++ b/srsepc/src/spgw/gtpc.cc @@ -455,8 +455,8 @@ spgw_tunnel_ctx_t* spgw::gtpc::create_gtpc_ctx(const struct srsran::gtpc_create_ tunnel_ctx->dw_ctrl_fteid.ipv4 = cs_req.sender_f_teid.ipv4; std::memset(&tunnel_ctx->dw_user_fteid, 0, sizeof(srsran::gtp_fteid_t)); - m_teid_to_tunnel_ctx.insert(std::pair(spgw_uplink_ctrl_teid, tunnel_ctx)); - m_imsi_to_ctr_teid.insert(std::pair(cs_req.imsi, spgw_uplink_ctrl_teid)); + m_teid_to_tunnel_ctx.emplace(spgw_uplink_ctrl_teid, tunnel_ctx); + m_imsi_to_ctr_teid.emplace(cs_req.imsi, spgw_uplink_ctrl_teid); return tunnel_ctx; } From a60589b8ef55f47ce5548acdcdedbd41faee89ab Mon Sep 17 00:00:00 2001 From: Appleman4321 Date: Mon, 16 Jan 2023 14:33:14 +0300 Subject: [PATCH 139/167] Fixed duplicate code and comments --- lib/examples/pssch_ue.c | 3 +-- srsue/src/phy/phy.cc | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/examples/pssch_ue.c b/lib/examples/pssch_ue.c index 334430554..d0c70b689 100644 --- a/lib/examples/pssch_ue.c +++ b/lib/examples/pssch_ue.c @@ -58,13 +58,12 @@ typedef struct { void args_default(prog_args_t* args) { - args->disable_plots = false; args->use_standard_lte_rates = false; + args->disable_plots = false; args->input_file_name = NULL; args->file_start_sf_idx = 0; args->nof_rx_antennas = 1; args->rf_dev = ""; - args->rf_dev = ""; args->rf_args = ""; args->rf_freq = 5.92e9; args->rf_gain = 50; diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 9fca03a4c..4c64a5783 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -304,14 +304,14 @@ bool phy::cell_select(phy_cell_t cell) // Update PCI before starting the background command to make sure PRACH gets the updated value selected_cell.id = cell.pci; - // Update EARCN before starting the background task to make sure is taken into account when finding carriers to + // Update EARFCN before starting the background task to make sure is taken into account when finding carriers to // measure inter-frequency neighbours (see set_cells_to_meas) selected_earfcn = cell.earfcn; // Indicate workers that cell selection is in progress common.cell_is_selecting = true; - // Update EARCN before starting the background task to make sure is taken into account when finding carriers to + // Update EARFCN before starting the background task to make sure is taken into account when finding carriers to // measure inter-frequency neighbours (see set_cells_to_meas) selected_earfcn = cell.earfcn; From 3573bf9d7da979bd7d7205d28cb08b1a7e5f8011 Mon Sep 17 00:00:00 2001 From: Matan Perelman Date: Sun, 4 Dec 2022 09:16:23 +0200 Subject: [PATCH 140/167] epc: Fix typo --- srsepc/src/main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 43bfbfed3..8ce483996 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -202,7 +202,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) exit(1); } - // Concert hex strings + // Convert hex strings { std::stringstream sstr; sstr << std::hex << vm["mme.mme_group"].as(); From b7100efd848a2f12fc35f0b06882ce5dd2f5fd36 Mon Sep 17 00:00:00 2001 From: Matan Perelman Date: Sun, 4 Dec 2022 09:27:57 +0200 Subject: [PATCH 141/167] epc: Match lac and tac config with enb rr --- srsepc/src/main.cc | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index 8ce483996..7f4eaed66 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -215,16 +215,8 @@ void parse_args(all_args_t* args, int argc, char* argv[]) sstr >> tmp; args->mme_args.s1ap_args.mme_code = tmp; } - { - std::stringstream sstr; - sstr << std::hex << vm["mme.tac"].as(); - sstr >> args->mme_args.s1ap_args.tac; - } - { - std::stringstream sstr; - sstr << std::hex << vm["mme.lac"].as(); - sstr >> args->mme_args.s1ap_args.lac; - } + args->mme_args.s1ap_args.tac = std::stoi(vm["mme.tac"].as(), nullptr, 0); + args->mme_args.s1ap_args.lac = std::stoi(vm["mme.lac"].as(), nullptr, 0); // Convert MCC/MNC strings if (!srsran::string_to_mcc(mcc, &args->mme_args.s1ap_args.mcc)) { From 43fc466ff9d67a67052295f5b28a3b1c54cf314f Mon Sep 17 00:00:00 2001 From: b1u3s Date: Sun, 20 Nov 2022 23:39:59 +0800 Subject: [PATCH 142/167] liblte: add length on plmn list --- lib/src/asn1/liblte_mme.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/asn1/liblte_mme.cc b/lib/src/asn1/liblte_mme.cc index 48f3f9817..cfaab0f7d 100644 --- a/lib/src/asn1/liblte_mme.cc +++ b/lib/src/asn1/liblte_mme.cc @@ -612,6 +612,9 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_plmn_list_ie(uint8** ie_ptr, LIBLTE_MME_PLMN if (ie_ptr != NULL && plmn_list != NULL) { plmn_list->N_plmns = (*ie_ptr)[0] / 3; + if (plmn_list->N_plmns > LIBLTE_MME_PLMN_LIST_MAX_SIZE) { + return (err); + } for (i = 0; i < plmn_list->N_plmns; i++) { plmn_list->mcc[i] = ((*ie_ptr)[i * 3 + 0] & 0x0F) * 100; plmn_list->mcc[i] += (((*ie_ptr)[i * 3 + 0] >> 4) & 0x0F) * 10; @@ -3213,7 +3216,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_generic_message_container_ie(uint8** ie_ptr, msg->N_bytes |= (*ie_ptr)[1]; if (msg->N_bytes > LIBLTE_MAX_MSG_SIZE_BYTES) { - return err; + return (err); } for (i = 0; i < msg->N_bytes; i++) { From c74d4e1604c716f16e32c658ed749105c411014e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 17 Apr 2023 12:27:52 +0200 Subject: [PATCH 143/167] srsue: remove set_net_admin_caps.cc --- srsue/src/set_net_admin_caps.cc | 38 --------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 srsue/src/set_net_admin_caps.cc diff --git a/srsue/src/set_net_admin_caps.cc b/srsue/src/set_net_admin_caps.cc deleted file mode 100644 index 1a41f75bf..000000000 --- a/srsue/src/set_net_admin_caps.cc +++ /dev/null @@ -1,38 +0,0 @@ -/** - * - * \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 -#include -#include -#include -#include -#include - -using namespace std; - -int main(int argc, char* argv[]) -{ - if (argc != 2) { - std::cout << "Please call with the binary to provide net admin capabilities to as a parameter." << std::endl; - std::cout << "E.g. ./set_net_admin_caps myprogCalling " << std::endl; - return -1; - } - - std::string command("setcap 'cap_net_admin=eip' "); - command += argv[1]; - - std::cout << "Calling " << command << " with root rights." << std::endl; - setuid(0); - system(command.c_str()); - - return 0; -} From 33c43c96a77ee6fac59d2d5f949a773f386f5f07 Mon Sep 17 00:00:00 2001 From: Matan Perelman Date: Wed, 16 Nov 2022 14:09:07 +0200 Subject: [PATCH 144/167] srsenb: Add documentation for cell tx_gain --- srsenb/rr.conf.example | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/rr.conf.example b/srsenb/rr.conf.example index 78b2df154..54c1ba121 100644 --- a/srsenb/rr.conf.example +++ b/srsenb/rr.conf.example @@ -69,6 +69,7 @@ cell_list = // min_phr_thres = 0; // allowed_meas_bw = 6; // t304 = 2000; // in msec. possible values: 50, 100, 150, 200, 500, 1000, 2000 + // tx_gain = 20.0; // in dB. This gain is set by scaling the source signal. // CA cells scell_list = ( From 9a64958514665842c1b1af8a63b97efe42289f87 Mon Sep 17 00:00:00 2001 From: Patricio Latini Date: Sat, 26 Nov 2022 17:43:38 +0000 Subject: [PATCH 145/167] phy_common: add band 71 definition --- lib/include/srsran/phy/common/phy_common.h | 2 +- lib/src/phy/common/phy_common.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/include/srsran/phy/common/phy_common.h b/lib/include/srsran/phy/common/phy_common.h index dd4908529..6b8c755a4 100644 --- a/lib/include/srsran/phy/common/phy_common.h +++ b/lib/include/srsran/phy/common/phy_common.h @@ -162,7 +162,7 @@ typedef enum { SRSRAN_SF_NORM = 0, SRSRAN_SF_MBSFN } srsran_sf_t; #define SRSRAN_FDD_NOF_HARQ (FDD_HARQ_DELAY_DL_MS + FDD_HARQ_DELAY_UL_MS) #define SRSRAN_MAX_HARQ_PROC 15 -#define SRSRAN_NOF_LTE_BANDS 58 +#define SRSRAN_NOF_LTE_BANDS 59 #define SRSRAN_DEFAULT_MAX_FRAMES_PBCH 500 #define SRSRAN_DEFAULT_MAX_FRAMES_PSS 10 diff --git a/lib/src/phy/common/phy_common.c b/lib/src/phy/common/phy_common.c index 2abcb954f..ff49aa8ae 100644 --- a/lib/src/phy/common/phy_common.c +++ b/lib/src/phy/common/phy_common.c @@ -578,7 +578,8 @@ struct lte_band lte_bands[SRSRAN_NOF_LTE_BANDS] = { {68, 753, 67536, 132672, 55, SRSRAN_BAND_GEO_AREA_EMEA}, {69, 2570, 67836, 0, 0, SRSRAN_BAND_GEO_AREA_EMEA}, {70, 1995, 68336, 132972, 300, SRSRAN_BAND_GEO_AREA_NAR}, - {71, 0, 68586, 133122, 0, SRSRAN_BAND_GEO_AREA_NAR} // dummy band to bound band 70 earfcn + {71, 617, 68586, 133122, -46, SRSRAN_BAND_GEO_AREA_NAR}, + {72, 0, 68936, 133472, 0, SRSRAN_BAND_GEO_AREA_NAR} // dummy band to bound band 71 earfcn }; int srsran_str2mimotype(char* mimo_type_str, srsran_tx_scheme_t* type) From 4143e8f743f2852b60207d9b68ede08c78f6d451 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 4 Nov 2022 17:42:12 +0100 Subject: [PATCH 146/167] rrc: fetch old ue context when reestablishment corresponds to a UE performing S1 Handover --- srsenb/hdr/stack/rrc/rrc_mobility.h | 4 ++ srsenb/hdr/stack/rrc/rrc_ue.h | 3 ++ srsenb/src/stack/rrc/rrc_mobility.cc | 18 ++++++++- srsenb/src/stack/rrc/rrc_ue.cc | 59 +++++++++++++++++++++------- 4 files changed, 67 insertions(+), 17 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_mobility.h b/srsenb/hdr/stack/rrc/rrc_mobility.h index 4b706269c..8a26ee304 100644 --- a/srsenb/hdr/stack/rrc/rrc_mobility.h +++ b/srsenb/hdr/stack/rrc/rrc_mobility.h @@ -50,6 +50,8 @@ public: const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container, asn1::s1ap::cause_c& cause); + std::pair get_source_ue_rnti_and_pci(); + private: // helper methods bool update_ue_var_meas_cfg(uint32_t src_earfcn, @@ -109,6 +111,8 @@ private: struct s1_target_ho_st { asn1::s1ap::cause_c failure_cause; std::vector pending_tunnels; + uint16_t src_rnti; + uint32_t src_pci; }; struct wait_recfg_comp {}; struct s1_source_ho_st : public subfsm_t { diff --git a/srsenb/hdr/stack/rrc/rrc_ue.h b/srsenb/hdr/stack/rrc/rrc_ue.h index 8d1df7815..8cbcf0540 100644 --- a/srsenb/hdr/stack/rrc/rrc_ue.h +++ b/srsenb/hdr/stack/rrc/rrc_ue.h @@ -253,6 +253,9 @@ private: void apply_pdcp_srb_updates(const asn1::rrc::rr_cfg_ded_s& pending_rr_cfg); void apply_pdcp_drb_updates(const asn1::rrc::rr_cfg_ded_s& pending_rr_cfg); void apply_rlc_rb_updates(const asn1::rrc::rr_cfg_ded_s& pending_rr_cfg); + + /// Find UE whose Handover source identity matches the passed arguments. + ue* find_handover_source_ue(uint16_t old_rnti, uint32_t old_pci); }; // class ue } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index bdecc72eb..1d8bb1ba5 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -207,7 +207,8 @@ uint16_t rrc::start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& rrc::ue::rrc_mobility::rrc_mobility(rrc::ue* outer_ue) : base_t(outer_ue->parent->logger), rrc_ue(outer_ue), rrc_enb(outer_ue->parent), logger(outer_ue->parent->logger) -{} +{ +} //! Method to add Mobility Info to a RRC Connection Reconfiguration Message bool rrc::ue::rrc_mobility::fill_conn_recfg_no_ho_cmd(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg) @@ -584,7 +585,8 @@ bool rrc::ue::rrc_mobility::needs_intraenb_ho(idle_st& s, const ho_meas_report_e rrc::ue::rrc_mobility::s1_source_ho_st::s1_source_ho_st(rrc_mobility* parent_) : base_t(parent_), rrc_enb(parent_->rrc_enb), rrc_ue(parent_->rrc_ue), logger(parent_->logger) -{} +{ +} /** * TS 36.413, Section 8.4.6 - eNB Status Transfer @@ -854,6 +856,9 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& rrc_ue->mac_ctrl.handle_target_enb_ho_cmd(recfg_r8, rrc_ue->ue_capabilities); // Apply PHY updates rrc_ue->apply_reconf_phy_config(recfg_r8, true); + // Save source UE PCI and RNTI. + get_state()->src_rnti = hoprep_r8.as_cfg.source_ue_id.to_number(); + get_state()->src_pci = hoprep_r8.as_context.reest_info.source_pci; // Set admitted E-RABs std::vector admitted_erabs; @@ -1178,4 +1183,13 @@ void rrc::ue::rrc_mobility::handle_recfg_complete(intraenb_ho_st& s, const recfg logger.info("User rnti=0x%x successfully handovered to cell_id=0x%x", rrc_ue->rnti, s.target_cell->cell_cfg.cell_id); } +std::pair rrc::ue::rrc_mobility::get_source_ue_rnti_and_pci() +{ + if (not is_ho_running() or (not is_in_state() and not is_in_state())) { + return std::make_pair(SRSRAN_INVALID_RNTI, (uint32_t)0); + } + const s1_target_ho_st* st = get_state(); + return std::make_pair(st->src_rnti, st->src_pci); +} + } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 23907aa31..7403d536b 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -43,7 +43,8 @@ rrc::ue::ue(rrc* outer_rrc, uint16_t rnti_, const sched_interface::ue_cfg_t& sch bearer_list(rnti_, parent->cfg, outer_rrc->gtpu), ue_security_cfg(parent->cfg), mac_ctrl(rnti, ue_cell_list, bearer_list, parent->cfg, parent->mac, *parent->cell_common_list, sched_ue_cfg) -{} +{ +} rrc::ue::~ue() {} @@ -425,7 +426,8 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) std::string rrc::ue::to_string(const activity_timeout_type_t& type) { - constexpr static const char* options[] = {"Msg3 reception", "UE inactivity", "UE establishment", "UE reestablishment"}; + constexpr static const char* options[] = { + "Msg3 reception", "UE inactivity", "UE establishment", "UE reestablishment"}; return srsran::enum_to_text(options, (uint32_t)activity_timeout_type_t::nulltype, (uint32_t)type); } @@ -640,20 +642,29 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) return; } - uint16_t old_pci = msg->crit_exts.rrc_conn_reest_request_r8().ue_id.pci; - const enb_cell_common* old_cell = parent->cell_common_list->get_pci(old_pci); - auto old_ue_it = parent->users.find(old_rnti); - - // Reject unrecognized rntis, and PCIs that do not belong to eNB - if (old_ue_it == parent->users.end() or old_cell == nullptr or - old_ue_it->second->ue_cell_list.get_enb_cc_idx(old_cell->enb_cc_idx) == nullptr) { - send_connection_reest_rej(procedure_result_code::error_unknown_rnti); - parent->logger.info( - "RRCReestablishmentReject for rnti=0x%x. Cause: no rnti=0x%x context available", rnti, old_rnti); - srsran::console("RRCReestablishmentReject for rnti=0x%x. Cause: no context available\n", rnti); - return; + uint16_t old_pci = msg->crit_exts.rrc_conn_reest_request_r8().ue_id.pci; + ue* old_ue = nullptr; + { + const enb_cell_common* old_cell = parent->cell_common_list->get_pci(old_pci); + auto old_ue_it = parent->users.find(old_rnti); + + // Reject unrecognized rntis, and PCIs that do not belong to eNB + if (old_ue_it == parent->users.end() or old_cell == nullptr or + old_ue_it->second->ue_cell_list.get_enb_cc_idx(old_cell->enb_cc_idx) == nullptr) { + // Check if old UE context does not belong to an S1-Handover UE. + old_ue = find_handover_source_ue(old_rnti, old_pci); + if (old_ue == nullptr) { + send_connection_reest_rej(procedure_result_code::error_unknown_rnti); + parent->logger.info( + "RRCReestablishmentReject for rnti=0x%x. Cause: no rnti=0x%x context available", rnti, old_rnti); + srsran::console("RRCReestablishmentReject for rnti=0x%x. Cause: no context available\n", rnti); + return; + } + } else { + old_ue = old_ue_it->second.get(); + } } - ue* old_ue = old_ue_it->second.get(); + bool old_ue_supported_endc = old_ue->endc_handler and old_ue->endc_handler->is_endc_supported(); if (not old_ue_supported_endc and req_r8.reest_cause.value == reest_cause_opts::recfg_fail) { // Reestablishment Reject for ReconfigFailures of LTE-only mode @@ -1636,4 +1647,22 @@ int rrc::ue::get_ri(uint32_t m_ri, uint16_t* ri_idx) return ret; } +rrc::ue* rrc::ue::find_handover_source_ue(uint16_t old_rnti, uint32_t old_pci) +{ + for (auto& ue_pair : parent->users) { + rrc::ue& u = *ue_pair.second; + if (u.mobility_handler != nullptr and u.mobility_handler->is_ho_running()) { + std::pair src_ctxt = u.mobility_handler->get_source_ue_rnti_and_pci(); + if (src_ctxt.first == old_rnti and src_ctxt.second == old_pci) { + parent->logger.info("Found old UE Context RNTI=0x%x,PCI=%d used for Reestablishment. It corresponds to a UE " + "performing handover.", + old_rnti, + old_pci); + return &u; + } + } + } + return nullptr; +} + } // namespace srsenb From 4cc86455c3378854a014a4120b09af8f47fe47a9 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 31 Oct 2022 14:59:36 +0100 Subject: [PATCH 147/167] check if the UE supports used CA bands and UL CA --- lib/include/srsran/asn1/rrc_utils.h | 9 +- .../srsran/interfaces/rrc_interface_types.h | 2 + lib/src/asn1/rrc_utils.cc | 127 ++++++++++++++++-- srsenb/src/stack/rrc/rrc_mobility.cc | 2 +- srsenb/src/stack/rrc/rrc_ue.cc | 17 ++- srsenb/src/stack/rrc/ue_rr_cfg.cc | 28 ++-- 6 files changed, 162 insertions(+), 23 deletions(-) diff --git a/lib/include/srsran/asn1/rrc_utils.h b/lib/include/srsran/asn1/rrc_utils.h index de7832f5d..ecae50bda 100644 --- a/lib/include/srsran/asn1/rrc_utils.h +++ b/lib/include/srsran/asn1/rrc_utils.h @@ -71,6 +71,12 @@ struct ue_eutra_cap_s; } // namespace rrc } // namespace asn1 +namespace srsenb { + +struct ue_cell_ded; + +} // namespace srsenb + /************************ * Conversion Helpers ***********************/ @@ -130,7 +136,8 @@ int get_carrier_freq(const asn1::rrc::meas_obj_to_add_mod_s& obj); /*************************** * EUTRA UE Capabilities **************************/ -rrc_ue_capabilities_t make_rrc_ue_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_cap_s); +rrc_ue_capabilities_t make_rrc_ue_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_cap_s, + const srsenb::ue_cell_ded& pcell); // mbms mbms_notif_cfg_t make_mbms_notif_cfg(const asn1::rrc::mbms_notif_cfg_r9_s& asn1_type); diff --git a/lib/include/srsran/interfaces/rrc_interface_types.h b/lib/include/srsran/interfaces/rrc_interface_types.h index 2081a5589..aae1a5d3c 100644 --- a/lib/include/srsran/interfaces/rrc_interface_types.h +++ b/lib/include/srsran/interfaces/rrc_interface_types.h @@ -449,6 +449,8 @@ struct rrc_ue_capabilities_t { uint8_t category_ul = 0; bool support_dl_256qam = false; bool support_ul_64qam = false; + bool support_ca_bands = false; + bool support_ul_ca = false; }; } // namespace srsran diff --git a/lib/src/asn1/rrc_utils.cc b/lib/src/asn1/rrc_utils.cc index d54393057..8b688d070 100644 --- a/lib/src/asn1/rrc_utils.cc +++ b/lib/src/asn1/rrc_utils.cc @@ -11,6 +11,7 @@ */ #include "srsran/asn1/rrc_utils.h" +#include "srsenb/hdr/stack/rrc/rrc_cell_cfg.h" #include "srsran/asn1/obj_id_cmp_utils.h" #include "srsran/asn1/rrc.h" #include "srsran/config.h" @@ -923,36 +924,144 @@ int get_carrier_freq(const asn1::rrc::meas_obj_to_add_mod_s& obj) */ template -static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, const T& ue_eutra_cap) +static void +set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, const srsenb::ue_cell_ded& pcell, const T& ue_eutra_cap) { if (ue_eutra_cap.non_crit_ext_present) { - set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + set_rrc_ue_eutra_cap_t_gen(ue_cap, pcell, ue_eutra_cap.non_crit_ext); } } -static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, const asn1::rrc::ue_eutra_cap_s& ue_eutra_cap) +static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, + const srsenb::ue_cell_ded& pcell, + const asn1::rrc::ue_eutra_cap_s& ue_eutra_cap) { ue_cap.release = ue_eutra_cap.access_stratum_release.to_number(); ue_cap.category = ue_eutra_cap.ue_category; if (ue_eutra_cap.non_crit_ext_present) { - set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + set_rrc_ue_eutra_cap_t_gen(ue_cap, pcell, ue_eutra_cap.non_crit_ext); } } +bool is_ca_band_combo_supported(const band_combination_params_r10_l& enb_band_combo, + const band_combination_params_r10_l& ue_band_combo) +{ + if (enb_band_combo.size() != ue_band_combo.size()) { + return false; + } + + for (unsigned i = 0; i < enb_band_combo.size(); ++i) { + if (ue_band_combo[i].band_eutra_r10 != enb_band_combo[i].band_eutra_r10) { + return false; + } + } + + for (unsigned i = 0; i < enb_band_combo.size(); ++i) { + const auto& enb_band = enb_band_combo[i]; + const auto& ue_band = ue_band_combo[i]; + + if (enb_band.band_params_dl_r10_present and !ue_band.band_params_dl_r10_present) { + return false; + } + // for SCells this depends on the ul_allowed parameter + if (i == 0 and enb_band.band_params_ul_r10_present and !ue_band.band_params_ul_r10_present) { + return false; + } + + if (enb_band.band_params_dl_r10_present and ue_band.band_params_dl_r10_present) { + if (enb_band.band_params_dl_r10.size() != ue_band.band_params_dl_r10.size()) { + return false; + } + for (unsigned j = 0; j < enb_band.band_params_dl_r10.size(); ++j) { + if (enb_band.band_params_dl_r10[j].ca_bw_class_dl_r10 > ue_band.band_params_dl_r10[j].ca_bw_class_dl_r10) { + return false; + } + } + } + + if (enb_band.band_params_ul_r10_present and ue_band.band_params_ul_r10_present) { + if (enb_band.band_params_ul_r10.size() != ue_band.band_params_ul_r10.size()) { + return false; + } + for (unsigned j = 0; j < enb_band.band_params_ul_r10.size(); ++j) { + if (enb_band.band_params_ul_r10[j].ca_bw_class_ul_r10 > ue_band.band_params_ul_r10[j].ca_bw_class_ul_r10) { + return false; + } + } + } + } + return true; +} + +bool is_ul_ca_supported(const band_combination_params_r10_l& ue_band_combo) +{ + uint32_t ul_band_num = 0; + for (const auto& ue_band : ue_band_combo) { + if (ue_band.band_params_ul_r10_present) { + ul_band_num++; + } + } + return ul_band_num == ue_band_combo.size(); +} + static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, + const srsenb::ue_cell_ded& pcell, const asn1::rrc::ue_eutra_cap_v1020_ies_s& ue_eutra_cap) { if (ue_eutra_cap.ue_category_v1020_present) { ue_cap.category = ue_eutra_cap.ue_category_v1020; } + if (ue_eutra_cap.rf_params_v1020_present) { + const asn1::rrc::rf_params_v1020_s& rf_params = ue_eutra_cap.rf_params_v1020; + const srsenb::enb_cell_common* pcell_cfg = pcell.cell_common; + uint32_t cc_num = 1 + pcell_cfg->scells.size(); + band_combination_params_r10_l enb_band_combo; + + // TODO: add proper class (currently hardcoded class A) and mimo_cap checks + for (unsigned i = 0; i < cc_num; ++i) { + ca_mimo_params_dl_r10_s ca_mimo_params_dl; + ca_mimo_params_dl.ca_bw_class_dl_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_dl.supported_mimo_cap_dl_r10_present = false; + ca_mimo_params_dl.supported_mimo_cap_dl_r10 = mimo_cap_dl_r10_opts::nulltype; + + ca_mimo_params_ul_r10_s ca_mimo_params_ul; + ca_mimo_params_ul.ca_bw_class_ul_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_ul.supported_mimo_cap_ul_r10_present = false; + ca_mimo_params_ul.supported_mimo_cap_ul_r10 = mimo_cap_ul_r10_opts::nulltype; + + band_params_r10_s band_params; + uint32_t dl_earfcn = i == 0 ? pcell_cfg->cell_cfg.dl_earfcn : pcell_cfg->scells[i - 1]->cell_cfg.dl_earfcn; + band_params.band_eutra_r10 = (uint8_t)srsran_band_get_band(dl_earfcn); + band_params.band_params_dl_r10_present = true; + band_params.band_params_dl_r10.push_back(ca_mimo_params_dl); + + // PCell always supports UL, SCell depending on the config + if (i == 0 or (i >= 1 and pcell_cfg->cell_cfg.scell_list[i - 1].ul_allowed)) { + band_params.band_params_ul_r10_present = true; + band_params.band_params_ul_r10.push_back(ca_mimo_params_ul); + } + enb_band_combo.push_back(band_params); + } + + // compare the currently used CA band combo with band combos from UE + for (const auto& ue_band_combo : rf_params.supported_band_combination_r10) { + ue_cap.support_ca_bands |= is_ca_band_combo_supported(enb_band_combo, ue_band_combo); + if (ue_cap.support_ca_bands) { + ue_cap.support_ul_ca = is_ul_ca_supported(ue_band_combo); + break; + } + } + } + if (ue_eutra_cap.non_crit_ext_present) { - set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + set_rrc_ue_eutra_cap_t_gen(ue_cap, pcell, ue_eutra_cap.non_crit_ext); } } static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, + const srsenb::ue_cell_ded& pcell, const asn1::rrc::ue_eutra_cap_v1250_ies_s& ue_eutra_cap) { if (ue_eutra_cap.ue_category_dl_r12_present) { @@ -976,20 +1085,22 @@ static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& } if (ue_eutra_cap.non_crit_ext_present) { - set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + set_rrc_ue_eutra_cap_t_gen(ue_cap, pcell, ue_eutra_cap.non_crit_ext); } } static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, + const srsenb::ue_cell_ded& pcell, const asn1::rrc::ue_eutra_cap_v1530_ies_s& ue_eutra_cap) { ; // Do nothing } -rrc_ue_capabilities_t make_rrc_ue_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_cap_s) +rrc_ue_capabilities_t make_rrc_ue_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_cap_s, + const srsenb::ue_cell_ded& pcell) { rrc_ue_capabilities_t ue_cap; - set_rrc_ue_eutra_cap_t_gen(ue_cap, eutra_cap_s); + set_rrc_ue_eutra_cap_t_gen(ue_cap, pcell, eutra_cap_s); ue_cap.support_ul_64qam |= (ue_cap.category == 5) or (ue_cap.category == 8 and ue_cap.release >= 10); return ue_cap; } diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index 1d8bb1ba5..764297a8a 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -1002,7 +1002,7 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& rrc_ue->eutra_capabilities.to_json(js); logger.debug("New rnti=0x%x EUTRA capabilities: %s", rrc_ue->rnti, js.to_string().c_str()); } - rrc_ue->ue_capabilities = srsran::make_rrc_ue_capabilities(rrc_ue->eutra_capabilities); + rrc_ue->ue_capabilities = srsran::make_rrc_ue_capabilities(rrc_ue->eutra_capabilities, *target_cell); rrc_ue->eutra_capabilities_unpacked = true; } } diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 7403d536b..922b5e5a2 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -1060,6 +1060,7 @@ int rrc::ue::handle_ue_cap_info(ue_cap_info_s* msg) { parent->logger.info("UECapabilityInformation transaction ID: %d", msg->rrc_transaction_id); ue_cap_info_r8_ies_s* msg_r8 = &msg->crit_exts.c1().ue_cap_info_r8(); + const ue_cell_ded* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); for (uint32_t i = 0; i < msg_r8->ue_cap_rat_container_list.size(); i++) { if (msg_r8->ue_cap_rat_container_list[i].rat_type != rat_type_e::eutra) { @@ -1078,9 +1079,16 @@ int rrc::ue::handle_ue_cap_info(ue_cap_info_s* msg) parent->logger.debug("rnti=0x%x EUTRA capabilities: %s", rnti, js.to_string().c_str()); } eutra_capabilities_unpacked = true; - ue_capabilities = srsran::make_rrc_ue_capabilities(eutra_capabilities); + ue_capabilities = srsran::make_rrc_ue_capabilities(eutra_capabilities, *pcell); parent->logger.info("UE rnti: 0x%x category: %d", rnti, eutra_capabilities.ue_category); + if (ue_capabilities.support_ca_bands and ue_capabilities.support_ul_ca) { + parent->logger.info("UE rnti: 0x%x supports DL and UL CA with the used bands.", rnti); + } else if (ue_capabilities.support_ca_bands and not ue_capabilities.support_ul_ca) { + parent->logger.info("UE rnti: 0x%x supports DL CA with the used bands (no UL CA).", rnti); + } else { + parent->logger.info("UE rnti: 0x%x does not support CA with the used bands.", rnti); + } if (endc_handler != nullptr) { endc_handler->handle_eutra_capabilities(eutra_capabilities); @@ -1276,6 +1284,13 @@ void rrc::ue::update_scells() parent->logger.info("UE doesn't support CA. Skipping SCell activation"); return; } + if (not ue_capabilities.support_ca_bands) { + parent->logger.info("UE doesn't support used CA bands. Skipping SCell activation"); + return; + } + if (not ue_capabilities.support_ul_ca) { + parent->logger.info("UE supports only DL CA"); + } if (not eutra_capabilities.non_crit_ext_present or not eutra_capabilities.non_crit_ext.non_crit_ext_present or not eutra_capabilities.non_crit_ext.non_crit_ext.non_crit_ext_present or not eutra_capabilities.non_crit_ext.non_crit_ext.non_crit_ext.rf_params_v1020_present or diff --git a/srsenb/src/stack/rrc/ue_rr_cfg.cc b/srsenb/src/stack/rrc/ue_rr_cfg.cc index 0b9b1b616..856e613bd 100644 --- a/srsenb/src/stack/rrc/ue_rr_cfg.cc +++ b/srsenb/src/stack/rrc/ue_rr_cfg.cc @@ -447,18 +447,22 @@ void fill_scells_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, nonul_cfg.phich_cfg_r10 = scell_cfg.mib.phich_cfg; nonul_cfg.pdsch_cfg_common_r10 = cc_cfg_sib.pdsch_cfg_common; // RadioResourceConfigCommonSCell-r10::ul-Configuration-r10 - asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10_present = true; - auto& ul_cfg = asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10; - ul_cfg.ul_freq_info_r10.ul_carrier_freq_r10_present = true; - ul_cfg.ul_freq_info_r10.ul_carrier_freq_r10 = scell_cfg.cell_cfg.ul_earfcn; - ul_cfg.p_max_r10_present = cell_sib1.p_max_present; - ul_cfg.p_max_r10 = cell_sib1.p_max; - ul_cfg.ul_freq_info_r10.add_spec_emission_scell_r10 = 1; - ul_cfg.ul_pwr_ctrl_common_scell_r10.p0_nominal_pusch_r10 = cc_cfg_sib.ul_pwr_ctrl_common.p0_nominal_pusch; - ul_cfg.ul_pwr_ctrl_common_scell_r10.alpha_r10.value = cc_cfg_sib.ul_pwr_ctrl_common.alpha; - ul_cfg.srs_ul_cfg_common_r10 = cc_cfg_sib.srs_ul_cfg_common; - ul_cfg.ul_cp_len_r10.value = cc_cfg_sib.ul_cp_len.value; - ul_cfg.pusch_cfg_common_r10 = cc_cfg_sib.pusch_cfg_common; + if (ue_caps.support_ul_ca) { + asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10_present = true; + auto& ul_cfg = asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10; + ul_cfg.ul_freq_info_r10.ul_carrier_freq_r10_present = true; + ul_cfg.ul_freq_info_r10.ul_carrier_freq_r10 = scell_cfg.cell_cfg.ul_earfcn; + ul_cfg.p_max_r10_present = cell_sib1.p_max_present; + ul_cfg.p_max_r10 = cell_sib1.p_max; + ul_cfg.ul_freq_info_r10.add_spec_emission_scell_r10 = 1; + ul_cfg.ul_pwr_ctrl_common_scell_r10.p0_nominal_pusch_r10 = cc_cfg_sib.ul_pwr_ctrl_common.p0_nominal_pusch; + ul_cfg.ul_pwr_ctrl_common_scell_r10.alpha_r10.value = cc_cfg_sib.ul_pwr_ctrl_common.alpha; + ul_cfg.srs_ul_cfg_common_r10 = cc_cfg_sib.srs_ul_cfg_common; + ul_cfg.ul_cp_len_r10.value = cc_cfg_sib.ul_cp_len.value; + ul_cfg.pusch_cfg_common_r10 = cc_cfg_sib.pusch_cfg_common; + } else { + asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10_present = false; + } // RadioResourceConfigDedicatedSCell-r10 asn1cell.rr_cfg_ded_scell_r10_present = true; asn1cell.rr_cfg_ded_scell_r10.phys_cfg_ded_scell_r10_present = true; From 13d651763152b6752edb4f7440d9a1c928cce348 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 27 Oct 2022 15:53:33 +0200 Subject: [PATCH 148/167] prevent the scheduler from allocating data on SCell UL if not supported by UE --- lib/include/srsran/interfaces/enb_rrc_interface_types.h | 1 + srsenb/hdr/stack/mac/sched_interface.h | 1 + srsenb/src/enb_cfg_parser.cc | 4 ++++ srsenb/src/stack/mac/schedulers/sched_time_pf.cc | 5 ++++- srsenb/src/stack/mac/schedulers/sched_time_rr.cc | 4 ++++ srsenb/src/stack/rrc/mac_controller.cc | 7 ++++--- srsenb/src/stack/rrc/rrc_cell_cfg.cc | 6 ++++++ 7 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_rrc_interface_types.h b/lib/include/srsran/interfaces/enb_rrc_interface_types.h index 091241445..7165f3453 100644 --- a/lib/include/srsran/interfaces/enb_rrc_interface_types.h +++ b/lib/include/srsran/interfaces/enb_rrc_interface_types.h @@ -66,6 +66,7 @@ struct cell_cfg_t { asn1::rrc::mob_ctrl_info_s::t304_e_ t304; std::vector scell_list; rrc_meas_cfg_t meas_cfg; + bool barred; }; typedef std::vector cell_list_t; diff --git a/srsenb/hdr/stack/mac/sched_interface.h b/srsenb/hdr/stack/mac/sched_interface.h index 3a78b6497..f0e6fef82 100644 --- a/srsenb/hdr/stack/mac/sched_interface.h +++ b/srsenb/hdr/stack/mac/sched_interface.h @@ -140,6 +140,7 @@ public: struct ue_cfg_t { struct cc_cfg_t { bool active = false; + bool ul_disabled = false; uint32_t enb_cc_idx = 0; ///< eNB CC index srsran_dl_cfg_t dl_cfg = {}; uint32_t aperiodic_cqi_period = 0; // if 0 is periodic CQI diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 99c947d01..dea5dfc36 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1505,6 +1505,10 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) HANDLEPARSERCODE(parse_meas_report_desc(&cell_cfg.meas_cfg, cellroot)); } + if (cellroot.exists("barred") and cellroot["barred"]) { + cell_cfg.barred = true; + } + if (cellroot.exists("scell_list")) { HANDLEPARSERCODE(parse_scell_list(cell_cfg, cellroot)); } diff --git a/srsenb/src/stack/mac/schedulers/sched_time_pf.cc b/srsenb/src/stack/mac/schedulers/sched_time_pf.cc index 53de3621c..de1103f96 100644 --- a/srsenb/src/stack/mac/schedulers/sched_time_pf.cc +++ b/srsenb/src/stack/mac/schedulers/sched_time_pf.cc @@ -61,7 +61,10 @@ void sched_time_pf::new_tti(sched_ue_list& ue_db, sf_sched* tti_sched) dl_queue.push(&it->second); } if (it->second.ul_h != nullptr) { - ul_queue.push(&it->second); + // Allocate only if UL carrier is enabled + if (!u.second->get_ue_cfg().supported_cc_list[cc_cfg->enb_cc_idx].ul_disabled) { + ul_queue.push(&it->second); + } } } } diff --git a/srsenb/src/stack/mac/schedulers/sched_time_rr.cc b/srsenb/src/stack/mac/schedulers/sched_time_rr.cc index 3465c558e..6637b2630 100644 --- a/srsenb/src/stack/mac/schedulers/sched_time_rr.cc +++ b/srsenb/src/stack/mac/schedulers/sched_time_rr.cc @@ -121,6 +121,10 @@ void sched_time_rr::sched_ul_newtxs(sched_ue_list& ue_db, sf_sched* tti_sched, s iter = ue_db.begin(); // wrap around } sched_ue& user = *iter->second; + // Allocate only if UL carrier is enabled + if (user.get_ue_cfg().supported_cc_list[cc_cfg->enb_cc_idx].ul_disabled) { + continue; + } const ul_harq_proc* h = get_ul_newtx_harq(user, tti_sched); // Check if there is a empty harq if (h == nullptr) { diff --git a/srsenb/src/stack/rrc/mac_controller.cc b/srsenb/src/stack/rrc/mac_controller.cc index deb5cc6e4..503880ec0 100644 --- a/srsenb/src/stack/rrc/mac_controller.cc +++ b/srsenb/src/stack/rrc/mac_controller.cc @@ -457,9 +457,10 @@ void ue_cfg_apply_reconf_complete_updates(ue_cfg_t& ue_cfg, if (scell.scell_idx_r10 >= ue_cfg.supported_cc_list.size()) { ue_cfg.supported_cc_list.resize(scell.scell_idx_r10 + 1); } - auto& mac_scell = ue_cfg.supported_cc_list[scell.scell_idx_r10]; - mac_scell.active = true; - mac_scell.enb_cc_idx = ue_cell_list.get_ue_cc_idx(scell.scell_idx_r10)->cell_common->enb_cc_idx; + auto& mac_scell = ue_cfg.supported_cc_list[scell.scell_idx_r10]; + mac_scell.active = true; + mac_scell.ul_disabled = !scell.rr_cfg_common_scell_r10.ul_cfg_r10.ul_freq_info_r10.ul_carrier_freq_r10_present; + mac_scell.enb_cc_idx = ue_cell_list.get_ue_cc_idx(scell.scell_idx_r10)->cell_common->enb_cc_idx; if (scell.rr_cfg_ded_scell_r10_present and scell.rr_cfg_ded_scell_r10.phys_cfg_ded_scell_r10_present and scell.rr_cfg_ded_scell_r10.phys_cfg_ded_scell_r10.ul_cfg_r10_present) { diff --git a/srsenb/src/stack/rrc/rrc_cell_cfg.cc b/srsenb/src/stack/rrc/rrc_cell_cfg.cc index 00b0727b8..4f33a7f2c 100644 --- a/srsenb/src/stack/rrc/rrc_cell_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_cell_cfg.cc @@ -44,6 +44,12 @@ enb_cell_common_list::enb_cell_common_list(const rrc_cfg_t& cfg_) : cfg(cfg_) // Update DL EARFCN new_cell->sib1.freq_band_ind = (uint8_t)srsran_band_get_band(new_cell->cell_cfg.dl_earfcn); + if (new_cell->cell_cfg.barred) { + cell_access->cell_barred.value = sib_type1_s::cell_access_related_info_s_::cell_barred_opts::barred; + } else { + cell_access->cell_barred.value = sib_type1_s::cell_access_related_info_s_::cell_barred_opts::not_barred; + } + // Set Cell SIB2 // update PRACH root seq index for this cell new_cell->sib2 = cfg.sibs[1].sib2(); From 6bec41fcbe0fa7b222774d7cc2633f333c29ca94 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Thu, 27 Oct 2022 17:18:01 +0200 Subject: [PATCH 149/167] enable/disable UL CA using scell_list.ul_allowed parameter --- srsenb/src/stack/rrc/ue_rr_cfg.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/srsenb/src/stack/rrc/ue_rr_cfg.cc b/srsenb/src/stack/rrc/ue_rr_cfg.cc index 856e613bd..ac511f294 100644 --- a/srsenb/src/stack/rrc/ue_rr_cfg.cc +++ b/srsenb/src/stack/rrc/ue_rr_cfg.cc @@ -426,6 +426,9 @@ void fill_scells_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, } } + const ue_cell_ded* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); + const enb_cell_common* pcell_cfg = pcell->cell_common; + scell_to_add_mod_list_r10_l target_scells(ue_cell_list.nof_cells() - 1); for (size_t ue_cc_idx = 1; ue_cc_idx < ue_cell_list.nof_cells(); ++ue_cc_idx) { const ue_cell_ded& scell = *ue_cell_list.get_ue_cc_idx(ue_cc_idx); @@ -447,7 +450,14 @@ void fill_scells_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, nonul_cfg.phich_cfg_r10 = scell_cfg.mib.phich_cfg; nonul_cfg.pdsch_cfg_common_r10 = cc_cfg_sib.pdsch_cfg_common; // RadioResourceConfigCommonSCell-r10::ul-Configuration-r10 - if (ue_caps.support_ul_ca) { + bool ul_allowed = false; + for (const auto& scell_tmp : pcell_cfg->cell_cfg.scell_list) { + if (scell_tmp.cell_id == scell.cell_common->cell_cfg.cell_id) { + ul_allowed = scell_tmp.ul_allowed; + break; + } + } + if (ue_caps.support_ul_ca and ul_allowed) { asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10_present = true; auto& ul_cfg = asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10; ul_cfg.ul_freq_info_r10.ul_carrier_freq_r10_present = true; From 3178abf37b60c75a47133a8f023686d68ed9e3eb Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Mon, 31 Oct 2022 14:11:13 +0100 Subject: [PATCH 150/167] =?UTF-8?q?add=20Intra=E2=80=91band=20Non-contiguo?= =?UTF-8?q?us=20CA=20band=20combinations=20to=20UE=20caps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- srsue/hdr/stack/rrc/rrc_config.h | 2 ++ srsue/src/stack/rrc/rrc.cc | 32 ++++++++++++++++++++++++++++++-- srsue/src/ue.cc | 2 ++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/srsue/hdr/stack/rrc/rrc_config.h b/srsue/hdr/stack/rrc/rrc_config.h index 1f66c3eb7..1a58e2adb 100644 --- a/srsue/hdr/stack/rrc/rrc_config.h +++ b/srsue/hdr/stack/rrc/rrc_config.h @@ -27,6 +27,8 @@ struct rrc_args_t { std::array supported_bands; std::vector supported_bands_nr; uint32_t nof_supported_bands; + uint32_t nof_lte_carriers; + uint32_t nof_nr_carriers; bool support_ca; int mbms_service_id; uint32_t mbms_service_port; diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 64ababa23..ca652aec3 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -1992,8 +1992,11 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) phy_layer_params_v1020.multi_cluster_pusch_within_cc_r10_present = false; phy_layer_params_v1020.non_contiguous_ul_ra_within_cc_list_r10_present = false; + rf_params_v1020_s rf_params; band_combination_params_r10_l combination_params; if (args.support_ca) { + // add Intra‑band Contiguous or Inter‑band Non-contiguous CA band combination + // note that nof_supported_bands=1 when all cells are in the same but non-contiguous band for (uint32_t k = 0; k < args.nof_supported_bands; k++) { ca_mimo_params_dl_r10_s ca_mimo_params_dl; ca_mimo_params_dl.ca_bw_class_dl_r10 = ca_bw_class_r10_e::f; @@ -2013,10 +2016,35 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) combination_params.push_back(band_params); } } - - rf_params_v1020_s rf_params; rf_params.supported_band_combination_r10.push_back(combination_params); + // add all 2CC, 3CC and 4CC Intra‑band Non-contiguous CA band combinations + for (uint32_t k = 0; k < args.nof_supported_bands; k++) { + for (uint32_t j = 2; j <= args.nof_lte_carriers; j++) { + combination_params.clear(); + + ca_mimo_params_dl_r10_s ca_mimo_params_dl; + ca_mimo_params_dl.ca_bw_class_dl_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_dl.supported_mimo_cap_dl_r10_present = false; + + ca_mimo_params_ul_r10_s ca_mimo_params_ul; + ca_mimo_params_ul.ca_bw_class_ul_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_ul.supported_mimo_cap_ul_r10_present = false; + + band_params_r10_s band_params; + band_params.band_eutra_r10 = args.supported_bands[k]; + band_params.band_params_dl_r10_present = true; + band_params.band_params_dl_r10.push_back(ca_mimo_params_dl); + band_params.band_params_ul_r10_present = true; + band_params.band_params_ul_r10.push_back(ca_mimo_params_ul); + + for (uint32_t l = 0; l < j; l++) { + combination_params.push_back(band_params); + } + rf_params.supported_band_combination_r10.push_back(combination_params); + } + } + ue_eutra_cap_v1020_ies_s cap_v1020; if (args.ue_category >= 6 && args.ue_category <= 8) { cap_v1020.ue_category_v1020_present = true; diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index f51ee9e47..4d26b97c7 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -268,6 +268,8 @@ int ue::parse_args(const all_args_t& args_) args.stack.rrc.ue_category = (uint32_t)strtoul(args.stack.rrc.ue_category_str.c_str(), nullptr, 10); // Consider Carrier Aggregation support if more than one + args.stack.rrc.nof_lte_carriers = args.phy.nof_lte_carriers; + args.stack.rrc.nof_nr_carriers = args.phy.nof_nr_carriers; args.stack.rrc.support_ca = (args.phy.nof_lte_carriers > 1); // Make sure fix sampling rate is set for SA mode From 5eed9297d3fc181dd3e7f24b25d2b9751699b8f4 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Wed, 30 Nov 2022 16:04:59 +0100 Subject: [PATCH 151/167] fix: correctly skip resource allocation if ul_disabled --- srsenb/src/stack/mac/schedulers/sched_time_pf.cc | 7 +++++-- srsenb/src/stack/mac/schedulers/sched_time_rr.cc | 10 +++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/srsenb/src/stack/mac/schedulers/sched_time_pf.cc b/srsenb/src/stack/mac/schedulers/sched_time_pf.cc index de1103f96..4e418db61 100644 --- a/srsenb/src/stack/mac/schedulers/sched_time_pf.cc +++ b/srsenb/src/stack/mac/schedulers/sched_time_pf.cc @@ -62,8 +62,11 @@ void sched_time_pf::new_tti(sched_ue_list& ue_db, sf_sched* tti_sched) } if (it->second.ul_h != nullptr) { // Allocate only if UL carrier is enabled - if (!u.second->get_ue_cfg().supported_cc_list[cc_cfg->enb_cc_idx].ul_disabled) { - ul_queue.push(&it->second); + for (auto& i : u.second->get_ue_cfg().supported_cc_list) { + if (i.enb_cc_idx == cc_cfg->enb_cc_idx and not i.ul_disabled) { + ul_queue.push(&it->second); + break; + } } } } diff --git a/srsenb/src/stack/mac/schedulers/sched_time_rr.cc b/srsenb/src/stack/mac/schedulers/sched_time_rr.cc index 6637b2630..9a5de4875 100644 --- a/srsenb/src/stack/mac/schedulers/sched_time_rr.cc +++ b/srsenb/src/stack/mac/schedulers/sched_time_rr.cc @@ -122,9 +122,17 @@ void sched_time_rr::sched_ul_newtxs(sched_ue_list& ue_db, sf_sched* tti_sched, s } sched_ue& user = *iter->second; // Allocate only if UL carrier is enabled - if (user.get_ue_cfg().supported_cc_list[cc_cfg->enb_cc_idx].ul_disabled) { + bool ul_disabled = false; + for (auto& i : user.get_ue_cfg().supported_cc_list) { + if (i.enb_cc_idx == cc_cfg->enb_cc_idx) { + ul_disabled = i.ul_disabled; + break; + } + } + if (ul_disabled) { continue; } + const ul_harq_proc* h = get_ul_newtx_harq(user, tti_sched); // Check if there is a empty harq if (h == nullptr) { From 25d9ae460e790dfd7ba8a013c287429aa2699a30 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 9 Dec 2022 12:46:58 +0100 Subject: [PATCH 152/167] rrc: fix nas pdu list filling avoid setting dedicated info nas list as present when there are no NAS PDUs to send. Raise logging level when NAS messages are not present during DRB addition/modification --- srsenb/src/stack/rrc/rrc_bearer_cfg.cc | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index 7fd091b6c..cb1fb3ee2 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -414,14 +414,6 @@ void bearer_cfg_handler::rem_gtpu_bearer(uint32_t erab_id) void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg) { - // Add space for NAS messages - uint8_t n_nas = erab_info_list.size(); - if (n_nas > 0) { - msg->ded_info_nas_list_present = true; - msg->ded_info_nas_list.resize(n_nas); - } - - uint32_t idx = 0; // DRBs have already been configured in GTPU during bearer setup // Add E-RAB info message for the E-RABs if (msg->rr_cfg_ded.drb_to_add_mod_list_present) { @@ -434,14 +426,15 @@ void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_ if (info_it != erab_info_list.end()) { const std::vector& erab_info = info_it->second; logger->info(&erab_info[0], erab_info.size(), "connection_reconf erab_info -> nas_info rnti 0x%x", rnti); - msg->ded_info_nas_list[idx].resize(erab_info.size()); - memcpy(msg->ded_info_nas_list[idx].data(), &erab_info[0], erab_info.size()); + msg->ded_info_nas_list.push_back({}); + msg->ded_info_nas_list.back().resize(erab_info.size()); + memcpy(msg->ded_info_nas_list.back().data(), &erab_info[0], erab_info.size()); erab_info_list.erase(info_it); } else { - logger->debug("Not adding NAS message to connection reconfiguration. E-RAB id %d", erab_id); + logger->warning("Not adding NAS message to connection reconfiguration. E-RAB id %d", erab_id); } - idx++; } + msg->ded_info_nas_list_present = msg->ded_info_nas_list.size() > 0; } } From 3daaf9b356d8c412fb9db2732a6cb060e503054c Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 9 Dec 2022 12:50:22 +0100 Subject: [PATCH 153/167] Allow NAS PDUs to be cleared only after the Reconfiguration Complete is received by the eNB --- srsenb/hdr/stack/rrc/rrc_bearer_cfg.h | 4 ++++ srsenb/src/stack/rrc/rrc_bearer_cfg.cc | 18 +++++++++++++++++- srsenb/src/stack/rrc/rrc_ue.cc | 3 +++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h index 11abfa4cd..fb8e8fc7a 100644 --- a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h @@ -114,6 +114,7 @@ public: const gtpu_interface_rrc::bearer_props* props = nullptr); void rem_gtpu_bearer(uint32_t erab_id); void fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg); + void clear_pending_nas_info(); const std::map& get_erabs() const { return erabs; } const asn1::rrc::drb_to_add_mod_list_l& get_established_drbs() const { return current_drbs; } @@ -127,6 +128,9 @@ private: const rrc_cfg_t* cfg = nullptr; gtpu_interface_rrc* gtpu = nullptr; + // NAS PDUs being currently sent. + std::vector erab_ids_with_pending_nas_pdus; + // last cfg asn1::rrc::drb_to_add_mod_list_l current_drbs; }; diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index cb1fb3ee2..8d54b0301 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -417,6 +417,8 @@ void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_ // DRBs have already been configured in GTPU during bearer setup // Add E-RAB info message for the E-RABs if (msg->rr_cfg_ded.drb_to_add_mod_list_present) { + erab_ids_with_pending_nas_pdus.clear(); + for (const drb_to_add_mod_s& drb : msg->rr_cfg_ded.drb_to_add_mod_list) { uint32_t lcid = drb_to_lcid((lte_drb)drb.drb_id); auto erab_it = std::find_if( @@ -429,7 +431,7 @@ void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_ msg->ded_info_nas_list.push_back({}); msg->ded_info_nas_list.back().resize(erab_info.size()); memcpy(msg->ded_info_nas_list.back().data(), &erab_info[0], erab_info.size()); - erab_info_list.erase(info_it); + erab_ids_with_pending_nas_pdus.push_back(erab_id); } else { logger->warning("Not adding NAS message to connection reconfiguration. E-RAB id %d", erab_id); } @@ -438,4 +440,18 @@ void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_ } } +void bearer_cfg_handler::clear_pending_nas_info() +{ + for (uint32_t erab_id : erab_ids_with_pending_nas_pdus) { + auto info_it = erab_info_list.find(erab_id); + if (info_it == erab_info_list.end()) { + logger->warning("NAS PDU with ERAB id={} went missing", erab_id); + continue; + } + erab_info_list.erase(info_it); + } + + erab_ids_with_pending_nas_pdus.clear(); +} + } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 922b5e5a2..a0073c3f9 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -961,6 +961,9 @@ void rrc::ue::handle_rrc_reconf_complete(rrc_conn_recfg_complete_s* msg, srsran: // If performing handover, signal its completion mobility_handler->trigger(*msg); + // Clear pending NAS PDUs + bearer_list.clear_pending_nas_info(); + // 2> if the UE has radio link failure or handover failure information available const auto& complete_r8 = msg->crit_exts.rrc_conn_recfg_complete_r8(); if (complete_r8.non_crit_ext.non_crit_ext.rlf_info_available_r10_present or rlf_info_pending) { From 751136f46a3b5c61f612ca851f96b84186825126 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Fri, 10 Mar 2023 13:48:41 +0100 Subject: [PATCH 154/167] rrc,asn1: Add asn1 packing and unpacking test for ue cap enquiry and -information --- lib/test/asn1/srsran_asn1_rrc_dl_dcch_test.cc | 26 ++++ lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc | 143 ++++++++++++++++++ 2 files changed, 169 insertions(+) diff --git a/lib/test/asn1/srsran_asn1_rrc_dl_dcch_test.cc b/lib/test/asn1/srsran_asn1_rrc_dl_dcch_test.cc index 74dd117a7..50227e488 100644 --- a/lib/test/asn1/srsran_asn1_rrc_dl_dcch_test.cc +++ b/lib/test/asn1/srsran_asn1_rrc_dl_dcch_test.cc @@ -57,6 +57,31 @@ int rrc_conn_reconfig_ho_test1() return 0; } +int rrc_ue_cap_enquiry_test() +{ + uint8_t rrc_msg[] = {0x38, 0x00, 0x00}; + // 38 00 00 + + cbit_ref bref(rrc_msg, sizeof(rrc_msg)); + + dl_dcch_msg_s dl_dcch_msg; + dl_dcch_msg.unpack(bref); + + TESTASSERT(dl_dcch_msg.msg.type() == dl_dcch_msg_type_c::types::c1); + TESTASSERT(dl_dcch_msg.msg.c1().type() == dl_dcch_msg_type_c::c1_c_::types::ue_cap_enquiry); + + // assign to stack-allocated variable + asn1::rrc::ue_cap_enquiry_s ue_cap; + ue_cap = dl_dcch_msg.msg.c1().ue_cap_enquiry(); + + TESTASSERT(ue_cap.crit_exts.c1().type() == + asn1::rrc::ue_cap_enquiry_s::crit_exts_c_::c1_c_::types::ue_cap_enquiry_r8); + TESTASSERT(ue_cap.crit_exts.c1().ue_cap_enquiry_r8().ue_cap_request.size() == 1); + TESTASSERT(ue_cap.crit_exts.c1().ue_cap_enquiry_r8().ue_cap_request[0] == asn1::rrc::rat_type_e::eutra); + + return 0; +} + int main(int argc, char** argv) { auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); @@ -66,6 +91,7 @@ int main(int argc, char** argv) srslog::init(); TESTASSERT(rrc_conn_reconfig_ho_test1() == 0); + TESTASSERT(rrc_ue_cap_enquiry_test() == 0); return 0; } diff --git a/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc b/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc index a85ce41c6..db4ac82f2 100644 --- a/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc +++ b/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc @@ -15,6 +15,7 @@ #include "srsran/common/mac_pcap.h" #include +using namespace asn1; using namespace asn1::rrc; #define PCAP 0 @@ -166,6 +167,147 @@ int pack_fail_test() return 0; } +int rrc_ue_cap_information_test() +{ + uint8_t rrc_msg[] = { + 0x38, 0x01, 0x08, 0x89, 0x9e, 0x01, 0xb8, 0x05, 0x18, 0x18, 0x01, 0x33, 0xe6, 0xc0, 0x82, 0x06, 0x10, 0x38, 0xb1, + 0x84, 0x08, 0x92, 0x30, 0x65, 0x2a, 0x64, 0xea, 0x14, 0xaa, 0x5e, 0xfc, 0xc1, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, + 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, + 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, + 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, + 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, + 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xfb, 0xf0, + 0x6e, 0xc4, 0xf0, 0x01, 0x41, 0xbc, 0x05, 0xdc, 0x80, 0x00, 0x00, 0x00, 0x2f, 0x60, 0x00, 0x00, 0x02, 0x02, 0x77, + 0xc0, 0x00, 0x00, 0x00, 0xbf, 0xf0, 0x03, 0x00, 0x21, 0x00, 0x30, 0x02, 0x00, 0x80, 0x14, 0x00, 0xc0, 0x0c, 0x00, + 0x90, 0x03, 0x04, 0x21, 0x80, 0x18, 0x01, 0x82, 0x10, 0xc1, 0x08, 0x60, 0x80, 0x30, 0x40, 0x18, 0x20, 0x0c, 0x10, + 0x86, 0x08, 0x43, 0x04, 0x21, 0x82, 0x10, 0xc1, 0x00, 0x60, 0x80, 0x24, 0x10, 0x06, 0x08, 0x03, 0x04, 0x20, 0x82, + 0x10, 0x41, 0x08, 0x60, 0x84, 0x30, 0x42, 0x18, 0x21, 0x0c, 0x10, 0x82, 0x08, 0x41, 0x04, 0x21, 0x41, 0x00, 0x60, + 0x80, 0x30, 0x40, 0x12, 0x08, 0x43, 0x04, 0x21, 0x82, 0x10, 0xc1, 0x08, 0x60, 0x84, 0x30, 0x42, 0x18, 0x20, 0x0c, + 0x10, 0x04, 0x20, 0x80, 0x30, 0x40, 0x18, 0x20, 0x0c, 0x10, 0x06, 0x08, 0x43, 0x04, 0x21, 0x41, 0x08, 0x20, 0x84, + 0x10, 0x42, 0x08, 0x21, 0x04, 0x10, 0x06, 0x08, 0x02, 0x41, 0x00, 0x40, 0x82, 0x00, 0xc1, 0x00, 0x60, 0x80, 0x30, + 0x40, 0x12, 0x08, 0x41, 0x04, 0x20, 0x02, 0x08, 0x41, 0x04, 0x20, 0x20, 0x84, 0x30, 0x42, 0x18, 0x21, 0x0c, 0x10, + 0x86, 0x08, 0x43, 0x04, 0x21, 0x08, 0x20, 0x0c, 0x10, 0x06, 0x08, 0x03, 0x04, 0x01, 0x82, 0x10, 0xc0, 0x0c, 0x30, + 0x84, 0x21, 0x80, 0x12, 0xd7, 0xd5, 0x46, 0xc0, 0x3c, 0x00, 0x03, 0xf8, 0x18, 0xc0, 0x00, 0x82, 0x06, 0x00, 0x00, + 0x20, 0x81, 0xa6, 0x00, 0x08, 0x00, 0x2f, 0x84, 0x00, 0x36, 0xc0, 0x01, 0x00, 0x0c, 0x10, 0x00, 0x40, 0x03, 0x08, + 0x00, 0x10, 0x40, 0xc3, 0x00, 0x04, 0x10, 0x31, 0x00, 0x01, 0x00, 0x0c, 0x70, 0x00, 0x40, 0x03, 0x2c, 0x00, 0x10, + 0x00, 0xcc, 0x00, 0x04, 0x00, 0x34, 0x00, 0x01, 0x00, 0x0d, 0x10, 0x00, 0x40, 0x03, 0x48, 0x00, 0x10, 0x00, 0xd8, + 0x00, 0x04, 0x00, 0x36, 0x40, 0x01, 0x00, 0x0e, 0x50, 0x00, 0x41, 0x03, 0x98, 0x00, 0x10, 0x00, 0xe7, 0x00, 0x04, + 0x10, 0x3a, 0x00, 0x01, 0x04, 0x0e, 0x90, 0x00, 0x41, 0x03, 0xa8, 0x00, 0x10, 0x00, 0xef, 0x00, 0x04, 0x00, 0x3f, + 0xc0, 0x01, 0x04, 0x1c, 0x60, 0x00, 0x41, 0x46, 0x08, 0x20, 0x63, 0x00, 0x02, 0x48, 0x18, 0xc0, 0x00, 0x8a, 0x0e, + 0x30, 0x00, 0x20, 0xa0, 0x04, 0x10, 0x51, 0x82, 0x0e, 0x00, 0x00, 0x20, 0x83, 0xa6, 0x00, 0x08, 0x08, 0xc1, 0x04, + 0x15, 0x30, 0x81, 0x8c, 0x00, 0x08, 0x20, 0xaf, 0x84, 0x0c, 0x60, 0x00, 0x41, 0x07, 0xfc, 0x00, 0x10, 0x51, 0x82, + 0x08, 0x2f, 0xe1, 0x07, 0x18, 0x00, 0x10, 0x41, 0xe9, 0x00, 0x04, 0x14, 0x60, 0x82, 0x0b, 0x48, 0x41, 0xc6, 0x00, + 0x04, 0x10, 0x76, 0xc0, 0x01, 0x01, 0x18, 0x20, 0x82, 0xb6, 0x10, 0x31, 0x80, 0x01, 0x04, 0x1d, 0x90, 0x00, 0x40, + 0x46, 0x08, 0x00, 0xac, 0x84, 0x0c, 0x60, 0x00, 0x40, 0x07, 0x1c, 0x00, 0x10, 0x11, 0x82, 0x08, 0x28, 0xe1, 0x03, + 0x18, 0x00, 0x10, 0x41, 0xc6, 0x00, 0x04, 0x14, 0x40, 0x80, 0x0a, 0x30, 0x41, 0xc4, 0x00, 0x04, 0x00, 0x71, 0x80, + 0x01, 0x05, 0x0c, 0x20, 0x82, 0x8c, 0x10, 0x70, 0xc0, 0x01, 0x04, 0x1c, 0x60, 0x00, 0x41, 0x42, 0x08, 0x20, 0xa3, + 0x04, 0x1c, 0x20, 0x00, 0x41, 0x07, 0x18, 0x00, 0x10, 0x50, 0x42, 0x00, 0x28, 0xc1, 0x07, 0x04, 0x00, 0x10, 0x01, + 0xc0, 0x00, 0x04, 0x14, 0x00, 0x82, 0x06, 0x00, 0x00, 0x24, 0x03, 0xa6, 0x00, 0x08, 0x08, 0x01, 0x04, 0x15, 0x30, + 0x81, 0x80, 0x00, 0x08, 0x20, 0xaf, 0x84, 0x0c, 0x00, 0x00, 0x41, 0x07, 0xa4, 0x00, 0x10, 0x10, 0x02, 0x00, 0x2d, + 0x21, 0x03, 0x00, 0x00, 0x10, 0x01, 0xe8, 0x00, 0x04, 0x14, 0x00, 0x82, 0x0b, 0x40, 0x41, 0xc0, 0x00, 0x04, 0x10, + 0x79, 0xc0, 0x01, 0x05, 0x00, 0x20, 0x82, 0xce, 0x10, 0x70, 0x00, 0x01, 0x04, 0x1e, 0x50, 0x00, 0x41, 0x40, 0x08, + 0x20, 0xb2, 0x84, 0x1c, 0x00, 0x00, 0x41, 0x07, 0x6c, 0x00, 0x10, 0x10, 0x02, 0x08, 0x2b, 0x61, 0x03, 0x00, 0x00, + 0x10, 0x41, 0xd2, 0x00, 0x04, 0x04, 0x00, 0x80, 0x0a, 0x90, 0x40, 0xc0, 0x00, 0x04, 0x00, 0x74, 0x40, 0x01, 0x01, + 0x00, 0x20, 0x02, 0xa2, 0x10, 0x30, 0x00, 0x01, 0x00, 0x1c, 0x70, 0x00, 0x40, 0x40, 0x08, 0x20, 0xa3, 0x84, 0x0c, + 0x00, 0x00, 0x41, 0x07, 0x10, 0x00, 0x10, 0x10, 0x02, 0x08, 0x28, 0x81, 0x03, 0x00, 0x00, 0x10, 0x41, 0xc2, 0x00, + 0x04, 0x14, 0x00, 0x82, 0x0a, 0x10, 0x41, 0xc0, 0x00, 0x04, 0x10, 0x57, 0xc2, 0x06, 0x98, 0x00, 0x20, 0x03, 0xce, + 0x00, 0x08, 0x2a, 0x61, 0x00, 0x16, 0x70, 0x83, 0xa6, 0x00, 0x08, 0x00, 0xf2, 0x80, 0x02, 0x0a, 0x98, 0x40, 0x05, + 0x94, 0x20, 0xe9, 0x80, 0x02, 0x00, 0x3a, 0x60, 0x00, 0x80, 0x84, 0x10, 0x41, 0x53, 0x08, 0x18, 0x40, 0x00, 0x82, + 0x0a, 0xf8, 0x40, 0xdb, 0x00, 0x04, 0x00, 0x57, 0xc2, 0x06, 0x38, 0x00, 0x20, 0x02, 0xbe, 0x10, 0x30, 0x80, 0x01, + 0x04, 0x1e, 0x90, 0x00, 0x40, 0x5b, 0x08, 0x00, 0xb4, 0x84, 0x0d, 0xb0, 0x00, 0x40, 0x07, 0xa0, 0x00, 0x10, 0x16, + 0xc2, 0x00, 0x2d, 0x01, 0x03, 0x6c, 0x00, 0x10, 0x01, 0xe5, 0x00, 0x04, 0x05, 0xb0, 0x80, 0x0b, 0x28, 0x40, 0xdb, + 0x00, 0x04, 0x00, 0x76, 0xc0, 0x01, 0x01, 0x0c, 0x20, 0x82, 0xb6, 0x10, 0x30, 0xc0, 0x01, 0x04, 0x1d, 0xb0, 0x00, + 0x40, 0x42, 0x08, 0x20, 0xad, 0x84, 0x0c, 0x20, 0x00, 0x41, 0x07, 0x6c, 0x00, 0x10, 0x10, 0x42, 0x00, 0x2b, 0x61, + 0x03, 0x04, 0x00, 0x10, 0x01, 0xff, 0x00, 0x04, 0x14, 0x10, 0x80, 0x0b, 0xf8, 0x41, 0xc1, 0x00, 0x04, 0x00, 0x74, + 0x00, 0x01, 0x01, 0x04, 0x20, 0x02, 0xa0, 0x10, 0x30, 0x40, 0x01, 0x00, 0x1c, 0xb0, 0x00, 0x40, 0x41, 0x08, 0x00, + 0xa5, 0x84, 0x0c, 0x10, 0x00, 0x40, 0x07, 0x10, 0x00, 0x10, 0x10, 0x42, 0x00, 0x28, 0x81, 0x03, 0x04, 0x00, 0x10, + 0x01, 0xc3, 0x00, 0x04, 0x14, 0x10, 0x80, 0x0a, 0x18, 0x41, 0xc1, 0x00, 0x04, 0x00, 0x7a, 0x40, 0x01, 0x01, 0x08, + 0x20, 0x02, 0xd2, 0x10, 0x30, 0x80, 0x01, 0x00, 0x1e, 0x80, 0x00, 0x41, 0x42, 0x08, 0x20, 0xb4, 0x04, 0x1c, 0x20, + 0x00, 0x41, 0x07, 0x9c, 0x00, 0x10, 0x50, 0x82, 0x08, 0x2c, 0xe1, 0x07, 0x08, 0x00, 0x10, 0x41, 0xe5, 0x00, 0x04, + 0x14, 0x20, 0x82, 0x0b, 0x28, 0x41, 0xc2, 0x00, 0x04, 0x10, 0x74, 0x80, 0x01, 0x01, 0x08, 0x20, 0x02, 0xa4, 0x10, + 0x30, 0x80, 0x01, 0x00, 0x1d, 0x10, 0x00, 0x40, 0x42, 0x08, 0x00, 0xa8, 0x84, 0x0c, 0x20, 0x00, 0x40, 0x07, 0x1c, + 0x00, 0x10, 0x10, 0x82, 0x08, 0x28, 0xe1, 0x03, 0x08, 0x00, 0x10, 0x41, 0xc4, 0x00, 0x04, 0x04, 0x20, 0x82, 0x0a, + 0x20, 0x40, 0xc2, 0x00, 0x04, 0x10, 0x70, 0x80, 0x01, 0x05, 0x08, 0x20, 0x81, 0x84, 0x00, 0x09, 0x21, 0xb2, 0x84, + 0x14, 0x60, 0x83, 0x84, 0x00, 0x09, 0x28, 0x01, 0x04, 0x0c, 0x60, 0x10, 0x49, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0xf9, 0xc0, 0x00, 0x01, 0xfb, 0x10, + 0x3e, 0x74, 0x00, 0x00, 0x11, 0xf3, 0x80, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x02, 0x3f, 0x8b, 0xa1, 0xe1, 0xe2, 0xf1, + 0x70, 0x43, 0xc3, 0x91, 0x78, 0xbc, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x38, 0x87, 0x04, 0x3c, 0x38, 0x43, 0xc3, 0x90, + 0xf0, 0xf1, 0x78, 0xbc, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x39, 0x0f, 0x0e, 0x08, 0x78, 0x70, 0x87, 0x87, 0x22, + 0xf1, 0x72, 0x2f, 0x17, 0x87, 0x87, 0x8b, 0xc5, 0xc8, 0x78, 0x78, 0x78, 0x70, 0x23, 0xf8, 0xfe, 0x4f, 0xc9, 0xf8, + 0xb9, 0x17, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0x00, 0x00, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, + 0x40, 0x14, 0x04, 0x05, 0x01, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, + 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, + 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, + 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, + 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x14, 0x04, 0x05, 0x01, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, + 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, + 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x3c, 0x08, 0x02, 0x48, 0x07, 0x8c, 0xbc, 0xd0, 0x30, 0x1a, + 0x58, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x4a, 0x5d, 0xe3, 0x80, 0x74, 0x00, 0x2c, 0x10, 0x00, 0xcd, 0x25, + 0x08, 0x00, 0x80, 0x01, 0x2c, 0x3f, 0xc0, 0x12, 0x00, 0x90, 0x04, 0x10, 0x04, 0x80, 0x24, 0x01, 0x20, 0x09, 0x00, + 0x48, 0x02, 0x40, 0x12, 0x00, 0x90, 0x04, 0x80, 0x24, 0x01, 0x20, 0x09, 0x00, 0x48, 0x02, 0x40, 0x12, 0x00, 0x90, + 0x04, 0x80, 0x24, 0x01, 0x20, 0x09, 0x00, 0x48, 0x0a, 0x04, 0x01, 0x20, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, + 0x20, 0x20, 0x90, 0x10, 0x48, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x81, 0x01, 0x04, 0x80, 0xa0, 0x40, 0x41, 0x20, 0x28, + 0x10, 0x10, 0x48, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x81, 0x01, 0x04, 0x80, 0xa0, 0x40, 0x41, 0x20, 0x28, 0x10, 0x10, + 0x48, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x81, 0x00, 0x48, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, + 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, 0x24, 0x05, 0x02, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, + 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, 0x24, 0x05, 0x02, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, + 0x90, 0x10, 0x48, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x81, 0x01, 0x04, 0x80, 0xa0, 0x40, 0x41, 0x20, 0x20, 0x90, 0x10, + 0x48, 0x08, 0x24, 0x05, 0x02, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, + 0x24, 0x05, 0x02, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, 0x24, 0x05, + 0x02, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, 0x24, 0x05, 0x02, 0x02, + 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, 0x24, 0x05, 0x02, 0x02, 0x09, 0x01, + 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x02, 0x40, 0xc0, 0x10, 0x20, 0x04, 0x0c, 0x43, 0x2a, + 0x78, 0x18, 0x00, 0x00, 0x40, 0x20, 0x0c, 0x03, 0x82, 0x60, 0xd8, 0x4a, 0x13, 0x85, 0x02, 0x08, 0x98, 0x26, 0x88, + 0x00, 0x44, 0x02, 0x0a, 0x18, 0x32, 0xc0, 0x80, 0x00, 0x02, 0x01, 0x80, 0x70, 0x4c, 0x1b, 0x09, 0x42, 0x71, 0x36, + 0x90}; + + cbit_ref bref(rrc_msg, sizeof(rrc_msg)); + + ul_dcch_msg_s ul_dcch_msg; + ul_dcch_msg.unpack(bref); + + TESTASSERT(ul_dcch_msg.msg.type() == ul_dcch_msg_type_c::types::c1); + TESTASSERT(ul_dcch_msg.msg.c1().type() == ul_dcch_msg_type_c::c1_c_::types::ue_cap_info); + + // assign to stack-allocated variable + asn1::rrc::ue_cap_info_s ue_cap; + ue_cap = ul_dcch_msg.msg.c1().ue_cap_info(); + + TESTASSERT(ue_cap.crit_exts.c1().type() == asn1::rrc::ue_cap_info_s::crit_exts_c_::c1_c_::types::ue_cap_info_r8); + TESTASSERT(ue_cap.crit_exts.c1().ue_cap_info_r8().ue_cap_rat_container_list.size() == 1); + TESTASSERT(ue_cap.crit_exts.c1().ue_cap_info_r8().ue_cap_rat_container_list[0].rat_type == + asn1::rrc::rat_type_e::eutra); + + return 0; +} + int main(int argc, char** argv) { auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); @@ -183,6 +325,7 @@ int main(int argc, char** argv) #endif TESTASSERT(pack_fail_test() == -1); TESTASSERT(rrc_nr_test_scg_fail_packing() == SRSRAN_SUCCESS) + TESTASSERT(rrc_ue_cap_information_test() == 0); #if PCAP pcap.close(); From b927936d522ba73d3961dab2e69827b2ff3dff08 Mon Sep 17 00:00:00 2001 From: herlesupreeth Date: Mon, 6 Feb 2023 17:02:01 +0100 Subject: [PATCH 155/167] gtpu: improve check for PDU session Id in NR SA --- lib/include/srsran/common/common_lte.h | 8 ++++++ lib/include/srsran/common/common_nr.h | 9 +++++++ srsenb/hdr/stack/upper/gtpu.h | 25 ++++++++++++------- srsenb/src/stack/enb_stack_lte.cc | 2 +- srsenb/src/stack/upper/gtpu.cc | 19 +++++++++----- srsenb/test/upper/gtpu_test.cc | 11 ++++---- srsgnb/src/stack/gnb_stack_nr.cc | 2 +- srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc | 2 +- 8 files changed, 55 insertions(+), 23 deletions(-) diff --git a/lib/include/srsran/common/common_lte.h b/lib/include/srsran/common/common_lte.h index 44f324ec2..452c383f1 100644 --- a/lib/include/srsran/common/common_lte.h +++ b/lib/include/srsran/common/common_lte.h @@ -95,6 +95,14 @@ inline const char* get_drb_name(lte_drb drb_id) return names[(uint32_t)(drb_id < lte_drb::invalid ? drb_id : lte_drb::invalid) - 1]; } +inline const char* get_rb_name(uint32_t lcid) +{ + if (is_lte_srb(lcid)) { + return get_srb_name(static_cast(lcid)); + } + return get_drb_name(static_cast(lcid - MAX_LTE_SRB_ID)); +} + } // namespace srsran #endif // SRSRAN_COMMON_LTE_H diff --git a/lib/include/srsran/common/common_nr.h b/lib/include/srsran/common/common_nr.h index 17e9e2521..889046bc7 100644 --- a/lib/include/srsran/common/common_nr.h +++ b/lib/include/srsran/common/common_nr.h @@ -94,6 +94,15 @@ inline const char* get_drb_name(nr_drb drb_id) "DRB25", "DRB26", "DRB27", "DRB28", "DRB29", "invalid DRB id"}; return names[(uint32_t)(drb_id < nr_drb::invalid ? drb_id : nr_drb::invalid) - 1]; } + +inline const char* get_nr_rb_name(uint32_t lcid) +{ + if (is_nr_srb(lcid)) { + return get_srb_name(static_cast(lcid)); + } + return get_drb_name(static_cast(lcid - MAX_NR_SRB_ID)); +} + } // namespace srsran #endif // SRSRAN_COMMON_NR_H \ No newline at end of file diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index 47399d476..00019144f 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -11,8 +11,8 @@ */ #include -#include #include +#include #include "srsenb/hdr/common/common_enb.h" #include "srsran/adt/bounded_vector.h" @@ -49,7 +49,7 @@ class gtpu_tunnel_manager public: // A UE should have <= 3 DRBs active, and each DRB should have two tunnels active at the same time at most - const static size_t MAX_TUNNELS_PER_UE = 10; + const static size_t MAX_TUNNELS_PER_UE = 32; enum class tunnel_state { pdcp_active, buffering, forward_to, forwarded_from, inactive }; @@ -66,8 +66,8 @@ public: tunnel* fwd_tunnel = nullptr; ///< forward Rx SDUs to this TEID srsran::move_callback on_removal; - tunnel() = default; - tunnel(tunnel&&) noexcept = default; + tunnel() = default; + tunnel(tunnel&&) noexcept = default; tunnel& operator=(tunnel&&) noexcept = default; ~tunnel() { @@ -92,7 +92,7 @@ public: }; using ue_bearer_tunnel_list = srsran::bounded_vector; - explicit gtpu_tunnel_manager(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger); + explicit gtpu_tunnel_manager(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, bool is_nr_); void init(const gtpu_args_t& gtpu_args, pdcp_interface_gtpu* pdcp_); bool has_teid(uint32_t teid) const { return tunnels.contains(teid); } @@ -118,13 +118,16 @@ private: using tunnel_list_t = srsran::static_id_obj_pool; using tunnel_ctxt_it = typename tunnel_list_t::iterator; + // Flag to indicate whether GTPU is used in NR or LTE context. + bool is_nr; + srsran::task_sched_handle task_sched; const gtpu_args_t* gtpu_args = nullptr; pdcp_interface_gtpu* pdcp = nullptr; srslog::basic_logger& logger; std::unordered_map ue_teidin_db; - tunnel_list_t tunnels; + tunnel_list_t tunnels; }; using gtpu_tunnel_state = gtpu_tunnel_manager::tunnel_state; @@ -135,6 +138,7 @@ class gtpu final : public gtpu_interface_rrc, public gtpu_interface_pdcp public: explicit gtpu(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, + bool is_nr_, srsran::socket_manager_itf* rx_socket_handler_); ~gtpu(); @@ -168,6 +172,9 @@ private: srsran::socket_manager_itf* rx_socket_handler = nullptr; srsran::task_queue_handle gtpu_queue; + // Flag to indicate whether GTPU entity is used in NR or LTE context. + bool is_nr; + gtpu_args_t args; std::string gtp_bind_addr; std::string mme_addr; @@ -181,10 +188,10 @@ private: public: explicit m1u_handler(gtpu* gtpu_) : parent(gtpu_), logger(parent->logger) {} ~m1u_handler(); - m1u_handler(const m1u_handler&) = delete; - m1u_handler(m1u_handler&&) = delete; + m1u_handler(const m1u_handler&) = delete; + m1u_handler(m1u_handler&&) = delete; m1u_handler& operator=(const m1u_handler&) = delete; - m1u_handler& operator=(m1u_handler&&) = delete; + m1u_handler& operator=(m1u_handler&&) = delete; bool init(std::string m1u_multiaddr_, std::string m1u_if_addr_); void handle_rx_packet(srsran::unique_byte_buffer_t pdu, const sockaddr_in& addr); diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 269a0ccae..aae832a01 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -36,7 +36,7 @@ enb_stack_lte::enb_stack_lte(srslog::sink& log_sink) : pdcp(&task_sched, pdcp_logger), mac(&task_sched, mac_logger), rlc(rlc_logger), - gtpu(&task_sched, gtpu_logger, &get_rx_io_manager()), + gtpu(&task_sched, gtpu_logger, false, &get_rx_io_manager()), s1ap(&task_sched, s1ap_logger, &get_rx_io_manager()), rrc(&task_sched, bearers), mac_pcap(), diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 764e7c55b..98227563e 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -12,6 +12,7 @@ #include "srsran/upper/gtpu.h" #include "srsenb/hdr/stack/upper/gtpu.h" +#include "srsran/common/common_nr.h" #include "srsran/common/network_utils.h" #include "srsran/common/standard_streams.h" #include "srsran/common/string_helpers.h" @@ -32,9 +33,12 @@ namespace srsenb { #define TEID_IN_FMT "TEID In=0x%x" #define TEID_OUT_FMT "TEID Out=0x%x" -gtpu_tunnel_manager::gtpu_tunnel_manager(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger) : - logger(logger), task_sched(task_sched_), tunnels(1) -{} +gtpu_tunnel_manager::gtpu_tunnel_manager(srsran::task_sched_handle task_sched_, + srslog::basic_logger& logger, + bool is_nr_) : + logger(logger), is_nr(is_nr_), task_sched(task_sched_), tunnels(1) +{ +} void gtpu_tunnel_manager::init(const gtpu_args_t& args, pdcp_interface_gtpu* pdcp_) { @@ -57,7 +61,7 @@ gtpu_tunnel_manager::ue_bearer_tunnel_list* gtpu_tunnel_manager::find_rnti_tunne srsran::span gtpu_tunnel_manager::find_rnti_bearer_tunnels(uint16_t rnti, uint32_t eps_bearer_id) { - if (not is_eps_bearer_id(eps_bearer_id)) { + if ((not is_nr and not is_eps_bearer_id(eps_bearer_id)) or (is_nr and not is_nr_lcid(eps_bearer_id))) { logger.warning("Searching for bearer with invalid eps-BearerID=%d", eps_bearer_id); return {}; } @@ -74,7 +78,7 @@ gtpu_tunnel_manager::find_rnti_bearer_tunnels(uint16_t rnti, uint32_t eps_bearer const gtpu_tunnel* gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t eps_bearer_id, uint32_t teidout, uint32_t spgw_addr) { - if (not is_eps_bearer_id(eps_bearer_id)) { + if ((not is_nr and not is_eps_bearer_id(eps_bearer_id)) or (is_nr and not is_nr_lcid(eps_bearer_id))) { logger.warning("Adding TEID with invalid eps-BearerID=%d", eps_bearer_id); return nullptr; } @@ -351,11 +355,14 @@ void gtpu_tunnel_manager::setup_forwarding(uint32_t rx_teid, uint32_t tx_teid) gtpu::gtpu(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, + bool is_nr_, srsran::socket_manager_itf* rx_socket_handler_) : m1u(this), task_sched(task_sched_), logger(logger), - tunnels(task_sched_, logger), + is_nr(is_nr_), + tunnels(task_sched_, logger, is_nr), + rx_socket_handler(rx_socket_handler_) { gtpu_queue = task_sched.make_task_queue(); diff --git a/srsenb/test/upper/gtpu_test.cc b/srsenb/test/upper/gtpu_test.cc index caa4fdfc8..8b0b9a869 100644 --- a/srsenb/test/upper/gtpu_test.cc +++ b/srsenb/test/upper/gtpu_test.cc @@ -158,7 +158,7 @@ void test_gtpu_tunnel_manager() srsran::task_scheduler task_sched; gtpu_args_t gtpu_args = {}; - gtpu_tunnel_manager tunnels(&task_sched, srslog::fetch_basic_logger("GTPU")); + gtpu_tunnel_manager tunnels(&task_sched, srslog::fetch_basic_logger("GTPU"), false); tunnels.init(gtpu_args, nullptr); TESTASSERT(tunnels.find_tunnel(0) == nullptr); TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_eps_bearer_id).empty()); @@ -235,9 +235,10 @@ int test_gtpu_direct_tunneling(tunnel_test_event event) logger2.set_hex_dump_max_size(2048); srsran::task_scheduler task_sched; dummy_socket_manager senb_rx_sockets, tenb_rx_sockets; - srsenb::gtpu senb_gtpu(&task_sched, logger1, &senb_rx_sockets), tenb_gtpu(&task_sched, logger2, &tenb_rx_sockets); - pdcp_tester senb_pdcp, tenb_pdcp; - gtpu_args_t gtpu_args; + srsenb::gtpu senb_gtpu(&task_sched, logger1, false, &senb_rx_sockets), + tenb_gtpu(&task_sched, logger2, false, &tenb_rx_sockets); + pdcp_tester senb_pdcp, tenb_pdcp; + gtpu_args_t gtpu_args; gtpu_args.gtp_bind_addr = senb_addr_str; gtpu_args.mme_addr = sgw_addr_str; gtpu_args.indirect_tunnel_timeout_msec = std::uniform_int_distribution{500, 2000}(g); @@ -263,7 +264,7 @@ int test_gtpu_direct_tunneling(tunnel_test_event event) props.flush_before_teidin = tenb_teid_in; uint32_t addr_in3; uint32_t dl_tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1_bearer_id, senb_addr, 0, addr_in3, &props).value(); - props = {}; + props = {}; props.forward_from_teidin_present = true; props.forward_from_teidin = senb_teid_in; uint32_t addr_in4; diff --git a/srsgnb/src/stack/gnb_stack_nr.cc b/srsgnb/src/stack/gnb_stack_nr.cc index fdff1c649..764d23887 100644 --- a/srsgnb/src/stack/gnb_stack_nr.cc +++ b/srsgnb/src/stack/gnb_stack_nr.cc @@ -83,7 +83,7 @@ int gnb_stack_nr::init(const gnb_stack_args_t& args_, if (x2_ == nullptr) { // SA mode ngap.reset(new srsenb::ngap(&task_sched, ngap_logger, &srsran::get_rx_io_manager())); - gtpu.reset(new srsenb::gtpu(&task_sched, gtpu_logger, &srsran::get_rx_io_manager())); + gtpu.reset(new srsenb::gtpu(&task_sched, gtpu_logger, true, &srsran::get_rx_io_manager())); gtpu_adapter.reset(new gtpu_pdcp_adapter(gtpu_logger, nullptr, &pdcp, gtpu.get(), *bearer_manager)); } diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc b/srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc index ad2060328..d9c3a3d0a 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc +++ b/srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc @@ -137,7 +137,7 @@ void test_rrc_sa_ngap_integration(ngap_args_t ngap_args) srsran::socket_manager rx_sockets; srsenb::ngap ngap_obj(&task_sched, ngap_logger, &rx_sockets); - srsenb::gtpu gtpu_obj(&task_sched, gtpu_logger, &rx_sockets); + srsenb::gtpu gtpu_obj(&task_sched, gtpu_logger, true, &rx_sockets); gtpu_args_t gtpu_args; gtpu_args.embms_enable = false; From 0d8cae98fdf88f00778dd9bb4cff24b778d3e168 Mon Sep 17 00:00:00 2001 From: herlesupreeth Date: Mon, 6 Feb 2023 17:20:45 +0100 Subject: [PATCH 156/167] ngap: fix GTPU bearer removal --- srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc b/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc index 3ccf297ef..9dab4bb5b 100644 --- a/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc +++ b/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc @@ -15,7 +15,8 @@ namespace srsenb { ngap_ue_bearer_manager::ngap_ue_bearer_manager(gtpu_interface_rrc* gtpu_, srslog::basic_logger& logger_) : gtpu(gtpu_), logger(logger_) -{} +{ +} ngap_ue_bearer_manager::~ngap_ue_bearer_manager(){}; int ngap_ue_bearer_manager::add_pdu_session(uint16_t rnti, @@ -62,7 +63,7 @@ int ngap_ue_bearer_manager::reset_pdu_sessions(uint16_t rnti) { for (auto iter = pdu_session_list.begin(); iter != pdu_session_list.end(); iter++) { auto pdu_session_id = iter->first; - rem_gtpu_bearer(pdu_session_id, rnti); + rem_gtpu_bearer(rnti, pdu_session_id); } next_lcid_list.erase(rnti); return true; From 8cac5e9919b6ba85b3580257cfadc52d05659bfb Mon Sep 17 00:00:00 2001 From: herlesupreeth Date: Wed, 8 Feb 2023 18:13:37 +0100 Subject: [PATCH 157/167] ngap,rrc: fix PDU session Id and DRB Id assigned --- srsgnb/hdr/stack/rrc/rrc_nr_ue.h | 2 +- srsgnb/src/stack/rrc/cell_asn1_config.cc | 2 +- srsgnb/src/stack/rrc/rrc_nr_ue.cc | 19 +++++++++++++------ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_ue.h b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h index 84b4566c1..52243082e 100644 --- a/srsgnb/hdr/stack/rrc/rrc_nr_ue.h +++ b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h @@ -186,7 +186,7 @@ private: // MAC controller sched_nr_interface::ue_cfg_t uecfg{}; - const uint32_t drb1_lcid = 4; + const uint32_t drb1_lcid = 4; uint32_t drb1_five_qi = 0; /// selected by 5GC // Security helper diff --git a/srsgnb/src/stack/rrc/cell_asn1_config.cc b/srsgnb/src/stack/rrc/cell_asn1_config.cc index 314811c49..17d99cba0 100644 --- a/srsgnb/src/stack/rrc/cell_asn1_config.cc +++ b/srsgnb/src/stack/rrc/cell_asn1_config.cc @@ -1348,7 +1348,7 @@ int fill_cellgroup_with_radio_bearer_cfg(const rrc_nr_cfg_t& // Add DRBs for (const drb_to_add_mod_s& drb : bearers.drb_to_add_mod_list) { out.rlc_bearer_to_add_mod_list.push_back({}); - uint32_t lcid = drb.drb_id + (int)srsran::nr_srb::count - 1; + uint32_t lcid = drb.drb_id + srsran::MAX_NR_SRB_ID; enb_bearer_manager::radio_bearer_t rb = bearer_mapper.get_lcid_bearer(rnti, lcid); if (rb.is_valid() and cfg.five_qi_cfg.find(rb.five_qi) != cfg.five_qi_cfg.end()) { fill_drb(cfg, rb, (srsran::nr_drb)drb.drb_id, out.rlc_bearer_to_add_mod_list.back()); diff --git a/srsgnb/src/stack/rrc/rrc_nr_ue.cc b/srsgnb/src/stack/rrc/rrc_nr_ue.cc index b7fb7ee6b..ac4fbe685 100644 --- a/srsgnb/src/stack/rrc/rrc_nr_ue.cc +++ b/srsgnb/src/stack/rrc/rrc_nr_ue.cc @@ -1340,29 +1340,36 @@ void rrc_nr::ue::establish_eps_bearer(uint32_t pdu_session_id, nas_pdu_queue.push_back(std::move(pdu)); // Add SRB2, if not yet added - if (radio_bearer_cfg.srb_to_add_mod_list.size() <= 1) { + asn1::rrc_nr::srb_to_add_mod_s* srb_it = + std::find_if(radio_bearer_cfg.srb_to_add_mod_list.begin(), + radio_bearer_cfg.srb_to_add_mod_list.end(), + [](const asn1::rrc_nr::srb_to_add_mod_s& srb) { return srb.srb_id == 2; }); + + if (srb_it == radio_bearer_cfg.srb_to_add_mod_list.end()) { next_radio_bearer_cfg.srb_to_add_mod_list.push_back(srb_to_add_mod_s{}); next_radio_bearer_cfg.srb_to_add_mod_list.back().srb_id = 2; } drb_to_add_mod_s drb; drb.cn_assoc_present = true; - drb.cn_assoc.set_sdap_cfg().pdu_session = 1; + drb.cn_assoc.set_sdap_cfg().pdu_session = pdu_session_id; drb.cn_assoc.sdap_cfg().sdap_hdr_dl.value = asn1::rrc_nr::sdap_cfg_s::sdap_hdr_dl_opts::absent; drb.cn_assoc.sdap_cfg().sdap_hdr_ul.value = asn1::rrc_nr::sdap_cfg_s::sdap_hdr_ul_opts::absent; drb.cn_assoc.sdap_cfg().default_drb = true; drb.cn_assoc.sdap_cfg().mapped_qos_flows_to_add.resize(1); drb.cn_assoc.sdap_cfg().mapped_qos_flows_to_add[0] = 1; - drb.drb_id = 1; + drb.drb_id = lcid - srsran::MAX_NR_SRB_ID; drb.pdcp_cfg_present = true; drb.pdcp_cfg = parent->cfg.five_qi_cfg[five_qi].pdcp_cfg; next_radio_bearer_cfg.drb_to_add_mod_list.push_back(drb); - parent->bearer_mapper->add_eps_bearer( - rnti, lcid - 3, srsran::srsran_rat_t::nr, lcid); // TODO: configurable bearer id <-> lcid mapping - parent->bearer_mapper->set_five_qi(rnti, lcid - 3, five_qi); + parent->bearer_mapper->add_eps_bearer(rnti, + pdu_session_id, + srsran::srsran_rat_t::nr, + lcid); // TODO: configurable bearer id <-> lcid mapping + parent->bearer_mapper->set_five_qi(rnti, pdu_session_id, five_qi); // store 5QI for possible reestablishment of DRB drb1_five_qi = five_qi; From dc3c1d3ccc16f2a62905d66c1ab11597131c2ff9 Mon Sep 17 00:00:00 2001 From: herlesupreeth Date: Tue, 21 Mar 2023 09:16:55 +0100 Subject: [PATCH 158/167] gtpu,rrc: use RAN type rather than boolean --- srsenb/hdr/stack/upper/gtpu.h | 14 ++++++----- srsenb/src/stack/enb_stack_lte.cc | 2 +- srsenb/src/stack/upper/gtpu.cc | 24 ++++++++++++------- srsenb/test/upper/gtpu_test.cc | 6 ++--- srsgnb/src/stack/gnb_stack_nr.cc | 2 +- srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc | 2 +- 6 files changed, 30 insertions(+), 20 deletions(-) diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index 00019144f..6114a14d9 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -92,7 +92,9 @@ public: }; using ue_bearer_tunnel_list = srsran::bounded_vector; - explicit gtpu_tunnel_manager(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, bool is_nr_); + explicit gtpu_tunnel_manager(srsran::task_sched_handle task_sched_, + srslog::basic_logger& logger, + srsran::srsran_rat_t ran_type_); void init(const gtpu_args_t& gtpu_args, pdcp_interface_gtpu* pdcp_); bool has_teid(uint32_t teid) const { return tunnels.contains(teid); } @@ -118,8 +120,8 @@ private: using tunnel_list_t = srsran::static_id_obj_pool; using tunnel_ctxt_it = typename tunnel_list_t::iterator; - // Flag to indicate whether GTPU is used in NR or LTE context. - bool is_nr; + // Used to differentiate whether GTPU is used in NR or LTE context. + srsran::srsran_rat_t ran_type; srsran::task_sched_handle task_sched; const gtpu_args_t* gtpu_args = nullptr; @@ -138,7 +140,7 @@ class gtpu final : public gtpu_interface_rrc, public gtpu_interface_pdcp public: explicit gtpu(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, - bool is_nr_, + srsran::srsran_rat_t ran_type_, srsran::socket_manager_itf* rx_socket_handler_); ~gtpu(); @@ -172,8 +174,8 @@ private: srsran::socket_manager_itf* rx_socket_handler = nullptr; srsran::task_queue_handle gtpu_queue; - // Flag to indicate whether GTPU entity is used in NR or LTE context. - bool is_nr; + // Used to differentiate whether GTPU is used in NR or LTE context. + srsran::srsran_rat_t ran_type; gtpu_args_t args; std::string gtp_bind_addr; diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index aae832a01..ee45e8e4d 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -36,7 +36,7 @@ enb_stack_lte::enb_stack_lte(srslog::sink& log_sink) : pdcp(&task_sched, pdcp_logger), mac(&task_sched, mac_logger), rlc(rlc_logger), - gtpu(&task_sched, gtpu_logger, false, &get_rx_io_manager()), + gtpu(&task_sched, gtpu_logger, srsran::srsran_rat_t::lte, &get_rx_io_manager()), s1ap(&task_sched, s1ap_logger, &get_rx_io_manager()), rrc(&task_sched, bearers), mac_pcap(), diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 98227563e..17e8b29af 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -35,8 +35,8 @@ namespace srsenb { gtpu_tunnel_manager::gtpu_tunnel_manager(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, - bool is_nr_) : - logger(logger), is_nr(is_nr_), task_sched(task_sched_), tunnels(1) + srsran::srsran_rat_t ran_type_) : + logger(logger), ran_type(ran_type_), task_sched(task_sched_), tunnels(1) { } @@ -61,7 +61,11 @@ gtpu_tunnel_manager::ue_bearer_tunnel_list* gtpu_tunnel_manager::find_rnti_tunne srsran::span gtpu_tunnel_manager::find_rnti_bearer_tunnels(uint16_t rnti, uint32_t eps_bearer_id) { - if ((not is_nr and not is_eps_bearer_id(eps_bearer_id)) or (is_nr and not is_nr_lcid(eps_bearer_id))) { + if (ran_type == srsran::srsran_rat_t::lte and not is_eps_bearer_id(eps_bearer_id)) { + logger.warning("Searching for bearer with invalid eps-BearerID=%d", eps_bearer_id); + return {}; + } + if (ran_type == srsran::srsran_rat_t::nr and not is_nr_lcid(eps_bearer_id)) { logger.warning("Searching for bearer with invalid eps-BearerID=%d", eps_bearer_id); return {}; } @@ -78,9 +82,13 @@ gtpu_tunnel_manager::find_rnti_bearer_tunnels(uint16_t rnti, uint32_t eps_bearer const gtpu_tunnel* gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t eps_bearer_id, uint32_t teidout, uint32_t spgw_addr) { - if ((not is_nr and not is_eps_bearer_id(eps_bearer_id)) or (is_nr and not is_nr_lcid(eps_bearer_id))) { + if (ran_type == srsran::srsran_rat_t::lte and not is_eps_bearer_id(eps_bearer_id)) { logger.warning("Adding TEID with invalid eps-BearerID=%d", eps_bearer_id); - return nullptr; + return {}; + } + if (ran_type == srsran::srsran_rat_t::nr and not is_nr_lcid(eps_bearer_id)) { + logger.warning("Adding TEID with invalid eps-BearerID=%d", eps_bearer_id); + return {}; } auto ret_pair = tunnels.insert(tunnel()); if (not ret_pair) { @@ -355,13 +363,13 @@ void gtpu_tunnel_manager::setup_forwarding(uint32_t rx_teid, uint32_t tx_teid) gtpu::gtpu(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, - bool is_nr_, + srsran::srsran_rat_t ran_type_, srsran::socket_manager_itf* rx_socket_handler_) : m1u(this), task_sched(task_sched_), logger(logger), - is_nr(is_nr_), - tunnels(task_sched_, logger, is_nr), + ran_type(ran_type_), + tunnels(task_sched_, logger, ran_type), rx_socket_handler(rx_socket_handler_) { diff --git a/srsenb/test/upper/gtpu_test.cc b/srsenb/test/upper/gtpu_test.cc index 8b0b9a869..41681ea39 100644 --- a/srsenb/test/upper/gtpu_test.cc +++ b/srsenb/test/upper/gtpu_test.cc @@ -158,7 +158,7 @@ void test_gtpu_tunnel_manager() srsran::task_scheduler task_sched; gtpu_args_t gtpu_args = {}; - gtpu_tunnel_manager tunnels(&task_sched, srslog::fetch_basic_logger("GTPU"), false); + gtpu_tunnel_manager tunnels(&task_sched, srslog::fetch_basic_logger("GTPU"), srsran::srsran_rat_t::lte); tunnels.init(gtpu_args, nullptr); TESTASSERT(tunnels.find_tunnel(0) == nullptr); TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_eps_bearer_id).empty()); @@ -235,8 +235,8 @@ int test_gtpu_direct_tunneling(tunnel_test_event event) logger2.set_hex_dump_max_size(2048); srsran::task_scheduler task_sched; dummy_socket_manager senb_rx_sockets, tenb_rx_sockets; - srsenb::gtpu senb_gtpu(&task_sched, logger1, false, &senb_rx_sockets), - tenb_gtpu(&task_sched, logger2, false, &tenb_rx_sockets); + srsenb::gtpu senb_gtpu(&task_sched, logger1, srsran::srsran_rat_t::lte, &senb_rx_sockets), + tenb_gtpu(&task_sched, logger2, srsran::srsran_rat_t::lte, &tenb_rx_sockets); pdcp_tester senb_pdcp, tenb_pdcp; gtpu_args_t gtpu_args; gtpu_args.gtp_bind_addr = senb_addr_str; diff --git a/srsgnb/src/stack/gnb_stack_nr.cc b/srsgnb/src/stack/gnb_stack_nr.cc index 764d23887..5649d98c3 100644 --- a/srsgnb/src/stack/gnb_stack_nr.cc +++ b/srsgnb/src/stack/gnb_stack_nr.cc @@ -83,7 +83,7 @@ int gnb_stack_nr::init(const gnb_stack_args_t& args_, if (x2_ == nullptr) { // SA mode ngap.reset(new srsenb::ngap(&task_sched, ngap_logger, &srsran::get_rx_io_manager())); - gtpu.reset(new srsenb::gtpu(&task_sched, gtpu_logger, true, &srsran::get_rx_io_manager())); + gtpu.reset(new srsenb::gtpu(&task_sched, gtpu_logger, srsran::srsran_rat_t::nr, &srsran::get_rx_io_manager())); gtpu_adapter.reset(new gtpu_pdcp_adapter(gtpu_logger, nullptr, &pdcp, gtpu.get(), *bearer_manager)); } diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc b/srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc index d9c3a3d0a..e467bc993 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc +++ b/srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc @@ -137,7 +137,7 @@ void test_rrc_sa_ngap_integration(ngap_args_t ngap_args) srsran::socket_manager rx_sockets; srsenb::ngap ngap_obj(&task_sched, ngap_logger, &rx_sockets); - srsenb::gtpu gtpu_obj(&task_sched, gtpu_logger, true, &rx_sockets); + srsenb::gtpu gtpu_obj(&task_sched, gtpu_logger, srsran::srsran_rat_t::nr, &rx_sockets); gtpu_args_t gtpu_args; gtpu_args.embms_enable = false; From 05f018b1634dc1fc19fc7edf5fa1031593ad1c65 Mon Sep 17 00:00:00 2001 From: herlesupreeth Date: Tue, 21 Mar 2023 09:21:51 +0100 Subject: [PATCH 159/167] gtpu: fix return value --- srsenb/src/stack/upper/gtpu.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 17e8b29af..1cfdba525 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -84,11 +84,11 @@ gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t eps_bearer_id, uint32_t { if (ran_type == srsran::srsran_rat_t::lte and not is_eps_bearer_id(eps_bearer_id)) { logger.warning("Adding TEID with invalid eps-BearerID=%d", eps_bearer_id); - return {}; + return nullptr; } if (ran_type == srsran::srsran_rat_t::nr and not is_nr_lcid(eps_bearer_id)) { logger.warning("Adding TEID with invalid eps-BearerID=%d", eps_bearer_id); - return {}; + return nullptr; } auto ret_pair = tunnels.insert(tunnel()); if (not ret_pair) { From 150bfb6185e628feaabf0072f2cbdaef625b1a7f Mon Sep 17 00:00:00 2001 From: herlesupreeth Date: Thu, 23 Mar 2023 17:18:02 +0100 Subject: [PATCH 160/167] gtpu,ngap: fix pdu session id check and lcid allocation --- lib/include/srsran/common/common_nr.h | 9 ++++++++ srsenb/hdr/stack/upper/gtpu.h | 2 +- srsenb/src/stack/upper/gtpu.cc | 8 +++---- .../hdr/stack/ngap/ngap_ue_bearer_manager.h | 2 -- .../src/stack/ngap/ngap_ue_bearer_manager.cc | 22 +++++++++++++++---- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/lib/include/srsran/common/common_nr.h b/lib/include/srsran/common/common_nr.h index 889046bc7..fc23fc691 100644 --- a/lib/include/srsran/common/common_nr.h +++ b/lib/include/srsran/common/common_nr.h @@ -57,6 +57,15 @@ enum class nr_drb { const uint32_t MAX_NR_DRB_ID = 29; const uint32_t MAX_NR_NOF_BEARERS = MAX_NR_DRB_ID + MAX_NR_SRB_ID; // 32 +// PDU Session ID range [1, 15]. See TS 24.007, 11.2.3.1b. +const uint32_t MAX_NR_PDU_SESSION_ID = 15; +const uint32_t MIN_NR_PDU_SESSION_ID = 1; + +constexpr bool is_nr_pdu_session_id(uint32_t pdu_session_id) +{ + return pdu_session_id >= MIN_NR_PDU_SESSION_ID and pdu_session_id <= MAX_NR_PDU_SESSION_ID; +} + constexpr bool is_nr_lcid(uint32_t lcid) { return lcid < MAX_NR_NOF_BEARERS; diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index 6114a14d9..001ebb2a4 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -49,7 +49,7 @@ class gtpu_tunnel_manager public: // A UE should have <= 3 DRBs active, and each DRB should have two tunnels active at the same time at most - const static size_t MAX_TUNNELS_PER_UE = 32; + const static size_t MAX_TUNNELS_PER_UE = 10; enum class tunnel_state { pdcp_active, buffering, forward_to, forwarded_from, inactive }; diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 1cfdba525..74bf0e6b0 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -65,8 +65,8 @@ gtpu_tunnel_manager::find_rnti_bearer_tunnels(uint16_t rnti, uint32_t eps_bearer logger.warning("Searching for bearer with invalid eps-BearerID=%d", eps_bearer_id); return {}; } - if (ran_type == srsran::srsran_rat_t::nr and not is_nr_lcid(eps_bearer_id)) { - logger.warning("Searching for bearer with invalid eps-BearerID=%d", eps_bearer_id); + if (ran_type == srsran::srsran_rat_t::nr and not is_nr_pdu_session_id(eps_bearer_id)) { + logger.warning("Searching for bearer with invalid PDU Session Id=%d", eps_bearer_id); return {}; } auto* ue_ptr = find_rnti_tunnels(rnti); @@ -86,8 +86,8 @@ gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t eps_bearer_id, uint32_t logger.warning("Adding TEID with invalid eps-BearerID=%d", eps_bearer_id); return nullptr; } - if (ran_type == srsran::srsran_rat_t::nr and not is_nr_lcid(eps_bearer_id)) { - logger.warning("Adding TEID with invalid eps-BearerID=%d", eps_bearer_id); + if (ran_type == srsran::srsran_rat_t::nr and not is_nr_pdu_session_id(eps_bearer_id)) { + logger.warning("Adding TEID with invalid PDU Session Id=%d", eps_bearer_id); return nullptr; } auto ret_pair = tunnels.insert(tunnel()); diff --git a/srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h b/srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h index 31ceaac77..66f49b983 100644 --- a/srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h +++ b/srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h @@ -64,8 +64,6 @@ private: pdu_session_list_t pdu_session_list; srslog::basic_logger& logger; - std::map next_lcid_list; // Map RNTI to next LCID to be allocated - int add_gtpu_bearer(uint16_t rnti, uint32_t pdu_session_id, uint32_t teid_out, diff --git a/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc b/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc index 9dab4bb5b..4b6f59f0d 100644 --- a/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc +++ b/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc @@ -11,6 +11,7 @@ */ #include "srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h" +#include "srsran/common/common_nr.h" namespace srsenb { ngap_ue_bearer_manager::ngap_ue_bearer_manager(gtpu_interface_rrc* gtpu_, srslog::basic_logger& logger_) : @@ -39,6 +40,10 @@ int ngap_ue_bearer_manager::add_pdu_session(uint16_t } lcid = allocate_lcid(rnti); + if (lcid >= srsran::MAX_NR_NOF_BEARERS) { + logger.error("Adding PDU Session ID=%d to GTPU. No free LCID.", pdu_session_id); + return SRSRAN_ERROR; + } // TODO: remove lcid and just use pdu_session_id and rnti as id for GTP tunnel int rtn = add_gtpu_bearer(rnti, pdu_session_id, teid_out, addr_out, tunnel); @@ -65,7 +70,6 @@ int ngap_ue_bearer_manager::reset_pdu_sessions(uint16_t rnti) auto pdu_session_id = iter->first; rem_gtpu_bearer(rnti, pdu_session_id); } - next_lcid_list.erase(rnti); return true; } @@ -116,10 +120,20 @@ void ngap_ue_bearer_manager::rem_gtpu_bearer(uint16_t rnti, uint32_t pdu_session uint8_t ngap_ue_bearer_manager::allocate_lcid(uint32_t rnti) { - if (next_lcid_list.find(rnti) == next_lcid_list.end()) { - next_lcid_list[rnti] = 4; + if (pdu_session_list.empty()) { + return 4; + } + for (unsigned lcid = 4; lcid < srsran::MAX_NR_NOF_BEARERS; lcid++) { + const auto pdu_session_it = + std::find_if(pdu_session_list.cbegin(), + pdu_session_list.cend(), + [lcid](const std::pair& t) { return t.second.lcid != lcid; }); + if (pdu_session_it != pdu_session_list.cend()) { + return lcid; + } } - return next_lcid_list[rnti]++; + // All LCIDs are used. + return srsran::MAX_NR_NOF_BEARERS; } } // namespace srsenb From ac2d0beedd907d15a7ead0e33a34959eb7964cc5 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 11 Apr 2023 10:32:24 +0200 Subject: [PATCH 161/167] sched: use circular buffer instead of deque to handle pending RACHs --- srsenb/hdr/stack/mac/sched_carrier.h | 7 ++++--- srsenb/src/stack/mac/sched_carrier.cc | 29 ++++++++++++++++++--------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/srsenb/hdr/stack/mac/sched_carrier.h b/srsenb/hdr/stack/mac/sched_carrier.h index 96c732e58..d4588d5cd 100644 --- a/srsenb/hdr/stack/mac/sched_carrier.h +++ b/srsenb/hdr/stack/mac/sched_carrier.h @@ -15,6 +15,7 @@ #include "sched.h" #include "schedulers/sched_base.h" +#include "srsran/adt/circular_buffer.h" #include "srsran/adt/pool/cached_alloc.h" #include "srsran/srslog/srslog.h" @@ -131,9 +132,9 @@ private: const sched_cell_params_t* cc_cfg = nullptr; sched_ue_list* ue_db = nullptr; - srsran::deque pending_rars; - uint32_t rar_aggr_level = 2; - static const uint32_t PRACH_RAR_OFFSET = 3; // TS 36.321 Sec. 5.1.4 + srsran::dyn_circular_buffer pending_rars; + uint32_t rar_aggr_level = 2; + static const uint32_t PRACH_RAR_OFFSET = 3; // TS 36.321 Sec. 5.1.4 }; } // namespace srsenb diff --git a/srsenb/src/stack/mac/sched_carrier.cc b/srsenb/src/stack/mac/sched_carrier.cc index 0e0d5ef62..bdc6a3a7a 100644 --- a/srsenb/src/stack/mac/sched_carrier.cc +++ b/srsenb/src/stack/mac/sched_carrier.cc @@ -28,7 +28,8 @@ using srsran::tti_point; bc_sched::bc_sched(const sched_cell_params_t& cfg_, srsenb::rrc_interface_mac* rrc_) : cc_cfg(&cfg_), rrc(rrc_), logger(srslog::fetch_basic_logger("MAC")) -{} +{ +} void bc_sched::dl_sched(sf_sched* tti_sched) { @@ -169,8 +170,9 @@ void bc_sched::reset() *******************************************************/ ra_sched::ra_sched(const sched_cell_params_t& cfg_, sched_ue_list& ue_db_) : - cc_cfg(&cfg_), logger(srslog::fetch_basic_logger("MAC")), ue_db(&ue_db_) -{} + cc_cfg(&cfg_), logger(srslog::fetch_basic_logger("MAC")), ue_db(&ue_db_), pending_rars(16) +{ +} alloc_result ra_sched::allocate_pending_rar(sf_sched* tti_sched, const pending_rar_t& rar, uint32_t& nof_grants_alloc) { @@ -205,8 +207,10 @@ void ra_sched::dl_sched(sf_sched* tti_sched) tti_point tti_tx_dl = tti_sched->get_tti_tx_dl(); rar_aggr_level = 2; - for (auto it = pending_rars.begin(); it != pending_rars.end();) { - auto& rar = *it; + for (auto& rar : pending_rars) { + if (rar.msg3_grant.empty()) { + continue; + } // In case of RAR outside RAR window: // - if window has passed, discard RAR @@ -223,7 +227,7 @@ void ra_sched::dl_sched(sf_sched* tti_sched) tti_tx_dl); srsran::console("%s\n", srsran::to_c_str(str_buffer)); logger.warning("%s", srsran::to_c_str(str_buffer)); - it = pending_rars.erase(it); + rar.msg3_grant.clear(); // mark as handled. continue; } return; @@ -239,7 +243,7 @@ void ra_sched::dl_sched(sf_sched* tti_sched) // - otherwise, erase only Msg3 grants that were allocated, and stop iteration if (nof_rar_allocs == rar.msg3_grant.size()) { - it = pending_rars.erase(it); + rar.msg3_grant.clear(); // mark as handled. } else { std::copy(rar.msg3_grant.begin() + nof_rar_allocs, rar.msg3_grant.end(), rar.msg3_grant.begin()); rar.msg3_grant.resize(rar.msg3_grant.size() - nof_rar_allocs); @@ -252,9 +256,13 @@ void ra_sched::dl_sched(sf_sched* tti_sched) if (ret != alloc_result::no_cch_space) { break; } - ++it; } } + + // Pop elements at the front that have been handled. + while (not pending_rars.empty() and pending_rars.begin()->msg3_grant.empty()) { + pending_rars.pop(); + } } int ra_sched::dl_rach_info(dl_sched_rar_info_t rar_info) @@ -287,7 +295,10 @@ int ra_sched::dl_rach_info(dl_sched_rar_info_t rar_info) p.ra_rnti = ra_rnti; p.prach_tti = tti_point{rar_info.prach_tti}; p.msg3_grant.push_back(rar_info); - pending_rars.push_back(p); + if (not pending_rars.try_push(p)) { + logger.warning("SCHED: Unable to handle RAR ra-rnti=0x%x, as the maximum number of pending RARs has been reached", + ra_rnti); + } return SRSRAN_SUCCESS; } From ec9812e72da58d72b72464b47758461c0446d23a Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 11 Apr 2023 10:53:58 +0200 Subject: [PATCH 162/167] sched: handle failure to schedule RAR --- srsenb/src/stack/mac/mac.cc | 5 ++++- srsenb/src/stack/mac/sched_carrier.cc | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 1be0ab51f..13fa596e2 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -598,7 +598,10 @@ void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx } // Trigger scheduler RACH - scheduler.dl_rach_info(enb_cc_idx, rar_info); + if (scheduler.dl_rach_info(enb_cc_idx, rar_info) != SRSRAN_SUCCESS) { + ue_rem(rnti); + return; + } auto get_pci = [this, enb_cc_idx]() { srsran::rwlock_read_guard lock(rwlock); diff --git a/srsenb/src/stack/mac/sched_carrier.cc b/srsenb/src/stack/mac/sched_carrier.cc index bdc6a3a7a..130e99e40 100644 --- a/srsenb/src/stack/mac/sched_carrier.cc +++ b/srsenb/src/stack/mac/sched_carrier.cc @@ -298,6 +298,7 @@ int ra_sched::dl_rach_info(dl_sched_rar_info_t rar_info) if (not pending_rars.try_push(p)) { logger.warning("SCHED: Unable to handle RAR ra-rnti=0x%x, as the maximum number of pending RARs has been reached", ra_rnti); + return SRSRAN_ERROR; } return SRSRAN_SUCCESS; From 7251d4dcd2c2bddd33b331f554b2d645772fa406 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 26 Jul 2022 15:34:22 +0200 Subject: [PATCH 163/167] gnb: fix CSI-IM resource information in RRC recnofig for NSA amariue was complaining about CSI-IM resources allocated but not present in resource config. 15:36:05.604 [RRC] - 0002 - DCCH: CellGroupConfig: ERROR: CSI-IM Set resource #0 not found in CSI Resource config #1 the patch simply removes the CSI-IM config. --- srsgnb/src/stack/rrc/cell_asn1_config.cc | 29 +++++++++--------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/srsgnb/src/stack/rrc/cell_asn1_config.cc b/srsgnb/src/stack/rrc/cell_asn1_config.cc index 17d99cba0..6d8677fe6 100644 --- a/srsgnb/src/stack/rrc/cell_asn1_config.cc +++ b/srsgnb/src/stack/rrc/cell_asn1_config.cc @@ -419,25 +419,21 @@ void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_m void fill_csi_resource_cfg_to_add(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) { if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - csi_meas_cfg.csi_res_cfg_to_add_mod_list.resize(3); + csi_meas_cfg.csi_res_cfg_to_add_mod_list.resize(2); - csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].csi_res_cfg_id = 0; - auto& nzp = csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].csi_rs_res_set_list.set_nzp_csi_rs_ssb(); + auto& res0 = csi_meas_cfg.csi_res_cfg_to_add_mod_list[0]; + res0.csi_res_cfg_id = 0; + res0.bwp_id = 0; + res0.res_type.value = csi_res_cfg_s::res_type_opts::periodic; + auto& nzp = res0.csi_rs_res_set_list.set_nzp_csi_rs_ssb(); nzp.nzp_csi_rs_res_set_list.push_back(0); - csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].bwp_id = 0; - csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].res_type.value = csi_res_cfg_s::res_type_opts::periodic; - csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].csi_res_cfg_id = 1; - auto& im_res = csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].csi_rs_res_set_list.set_csi_im_res_set_list(); - im_res.push_back(0); - csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].bwp_id = 0; - csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].res_type.value = csi_res_cfg_s::res_type_opts::periodic; - - csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].csi_res_cfg_id = 2; - auto& nzp2 = csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].csi_rs_res_set_list.set_nzp_csi_rs_ssb(); + auto& res2 = csi_meas_cfg.csi_res_cfg_to_add_mod_list[1]; + res2.csi_res_cfg_id = 1; + res2.bwp_id = 0; + res2.res_type.value = csi_res_cfg_s::res_type_opts::periodic; + auto& nzp2 = res2.csi_rs_res_set_list.set_nzp_csi_rs_ssb(); nzp2.nzp_csi_rs_res_set_list.push_back(1); - csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].bwp_id = 0; - csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].res_type.value = csi_res_cfg_s::res_type_opts::periodic; } } @@ -489,9 +485,6 @@ int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas fill_nzp_csi_rs_from_enb_cfg(cfg, csi_meas_cfg); if (cfg.is_standalone) { - // CSI IM config - fill_csi_im_resource_cfg_to_add(cfg, csi_meas_cfg); - // CSI report config fill_csi_report_from_enb_cfg(cfg, csi_meas_cfg); } From 45a04b715c017edee59329e5d2d3b85be8834c31 Mon Sep 17 00:00:00 2001 From: yagoda Date: Thu, 20 Apr 2023 11:25:07 +0200 Subject: [PATCH 164/167] e2ap: freeing heap allocated random object --- srsgnb/hdr/stack/ric/e2sm_kpm.h | 2 +- srsgnb/src/stack/ric/e2sm_kpm.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h index ba1d88d5b..77583ca08 100644 --- a/srsgnb/hdr/stack/ric/e2sm_kpm.h +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -35,7 +35,7 @@ public: static const uint32_t revision; e2sm_kpm(srslog::basic_logger& logger_, srsran::task_scheduler* _task_sched_ptr); - ~e2sm_kpm() = default; + ~e2sm_kpm(); virtual bool generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func); virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc index f9ab99b21..4d05700b3 100644 --- a/srsgnb/src/stack/ric/e2sm_kpm.cc +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -49,6 +49,10 @@ e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_, srsran::task_scheduler* _task_ } } +e2sm_kpm::~e2sm_kpm() +{ + srsran_random_free(random_gen); +} bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func) { desc.function_shortname = short_name; From 3d9e0cb840ca76554323ab32a7704ff257058f61 Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 24 Feb 2023 13:27:56 +0100 Subject: [PATCH 165/167] sched: fix total number of PRBs allocated to msg3 --- srsenb/src/stack/mac/sched_grid.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/sched_grid.cc b/srsenb/src/stack/mac/sched_grid.cc index 126c11aab..0cbeeea4f 100644 --- a/srsenb/src/stack/mac/sched_grid.cc +++ b/srsenb/src/stack/mac/sched_grid.cc @@ -439,7 +439,7 @@ alloc_result sf_sched::alloc_rar(uint32_t aggr_lvl, const pending_rar_t& rar, rb rar_alloc.alloc_data.rbg_range = rbgs; rar_alloc.alloc_data.req_bytes = buf_rar; rar_allocs.push_back(rar_alloc); - last_msg3_prb += total_ul_nof_prbs * nof_grants; + last_msg3_prb += total_ul_nof_prbs; return ret; } From 2a2d6ca6b28b56691581fdefc23ab419496cae5d Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 21 Apr 2023 11:25:12 +0200 Subject: [PATCH 166/167] e2ap: fix tsan issue, stop e2_agent thread --- srsenb/src/enb.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 2c5299db7..32cc474df 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -151,6 +151,10 @@ void enb::stop() { if (started) { // tear down in reverse order + if (_e2_agent) { + _e2_agent->stop(); + } + if (phy) { phy->stop(); } From 0f628ca28fc405fccea744c32839d6c5659f2a8a Mon Sep 17 00:00:00 2001 From: Piotr Gawlowicz Date: Fri, 21 Apr 2023 15:09:32 +0200 Subject: [PATCH 167/167] ue,rrc: test packing of UE Caps with r15 -> increase ue cap info buffer size --- lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc | 350 ++++++++++++++++++ srsue/src/stack/rrc/rrc.cc | 2 +- 2 files changed, 351 insertions(+), 1 deletion(-) diff --git a/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc b/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc index db4ac82f2..63462c9e7 100644 --- a/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc +++ b/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc @@ -118,6 +118,352 @@ int rrc_ue_cap_info_test(srsran::mac_pcap* pcap) return 0; } +int rrc_ue_cap_info_pack_buff_size_test(srsran::mac_pcap* pcap, const uint32_t buf_size) +{ + auto& rrc_logger = srslog::fetch_basic_logger("RRC", false); + rrc_logger.set_level(srslog::basic_levels::debug); + rrc_logger.set_hex_dump_max_size(128); + + srsue::rrc_args_t args = {}; + args.ue_category = 8; + args.ue_category_ul = 5; + args.ue_category_dl = 14; + args.release = 15; + args.feature_group = 0xe6041c00; + args.nof_supported_bands = 1; + args.supported_bands[0] = 8; + args.nof_lte_carriers = 4; + args.nof_nr_carriers = 0; + args.support_ca = true; + args.supported_bands_nr.push_back(3); + + asn1::rrc::ul_dcch_msg_s ul_dcch_msg; + ul_dcch_msg.msg.set(ul_dcch_msg_type_c::types::c1); + ul_dcch_msg.msg.c1().set(ul_dcch_msg_type_c::c1_c_::types::ue_cap_info); + ul_dcch_msg.msg.c1().ue_cap_info().rrc_transaction_id = 0; + + ul_dcch_msg.msg.c1().ue_cap_info().crit_exts.set(ue_cap_info_s::crit_exts_c_::types::c1); + ul_dcch_msg.msg.c1().ue_cap_info().crit_exts.c1().set(ue_cap_info_s::crit_exts_c_::c1_c_::types::ue_cap_info_r8); + ue_cap_info_r8_ies_s* info = &ul_dcch_msg.msg.c1().ue_cap_info().crit_exts.c1().ue_cap_info_r8(); + info->ue_cap_rat_container_list.resize(1); + info->ue_cap_rat_container_list[0].rat_type = rat_type_e::eutra; + + ue_eutra_cap_s cap; + cap.access_stratum_release = (access_stratum_release_e::options)(args.release - SRSRAN_RELEASE_MIN); + cap.ue_category = (uint8_t)((args.ue_category < 1 || args.ue_category > 5) ? 4 : args.ue_category); + cap.pdcp_params.max_num_rohc_context_sessions_present = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0001_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0002_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0003_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0004_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0006_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0101_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0102_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0103_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0104_r15 = false; + + cap.phy_layer_params.ue_specific_ref_sigs_supported = false; + cap.phy_layer_params.ue_tx_ant_sel_supported = false; + + cap.rf_params.supported_band_list_eutra.resize(args.nof_supported_bands); + cap.meas_params.band_list_eutra.resize(args.nof_supported_bands); + for (uint32_t k = 0; k < args.nof_supported_bands; k++) { + cap.rf_params.supported_band_list_eutra[k].band_eutra = args.supported_bands[k]; + cap.rf_params.supported_band_list_eutra[k].half_duplex = false; + cap.meas_params.band_list_eutra[k].inter_freq_band_list.resize(1); + cap.meas_params.band_list_eutra[k].inter_freq_band_list[0].inter_freq_need_for_gaps = true; + } + + cap.feature_group_inds_present = true; + cap.feature_group_inds.from_number(args.feature_group); + + ue_eutra_cap_v1280_ies_s* ue_eutra_cap_v1280_ies; + ue_eutra_cap_v1360_ies_s* ue_eutra_cap_v1360_ies; + ue_eutra_cap_v1450_ies_s* ue_eutra_cap_v1450_ies; + if (args.release > 8) { + ue_eutra_cap_v920_ies_s cap_v920; + + cap_v920.phy_layer_params_v920.enhanced_dual_layer_fdd_r9_present = false; + cap_v920.phy_layer_params_v920.enhanced_dual_layer_tdd_r9_present = false; + cap_v920.inter_rat_params_geran_v920.dtm_r9_present = false; + cap_v920.inter_rat_params_geran_v920.e_redirection_geran_r9_present = false; + cap_v920.csg_proximity_ind_params_r9.inter_freq_proximity_ind_r9_present = false; + cap_v920.csg_proximity_ind_params_r9.intra_freq_proximity_ind_r9_present = false; + cap_v920.csg_proximity_ind_params_r9.utran_proximity_ind_r9_present = false; + cap_v920.neigh_cell_si_acquisition_params_r9.inter_freq_si_acquisition_for_ho_r9_present = false; + cap_v920.neigh_cell_si_acquisition_params_r9.intra_freq_si_acquisition_for_ho_r9_present = false; + cap_v920.neigh_cell_si_acquisition_params_r9.utran_si_acquisition_for_ho_r9_present = false; + cap_v920.son_params_r9.rach_report_r9_present = false; + + cap.non_crit_ext_present = true; + cap.non_crit_ext = cap_v920; + } + + if (args.release > 9) { + phy_layer_params_v1020_s phy_layer_params_v1020; + phy_layer_params_v1020.two_ant_ports_for_pucch_r10_present = false; + phy_layer_params_v1020.tm9_with_minus8_tx_fdd_r10_present = false; + phy_layer_params_v1020.pmi_disabling_r10_present = false; + phy_layer_params_v1020.cross_carrier_sched_r10_present = args.support_ca; + phy_layer_params_v1020.simul_pucch_pusch_r10_present = false; + phy_layer_params_v1020.multi_cluster_pusch_within_cc_r10_present = false; + phy_layer_params_v1020.non_contiguous_ul_ra_within_cc_list_r10_present = false; + + rf_params_v1020_s rf_params; + band_combination_params_r10_l combination_params; + if (args.support_ca) { + // add Intra‑band Contiguous or Inter‑band Non-contiguous CA band combination + // note that nof_supported_bands=1 when all cells are in the same but non-contiguous band + for (uint32_t k = 0; k < args.nof_supported_bands; k++) { + ca_mimo_params_dl_r10_s ca_mimo_params_dl; + ca_mimo_params_dl.ca_bw_class_dl_r10 = ca_bw_class_r10_e::f; + ca_mimo_params_dl.supported_mimo_cap_dl_r10_present = false; + + ca_mimo_params_ul_r10_s ca_mimo_params_ul; + ca_mimo_params_ul.ca_bw_class_ul_r10 = ca_bw_class_r10_e::f; + ca_mimo_params_ul.supported_mimo_cap_ul_r10_present = false; + + band_params_r10_s band_params; + band_params.band_eutra_r10 = args.supported_bands[k]; + band_params.band_params_dl_r10_present = true; + band_params.band_params_dl_r10.push_back(ca_mimo_params_dl); + band_params.band_params_ul_r10_present = true; + band_params.band_params_ul_r10.push_back(ca_mimo_params_ul); + + combination_params.push_back(band_params); + } + } + rf_params.supported_band_combination_r10.push_back(combination_params); + + // add all 2CC, 3CC and 4CC Intra‑band Non-contiguous CA band combinations + for (uint32_t k = 0; k < args.nof_supported_bands; k++) { + for (uint32_t j = 2; j <= args.nof_lte_carriers; j++) { + combination_params.clear(); + + ca_mimo_params_dl_r10_s ca_mimo_params_dl; + ca_mimo_params_dl.ca_bw_class_dl_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_dl.supported_mimo_cap_dl_r10_present = false; + + ca_mimo_params_ul_r10_s ca_mimo_params_ul; + ca_mimo_params_ul.ca_bw_class_ul_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_ul.supported_mimo_cap_ul_r10_present = false; + + band_params_r10_s band_params; + band_params.band_eutra_r10 = args.supported_bands[k]; + band_params.band_params_dl_r10_present = true; + band_params.band_params_dl_r10.push_back(ca_mimo_params_dl); + band_params.band_params_ul_r10_present = true; + band_params.band_params_ul_r10.push_back(ca_mimo_params_ul); + + for (uint32_t l = 0; l < j; l++) { + combination_params.push_back(band_params); + } + rf_params.supported_band_combination_r10.push_back(combination_params); + } + } + + ue_eutra_cap_v1020_ies_s cap_v1020; + if (args.ue_category >= 6 && args.ue_category <= 8) { + cap_v1020.ue_category_v1020_present = true; + cap_v1020.ue_category_v1020 = (uint8_t)args.ue_category; + } else { + // Do not populate UE category for this release if the category is out of range + } + cap_v1020.phy_layer_params_v1020_present = true; + cap_v1020.phy_layer_params_v1020 = phy_layer_params_v1020; + cap_v1020.rf_params_v1020_present = args.support_ca; + cap_v1020.rf_params_v1020 = rf_params; + + ue_eutra_cap_v940_ies_s cap_v940; + cap_v940.non_crit_ext_present = true; + cap_v940.non_crit_ext = cap_v1020; + + cap.non_crit_ext.non_crit_ext_present = true; + cap.non_crit_ext.non_crit_ext = cap_v940; + } + + if (args.release > 10) { + ue_eutra_cap_v11a0_ies_s cap_v11a0; + if (args.ue_category >= 11 && args.ue_category <= 12) { + cap_v11a0.ue_category_v11a0 = (uint8_t)args.ue_category; + cap_v11a0.ue_category_v11a0_present = true; + } else { + // Do not populate UE category for this release if the category is out of range + } + + ue_eutra_cap_v1180_ies_s cap_v1180; + cap_v1180.non_crit_ext_present = true; + cap_v1180.non_crit_ext = cap_v11a0; + + ue_eutra_cap_v1170_ies_s cap_v1170; + cap_v1170.non_crit_ext_present = true; + cap_v1170.non_crit_ext = cap_v1180; + if (args.ue_category >= 9 && args.ue_category <= 10) { + cap_v1170.ue_category_v1170 = (uint8_t)args.ue_category; + cap_v1170.ue_category_v1170_present = true; + } else { + // Do not populate UE category for this release if the category is out of range + } + + ue_eutra_cap_v1130_ies_s cap_v1130; + cap_v1130.non_crit_ext_present = true; + cap_v1130.non_crit_ext = cap_v1170; + + ue_eutra_cap_v1090_ies_s cap_v1090; + cap_v1090.non_crit_ext_present = true; + cap_v1090.non_crit_ext = cap_v1130; + + ue_eutra_cap_v1060_ies_s cap_v1060; + cap_v1060.non_crit_ext_present = true; + cap_v1060.non_crit_ext = cap_v1090; + + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext = cap_v1060; + } + + if (args.release > 11) { + supported_band_list_eutra_v1250_l supported_band_list_eutra_v1250; + for (uint32_t k = 0; k < args.nof_supported_bands; k++) { + supported_band_eutra_v1250_s supported_band_eutra_v1250; + // According to 3GPP 36.306 v12 Table 4.1A-1, 256QAM is supported for ue_category_dl 11-16 + supported_band_eutra_v1250.dl_minus256_qam_r12_present = (args.ue_category_dl >= 11); + + // According to 3GPP 36.331 v12 UE-EUTRA-Capability field descriptions + // This field is only present when the field ue-CategoryUL is considered to 5 or 13. + supported_band_eutra_v1250.ul_minus64_qam_r12_present = true; + + supported_band_list_eutra_v1250.push_back(supported_band_eutra_v1250); + } + + rf_params_v1250_s rf_params_v1250; + rf_params_v1250.supported_band_list_eutra_v1250_present = true; + rf_params_v1250.supported_band_list_eutra_v1250 = supported_band_list_eutra_v1250; + + ue_eutra_cap_v1250_ies_s cap_v1250; + + // Optional UE Category UL/DL + // Warning: Make sure the UE Category UL/DL matches with 3GPP 36.306 Table 4.1A-6 + if (args.ue_category_dl >= 0) { + cap_v1250.ue_category_dl_r12_present = true; + cap_v1250.ue_category_dl_r12 = (uint8_t)args.ue_category_dl; + } else { + // Do not populate UE category for this release if the category is not available + } + if (args.ue_category_ul >= 0) { + cap_v1250.ue_category_ul_r12_present = true; + cap_v1250.ue_category_ul_r12 = (uint8_t)args.ue_category_ul; + } else { + // Do not populate UE category for this release if the category is not available + } + cap_v1250.rf_params_v1250_present = true; + cap_v1250.rf_params_v1250 = rf_params_v1250; + + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext_present = true; + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext = cap_v1250; + // 12.50 + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 12.60 + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 12.70 + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + } + // Release 13 + if (args.release > 12) { + // 12.80 + ue_eutra_cap_v1280_ies = + &cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext; + ue_eutra_cap_v1280_ies->non_crit_ext_present = true; + // 13.10 + ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext_present = true; + // 13.20 + ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 13.30 + ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 13.40 + ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 13.50 + ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = + true; + } + // Release 14 + if (args.release > 13) { + // 13.60 + ue_eutra_cap_v1360_ies = + &ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext; + ue_eutra_cap_v1360_ies->non_crit_ext_present = true; + // 14.30 + ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext_present = true; + // 14.40 + ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 14.50 + ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + } + // Release 15 + if (args.release > 14) { + ue_eutra_cap_v1450_ies = &ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext.non_crit_ext; + // 14.60 + ue_eutra_cap_v1450_ies->non_crit_ext_present = true; + ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext_present = true; + + irat_params_nr_r15_s irat_params_nr_r15; + irat_params_nr_r15.en_dc_r15_present = true; + irat_params_nr_r15.supported_band_list_en_dc_r15_present = true; + + uint32_t nof_supported_nr_bands = args.supported_bands_nr.size(); + irat_params_nr_r15.supported_band_list_en_dc_r15.resize(nof_supported_nr_bands); + for (uint32_t k = 0; k < nof_supported_nr_bands; k++) { + irat_params_nr_r15.supported_band_list_en_dc_r15[k].band_nr_r15 = args.supported_bands_nr[k]; + } + + ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext.irat_params_nr_r15_present = true; + ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext.irat_params_nr_r15 = irat_params_nr_r15; + ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext.non_crit_ext_present = true; + + // 15.10 + ue_eutra_cap_v1510_ies_s* ue_cap_enquiry_v1510_ies = &ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext; + ue_cap_enquiry_v1510_ies->pdcp_params_nr_r15_present = true; + ue_cap_enquiry_v1510_ies->pdcp_params_nr_r15.sn_size_lo_r15_present = true; + } + + // Pack caps and copy to cap info + uint8_t buf[128]; + bzero(buf, sizeof(buf)); + asn1::bit_ref bref(buf, buf_size); + if (cap.pack(bref) != asn1::SRSASN_SUCCESS) { + rrc_logger.debug("Error packing EUTRA capabilities"); + return -1; + } + + bref.align_bytes_zero(); + uint32_t cap_len = (uint32_t)bref.distance_bytes(buf); + + info->ue_cap_rat_container_list[0].ue_cap_rat_container.resize(cap_len); + memcpy(info->ue_cap_rat_container_list[0].ue_cap_rat_container.data(), buf, cap_len); + rrc_logger.debug(buf, cap_len, "UE-Cap (%d/%zd B)", cap_len, sizeof(buf)); + + // pack the message + uint8_t byte_buf[512]; + bzero(byte_buf, sizeof(byte_buf)); + asn1::bit_ref bref3(byte_buf, sizeof(byte_buf)); + ul_dcch_msg.pack(bref3); + bref3.align_bytes_zero(); + + uint32_t len = (uint32_t)bref3.distance_bytes(byte_buf); + rrc_logger.debug(byte_buf, len, "UL-DCCH (%d/%zd B)", len, sizeof(byte_buf)); + + if (pcap != NULL) { + pcap->write_ul_rrc_pdu(byte_buf, len); + } + + return 0; +} + int pack_fail_test() { srsue::rrc_args_t args = {}; @@ -320,8 +666,12 @@ int main(int argc, char** argv) srsran::mac_pcap pcap; pcap.open("ul_dcch.pcap"); TESTASSERT(rrc_ue_cap_info_test(&pcap) == 0); + TESTASSERT(rrc_ue_cap_info_pack_buff_size_test(&pcap, 64) == -1); + TESTASSERT(rrc_ue_cap_info_pack_buff_size_test(&pcap, 128) == 0); #else // TESTASSERT(rrc_ue_cap_info_test(NULL) == 0); + TESTASSERT(rrc_ue_cap_info_pack_buff_size_test(NULL, 64) == -1); + TESTASSERT(rrc_ue_cap_info_pack_buff_size_test(NULL, 128) == 0); #endif TESTASSERT(pack_fail_test() == -1); TESTASSERT(rrc_nr_test_scg_fail_packing() == SRSRAN_SUCCESS) diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index ca652aec3..6acc06af3 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -2215,7 +2215,7 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) } // Pack caps and copy to cap info - uint8_t buf[64] = {}; + uint8_t buf[128] = {}; asn1::bit_ref bref(buf, sizeof(buf)); if (cap.pack(bref) != asn1::SRSASN_SUCCESS) { logger.error("Error packing EUTRA capabilities");