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());