e2sm_kpm: move ind msg processing logic to separate class and use virtual funcs

master
Piotr Gawlowicz 2 years ago committed by Justin Tallon
parent 6c8458bfb2
commit e70a2eb4e8

@ -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);
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<e2sm_kpm_label_enum> _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;
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);
std::vector<E2SM_KPM_metric_t> supported_meas_types;
std::map<uint32_t, E2SM_KPM_action_data_t> registered_actions_data;
std::map<uint32_t, e2sm_kpm_report_service*> registered_actions_data;
srsran_random_t random_gen;

@ -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 {

@ -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<e2sm_kpm_label_enum> _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

@ -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)

@ -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 <numeric>
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_label_enum> e2sm_kpm::_get_present_labels(const meas_info_item_s& action_meas_info_item)
{
std::vector<e2sm_kpm_label_enum> 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<e2sm_kpm_label_enum> 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);
@ -247,8 +157,6 @@ 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;
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<uint32_t, E2SM_KPM_action_data_t>(action_entry.sm_local_ric_action_id, action_data));
std::pair<uint32_t, e2sm_kpm_report_service*>(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);
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());

@ -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_label_enum>
e2sm_kpm_report_service::_get_present_labels(const meas_info_item_s& action_meas_info_item)
{
std::vector<e2sm_kpm_label_enum> 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<e2sm_kpm_label_enum> 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;
}
Loading…
Cancel
Save