|
|
|
@@ -23,6 +23,18 @@
|
|
|
|
|
|
|
|
|
|
#include <search.h>
|
|
|
|
|
|
|
|
|
|
e2_node_level_stats_t cp_node_level_stats(const e2_node_level_stats_t *src)
|
|
|
|
|
{
|
|
|
|
|
e2_node_level_stats_t dst = {
|
|
|
|
|
.mac_stats.dl.total_prb_aggregate = src->mac_stats.dl.total_prb_aggregate,
|
|
|
|
|
.mac_stats.dl.used_prb_aggregate = src->mac_stats.dl.used_prb_aggregate,
|
|
|
|
|
.mac_stats.ul.total_prb_aggregate = src->mac_stats.ul.total_prb_aggregate,
|
|
|
|
|
.mac_stats.ul.used_prb_aggregate = src->mac_stats.ul.used_prb_aggregate,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* measurements that need to store values from previous reporting period have a limitation
|
|
|
|
|
when it comes to multiple subscriptions to the same UEs; ric_req_id is unique per subscription */
|
|
|
|
|
typedef struct uldlcounter {
|
|
|
|
@@ -46,7 +58,7 @@ static nr_pdcp_statistics_t get_pdcp_stats_per_drb(const uint32_t rrc_ue_id, con
|
|
|
|
|
|
|
|
|
|
/* 3GPP TS 28.522 - section 5.1.2.1.1.1
|
|
|
|
|
note: this measurement is calculated as per spec */
|
|
|
|
|
static meas_record_lst_t fill_DRB_PdcpSduVolumeDL(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
|
|
|
|
|
static meas_record_lst_t fill_DRB_PdcpSduVolumeDL(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, __attribute__((unused))e2_node_level_stats_t* node_stats)
|
|
|
|
|
{
|
|
|
|
|
meas_record_lst_t meas_record = {0};
|
|
|
|
|
|
|
|
|
@@ -57,7 +69,7 @@ static meas_record_lst_t fill_DRB_PdcpSduVolumeDL(__attribute__((unused))uint32_
|
|
|
|
|
meas_record.value = INTEGER_MEAS_VALUE;
|
|
|
|
|
|
|
|
|
|
// Get DL data volume delivered to PDCP layer
|
|
|
|
|
meas_record.int_val = (pdcp.rxsdu_bytes - last_pdcp_sdu_total_bytes[ue_idx].dl)*8/1000; // [kb]
|
|
|
|
|
meas_record.int_val = (pdcp.rxsdu_bytes - last_pdcp_sdu_total_bytes[ue_idx].dl)*8/1000000; // [Mb]
|
|
|
|
|
last_pdcp_sdu_total_bytes[ue_idx].dl = pdcp.rxsdu_bytes;
|
|
|
|
|
|
|
|
|
|
return meas_record;
|
|
|
|
@@ -65,7 +77,7 @@ static meas_record_lst_t fill_DRB_PdcpSduVolumeDL(__attribute__((unused))uint32_
|
|
|
|
|
|
|
|
|
|
/* 3GPP TS 28.522 - section 5.1.2.1.2.1
|
|
|
|
|
note: this measurement is calculated as per spec */
|
|
|
|
|
static meas_record_lst_t fill_DRB_PdcpSduVolumeUL(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
|
|
|
|
|
static meas_record_lst_t fill_DRB_PdcpSduVolumeUL(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, __attribute__((unused))e2_node_level_stats_t* node_stats)
|
|
|
|
|
{
|
|
|
|
|
meas_record_lst_t meas_record = {0};
|
|
|
|
|
|
|
|
|
@@ -76,7 +88,7 @@ static meas_record_lst_t fill_DRB_PdcpSduVolumeUL(__attribute__((unused))uint32_
|
|
|
|
|
meas_record.value = INTEGER_MEAS_VALUE;
|
|
|
|
|
|
|
|
|
|
// Get UL data volume delivered from PDCP layer
|
|
|
|
|
meas_record.int_val = (pdcp.txsdu_bytes - last_pdcp_sdu_total_bytes[ue_idx].ul)*8/1000; // [kb]
|
|
|
|
|
meas_record.int_val = (pdcp.txsdu_bytes - last_pdcp_sdu_total_bytes[ue_idx].ul)*8/1000000; // [Mb]
|
|
|
|
|
last_pdcp_sdu_total_bytes[ue_idx].ul = pdcp.txsdu_bytes;
|
|
|
|
|
|
|
|
|
|
return meas_record;
|
|
|
|
@@ -103,7 +115,7 @@ static nr_rlc_statistics_t get_rlc_stats_per_drb(const rnti_t rnti, const int rb
|
|
|
|
|
|
|
|
|
|
/* 3GPP TS 28.522 - section 5.1.3.3.3
|
|
|
|
|
note: by default this measurement is calculated for previous 100ms (openair2/LAYER2/nr_rlc/nr_rlc_entity.c:118, 173, 213); please, update according to your needs */
|
|
|
|
|
static meas_record_lst_t fill_DRB_RlcSduDelayDl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, __attribute__((unused))const size_t ue_idx)
|
|
|
|
|
static meas_record_lst_t fill_DRB_RlcSduDelayDl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, __attribute__((unused))const size_t ue_idx, __attribute__((unused))e2_node_level_stats_t* node_stats)
|
|
|
|
|
{
|
|
|
|
|
meas_record_lst_t meas_record = {0};
|
|
|
|
|
|
|
|
|
@@ -122,7 +134,7 @@ static meas_record_lst_t fill_DRB_RlcSduDelayDl(__attribute__((unused))uint32_t
|
|
|
|
|
/* 3GPP TS 28.522 - section 5.1.1.3.1
|
|
|
|
|
note: per spec, average UE throughput in DL (taken into consideration values from all UEs, and averaged)
|
|
|
|
|
here calculated as: UE specific throughput in DL */
|
|
|
|
|
static meas_record_lst_t fill_DRB_UEThpDl(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
|
|
|
|
|
static meas_record_lst_t fill_DRB_UEThpDl(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, __attribute__((unused))e2_node_level_stats_t* node_stats)
|
|
|
|
|
{
|
|
|
|
|
meas_record_lst_t meas_record = {0};
|
|
|
|
|
|
|
|
|
@@ -141,7 +153,7 @@ static meas_record_lst_t fill_DRB_UEThpDl(uint32_t gran_period_ms, cudu_ue_info_
|
|
|
|
|
/* 3GPP TS 28.522 - section 5.1.1.3.3
|
|
|
|
|
note: per spec, average UE throughput in UL (taken into consideration values from all UEs, and averaged)
|
|
|
|
|
here calculated as: UE specific throughput in UL */
|
|
|
|
|
static meas_record_lst_t fill_DRB_UEThpUl(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
|
|
|
|
|
static meas_record_lst_t fill_DRB_UEThpUl(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, __attribute__((unused))e2_node_level_stats_t* node_stats)
|
|
|
|
|
{
|
|
|
|
|
meas_record_lst_t meas_record = {0};
|
|
|
|
|
|
|
|
|
@@ -159,32 +171,30 @@ static meas_record_lst_t fill_DRB_UEThpUl(uint32_t gran_period_ms, cudu_ue_info_
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 3GPP TS 28.522 - section 5.1.1.2.1
|
|
|
|
|
note: per spec, DL PRB usage [%] = (total used PRBs for DL traffic / total available PRBs for DL traffic) * 100
|
|
|
|
|
here calculated as: aggregated DL PRBs (t) - aggregated DL PRBs (t-gran_period) */
|
|
|
|
|
static meas_record_lst_t fill_RRU_PrbTotDl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
|
|
|
|
|
note: this measurement is calculated as per spec */
|
|
|
|
|
static meas_record_lst_t fill_RRU_PrbTotDl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, e2_node_level_stats_t* node_stats)
|
|
|
|
|
{
|
|
|
|
|
meas_record_lst_t meas_record = {0};
|
|
|
|
|
|
|
|
|
|
meas_record.value = INTEGER_MEAS_VALUE;
|
|
|
|
|
|
|
|
|
|
// Get the number of DL PRBs
|
|
|
|
|
meas_record.int_val = ue_info.ue->mac_stats.dl.total_rbs - last_total_prbs[ue_idx].dl; // [PRBs]
|
|
|
|
|
meas_record.int_val = (ue_info.ue->mac_stats.dl.total_rbs - last_total_prbs[ue_idx].dl) * 100 / (node_stats[1].mac_stats.dl.total_prb_aggregate - node_stats[0].mac_stats.dl.total_prb_aggregate); // [%]
|
|
|
|
|
last_total_prbs[ue_idx].dl = ue_info.ue->mac_stats.dl.total_rbs;
|
|
|
|
|
|
|
|
|
|
return meas_record;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 3GPP TS 28.522 - section 5.1.1.2.2
|
|
|
|
|
note: per spec, UL PRB usage [%] = (total used PRBs for UL traffic / total available PRBs for UL traffic) * 100
|
|
|
|
|
here calculated as: aggregated UL PRBs (t) - aggregated UL PRBs (t-gran_period) */
|
|
|
|
|
static meas_record_lst_t fill_RRU_PrbTotUl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
|
|
|
|
|
note: this measurement is calculated as per spec */
|
|
|
|
|
static meas_record_lst_t fill_RRU_PrbTotUl(__attribute__((unused))uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, e2_node_level_stats_t* node_stats)
|
|
|
|
|
{
|
|
|
|
|
meas_record_lst_t meas_record = {0};
|
|
|
|
|
|
|
|
|
|
meas_record.value = INTEGER_MEAS_VALUE;
|
|
|
|
|
|
|
|
|
|
// Get the number of UL PRBs
|
|
|
|
|
meas_record.int_val = ue_info.ue->mac_stats.ul.total_rbs - last_total_prbs[ue_idx].ul; // [PRBs]
|
|
|
|
|
meas_record.int_val = (ue_info.ue->mac_stats.ul.total_rbs - last_total_prbs[ue_idx].ul) * 100 / (node_stats[1].mac_stats.ul.total_prb_aggregate - node_stats[0].mac_stats.ul.total_prb_aggregate); // [%]
|
|
|
|
|
last_total_prbs[ue_idx].ul = ue_info.ue->mac_stats.ul.total_rbs;
|
|
|
|
|
|
|
|
|
|
return meas_record;
|
|
|
|
@@ -217,7 +227,7 @@ void init_kpm_subs_data(void)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
meas_record_lst_t get_kpm_meas_value(char* kpm_meas_name, uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
|
|
|
|
|
meas_record_lst_t get_kpm_meas_value(char* kpm_meas_name, uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, e2_node_level_stats_t* node_stats)
|
|
|
|
|
{
|
|
|
|
|
assert(kpm_meas_name != NULL);
|
|
|
|
|
|
|
|
|
@@ -226,7 +236,7 @@ meas_record_lst_t get_kpm_meas_value(char* kpm_meas_name, uint32_t gran_period_m
|
|
|
|
|
assert(found_entry != NULL && "Unsupported KPM measurement name");
|
|
|
|
|
|
|
|
|
|
kv_measure_t *kv_found = (kv_measure_t *)found_entry->data;
|
|
|
|
|
meas_record_lst_t meas_record = kv_found->value(gran_period_ms, ue_info, ue_idx);
|
|
|
|
|
meas_record_lst_t meas_record = kv_found->value(gran_period_ms, ue_info, ue_idx, node_stats);
|
|
|
|
|
|
|
|
|
|
return meas_record;
|
|
|
|
|
}
|
|
|
|
|