Commit d0a582e7 authored by Teodora's avatar Teodora

Implement E2 node level stats

For now, only DL/UL MAC stats.

This commit fixes the "RRU.PrbTotDl" and "RRU.PrbTotUl" measurement calculation
to align with the TS 28.552 specifications.
parent 021b546c
...@@ -54,10 +54,12 @@ typedef struct { ...@@ -54,10 +54,12 @@ typedef struct {
ue_id_e2sm_t* ue_id; ue_id_e2sm_t* ue_id;
// Optional // Optional
// only used to retreive MAC/RLC stats // only used to retrieve MAC/RLC stats
NR_UE_info_t** ue_info_list; NR_UE_info_t** ue_info_list;
}arr_ue_id_t; }arr_ue_id_t;
static e2_node_level_stats_t node_stats[2] = {0}; // [0] node stats collected in previous reporting period; [1] current node stats
static meas_data_lst_t fill_kpm_meas_data_item(const meas_info_format_1_lst_t* meas_info_lst, const size_t len, const uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx) static meas_data_lst_t fill_kpm_meas_data_item(const meas_info_format_1_lst_t* meas_info_lst, const size_t len, const uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx)
{ {
meas_data_lst_t data_item = {0}; meas_data_lst_t data_item = {0};
...@@ -74,7 +76,7 @@ static meas_data_lst_t fill_kpm_meas_data_item(const meas_info_format_1_lst_t* m ...@@ -74,7 +76,7 @@ static meas_data_lst_t fill_kpm_meas_data_item(const meas_info_format_1_lst_t* m
char* meas_info_name_str = cp_ba_to_str(meas_info_lst[i].meas_type.name); char* meas_info_name_str = cp_ba_to_str(meas_info_lst[i].meas_type.name);
data_item.meas_record_lst[i] = get_kpm_meas_value(meas_info_name_str, gran_period_ms, ue_info, ue_idx); data_item.meas_record_lst[i] = get_kpm_meas_value(meas_info_name_str, gran_period_ms, ue_info, ue_idx, node_stats);
free(meas_info_name_str); free(meas_info_name_str);
} }
...@@ -153,6 +155,8 @@ static kpm_ind_msg_format_3_t fill_kpm_ind_msg_frm_3(arr_ue_id_t* arr_ue_id, con ...@@ -153,6 +155,8 @@ static kpm_ind_msg_format_3_t fill_kpm_ind_msg_frm_3(arr_ue_id_t* arr_ue_id, con
msg_frm_3.meas_report_per_ue[i].ind_msg_format_1 = fill_kpm_ind_msg_frm_1(ue_info, i, act_def_fr_1); msg_frm_3.meas_report_per_ue[i].ind_msg_format_1 = fill_kpm_ind_msg_frm_1(ue_info, i, act_def_fr_1);
} }
node_stats[0] = cp_node_level_stats(&node_stats[1]);
return msg_frm_3; return msg_frm_3;
} }
...@@ -288,8 +292,10 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst ...@@ -288,8 +292,10 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst
const ngran_node_t node_type = get_e2_node_type(); const ngran_node_t node_type = get_e2_node_type();
gNB_MAC_INST *mac = RC.nrmac[0];
NR_SCHED_LOCK(&mac->sched_lock);
// Take MAC info // Take MAC info
UE_iterator(RC.nrmac[0]->UE_info.connected_ue_list, ue) { UE_iterator(mac->UE_info.connected_ue_list, ue) {
NR_UE_sched_ctrl_t *sched_ctrl = &ue->UE_sched_ctrl; NR_UE_sched_ctrl_t *sched_ctrl = &ue->UE_sched_ctrl;
// UE matches if any of its DRBs matches // UE matches if any of its DRBs matches
for (size_t l = 0; l < seq_arr_size(&sched_ctrl->lc_config); ++l) { for (size_t l = 0; l < seq_arr_size(&sched_ctrl->lc_config); ++l) {
...@@ -316,6 +322,10 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst ...@@ -316,6 +322,10 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst
AssertFatal(arr_ue_id.sz < MAX_MOBILES_PER_GNB, "cannot have more UEs than global UE number maximum\n"); AssertFatal(arr_ue_id.sz < MAX_MOBILES_PER_GNB, "cannot have more UEs than global UE number maximum\n");
} }
node_stats[1].mac_stats.dl.total_prb_aggregate = mac->mac_stats.dl.total_prb_aggregate;
node_stats[1].mac_stats.ul.total_prb_aggregate = mac->mac_stats.ul.total_prb_aggregate;
NR_SCHED_UNLOCK(&mac->sched_lock);
free(sd); // if NULL, nothing happens free(sd); // if NULL, nothing happens
return arr_ue_id; return arr_ue_id;
......
...@@ -23,6 +23,18 @@ ...@@ -23,6 +23,18 @@
#include <search.h> #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 /* 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 */ when it comes to multiple subscriptions to the same UEs; ric_req_id is unique per subscription */
typedef struct uldlcounter { typedef struct uldlcounter {
...@@ -46,7 +58,7 @@ static nr_pdcp_statistics_t get_pdcp_stats_per_drb(const uint32_t rrc_ue_id, con ...@@ -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 /* 3GPP TS 28.522 - section 5.1.2.1.1.1
note: this measurement is calculated as per spec */ 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}; meas_record_lst_t meas_record = {0};
...@@ -65,7 +77,7 @@ static meas_record_lst_t fill_DRB_PdcpSduVolumeDL(__attribute__((unused))uint32_ ...@@ -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 /* 3GPP TS 28.522 - section 5.1.2.1.2.1
note: this measurement is calculated as per spec */ 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}; meas_record_lst_t meas_record = {0};
...@@ -103,7 +115,7 @@ static nr_rlc_statistics_t get_rlc_stats_per_drb(const rnti_t rnti, const int rb ...@@ -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 /* 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 */ 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}; meas_record_lst_t meas_record = {0};
...@@ -122,7 +134,7 @@ static meas_record_lst_t fill_DRB_RlcSduDelayDl(__attribute__((unused))uint32_t ...@@ -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 /* 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) 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 */ 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}; 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_ ...@@ -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 /* 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) 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 */ 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}; 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_ ...@@ -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 /* 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 note: this measurement is calculated as per spec */
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, e2_node_level_stats_t* node_stats)
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)
{ {
meas_record_lst_t meas_record = {0}; meas_record_lst_t meas_record = {0};
meas_record.value = INTEGER_MEAS_VALUE; meas_record.value = INTEGER_MEAS_VALUE;
// Get the number of DL PRBs // 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; last_total_prbs[ue_idx].dl = ue_info.ue->mac_stats.dl.total_rbs;
return meas_record; return meas_record;
} }
/* 3GPP TS 28.522 - section 5.1.1.2.2 /* 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 note: this measurement is calculated as per spec */
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, e2_node_level_stats_t* node_stats)
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)
{ {
meas_record_lst_t meas_record = {0}; meas_record_lst_t meas_record = {0};
meas_record.value = INTEGER_MEAS_VALUE; meas_record.value = INTEGER_MEAS_VALUE;
// Get the number of UL PRBs // 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; last_total_prbs[ue_idx].ul = ue_info.ue->mac_stats.ul.total_rbs;
return meas_record; return meas_record;
...@@ -217,7 +227,7 @@ void init_kpm_subs_data(void) ...@@ -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); 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 ...@@ -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"); assert(found_entry != NULL && "Unsupported KPM measurement name");
kv_measure_t *kv_found = (kv_measure_t *)found_entry->data; 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; return meas_record;
} }
...@@ -34,7 +34,13 @@ typedef struct { ...@@ -34,7 +34,13 @@ typedef struct {
} cudu_ue_info_pair_t; } cudu_ue_info_pair_t;
typedef meas_record_lst_t (*kpm_meas_fp)(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx); typedef struct {
dlul_mac_stats_t mac_stats;
} e2_node_level_stats_t;
e2_node_level_stats_t cp_node_level_stats(const e2_node_level_stats_t *src);
typedef meas_record_lst_t (*kpm_meas_fp)(uint32_t gran_period_ms, cudu_ue_info_pair_t ue_info, const size_t ue_idx, e2_node_level_stats_t* node_stats);
typedef struct{ typedef struct{
char* key; char* key;
...@@ -44,6 +50,6 @@ typedef struct{ ...@@ -44,6 +50,6 @@ typedef struct{
void init_kpm_subs_data(void); 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);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment