Service Models support in CU-UP
- e2_ran_func library divided into e2_ran_func_cuup (CU-UP only) and e2_ran_func_du_cucp_cuup (DU, CU, CU-CP and gNB-mono) - GTP SM is not yet implemented in CU-UP -> CU-UP doesn't store PDU session information - PDCP SM support for gNB-mono, CU and CU-UP - KPM SM support for all node types (DU, CU, CU-UP, CU-CP and gNB-mono)
This commit is contained in:
+3
-3
@@ -1433,7 +1433,7 @@ target_link_libraries(L2 PRIVATE x2ap s1ap lte_rrc m2ap)
|
||||
target_link_libraries(L2 PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
|
||||
if(E2_AGENT)
|
||||
target_link_libraries(L2 PUBLIC e2_agent e2_agent_arg e2_ran_func)
|
||||
target_link_libraries(L2 PUBLIC e2_agent e2_agent_arg e2_ran_func_du_cucp_cuup)
|
||||
target_compile_definitions(L2 PRIVATE E2_AGENT)
|
||||
target_compile_definitions(L2 PRIVATE ${E2AP_VERSION} ${KPM_VERSION})
|
||||
endif()
|
||||
@@ -1460,7 +1460,7 @@ target_link_libraries(e1_if PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap
|
||||
|
||||
target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap nr_rlc)
|
||||
if(E2_AGENT)
|
||||
target_link_libraries(L2_NR PUBLIC e2_agent e2_agent_arg e2_ran_func)
|
||||
target_link_libraries(L2_NR PUBLIC e2_agent e2_agent_arg e2_ran_func_du_cucp_cuup)
|
||||
target_compile_definitions(L2_NR PRIVATE ${E2AP_VERSION} ${KPM_VERSION})
|
||||
target_compile_definitions(L2_NR PRIVATE E2_AGENT)
|
||||
endif()
|
||||
@@ -2115,7 +2115,7 @@ target_link_libraries(nr-cuup PRIVATE
|
||||
z sctp dl pthread shlib_loader ${T_LIB})
|
||||
target_link_libraries(nr-cuup PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
if(E2_AGENT)
|
||||
target_link_libraries(nr-cuup PRIVATE e2_agent e2_agent_arg) # RAN functions to be added
|
||||
target_link_libraries(nr-cuup PRIVATE e2_agent e2_agent_arg e2_ran_func_cuup)
|
||||
target_compile_definitions(nr-cuup PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -64,14 +64,13 @@ static void initialize_agent(ngran_node_t node_type, e2_agent_args_t oai_args)
|
||||
const int mcc = e1inst->cuup.setupReq.plmn[0].id.mcc;
|
||||
const int mnc = e1inst->cuup.setupReq.plmn[0].id.mnc;
|
||||
const int mnc_digit_len = e1inst->cuup.setupReq.plmn[0].id.mnc_digit_length;
|
||||
// const ngran_node_t node_type = ngran_gNB_CUUP;
|
||||
|
||||
printf("[E2 NODE]: mcc = %d mnc = %d mnc_digit = %d nb_id = %d \n", mcc, mnc, mnc_digit_len, nb_id);
|
||||
|
||||
printf("[E2 NODE]: Args %s %s \n", args.ip, args.libs_dir);
|
||||
|
||||
// sm_io_ag_ran_t io = init_ran_func_ag();
|
||||
// init_agent_api(mcc, mnc, mnc_digit_len, nb_id, cu_up_id, node_type, io, &args);
|
||||
sm_io_ag_ran_t io = init_ran_func_ag();
|
||||
init_agent_api(mcc, mnc, mnc_digit_len, nb_id, cu_up_id, node_type, io, &args);
|
||||
}
|
||||
#endif // E2_AGENT
|
||||
|
||||
|
||||
@@ -1,17 +1,40 @@
|
||||
add_subdirectory(CUSTOMIZED)
|
||||
add_subdirectory(O-RAN)
|
||||
add_library(e2_ran_func_cuup STATIC
|
||||
init_ran_func.c
|
||||
read_setup_ran.c
|
||||
../flexric/test/rnd/fill_rnd_data_e2_setup_req.c # this is not rnd data; it is used to fill E2 Node Component Configuration Addition List in E2 Setup Request message
|
||||
CUSTOMIZED/ran_func_gtp.c # current implementation doesn't take split architecture into account, neither CU/DU nor CU-UP/CU-CP
|
||||
CUSTOMIZED/ran_func_pdcp.c # current implementation doesn't take split architecture into account, neither CU/DU nor CU-UP/CU-CP
|
||||
CUSTOMIZED/ran_func_tc.c # currently, not implemented; therefore, filling rnd data
|
||||
../flexric/test/rnd/fill_rnd_data_tc.c
|
||||
O-RAN/ran_func_kpm.c # this file should only contain PDCP-U/GTP; to be done in the future
|
||||
../flexric/test/rnd/fill_rnd_data_kpm.c # this dependancy will be taken out once RAN Function Definition is implemented
|
||||
O-RAN/ran_func_rc.c # this file should only contain PDCP-U/GTP; to be done in the future
|
||||
../flexric/test/rnd/fill_rnd_data_rc.c # this dependancy will be taken out once RAN Function Definition is implemented
|
||||
)
|
||||
|
||||
add_library(e2_ran_func STATIC
|
||||
init_ran_func.c
|
||||
read_setup_ran.c
|
||||
../flexric/test/rnd/fill_rnd_data_e2_setup_req.c
|
||||
)
|
||||
target_link_libraries(e2_ran_func_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj)
|
||||
target_compile_definitions(e2_ran_func_cuup PUBLIC ${E2AP_VERSION} ${KPM_VERSION} NGRAN_GNB_CUUP)
|
||||
|
||||
target_link_libraries(e2_ran_func
|
||||
PUBLIC
|
||||
e2_ran_func_cust
|
||||
e2_ran_func_oran
|
||||
)
|
||||
|
||||
# This dependency sucks! Create pointers and forward declarations!
|
||||
target_compile_definitions(e2_ran_func PRIVATE ${E2AP_VERSION} ${KPM_VERSION})
|
||||
add_library(e2_ran_func_du_cucp_cuup STATIC
|
||||
init_ran_func.c
|
||||
read_setup_ran.c
|
||||
../flexric/test/rnd/fill_rnd_data_e2_setup_req.c # this is not rnd data; it is used to fill E2 Node Component Configuration Addition List in E2 Setup Request message
|
||||
CUSTOMIZED/ran_func_gtp.c # current implementation doesn't take split architecture into account, neither CU/DU nor CU-UP/CU-CP
|
||||
CUSTOMIZED/ran_func_pdcp.c # current implementation doesn't take split architecture into account, neither CU/DU nor CU-UP/CU-CP
|
||||
O-RAN/ran_func_kpm.c # this file should only contain RRC/PDCP-C; to be done in the future
|
||||
# when nr-softmodem is divided in separate executables
|
||||
../flexric/test/rnd/fill_rnd_data_kpm.c # this dependancy will be taken out once RAN Function Definition is implemented
|
||||
O-RAN/ran_func_rc.c # this file should only contain RRC/PDCP-C; to be done in the future
|
||||
# when nr-softmodem is divided in separate executables
|
||||
../flexric/test/rnd/fill_rnd_data_rc.c # this dependancy will be taken out once RAN Function Definition is implemented
|
||||
CUSTOMIZED/ran_func_mac.c
|
||||
CUSTOMIZED/ran_func_rlc.c
|
||||
CUSTOMIZED/ran_func_slice.c
|
||||
CUSTOMIZED/ran_func_tc.c
|
||||
../flexric/test/rnd/fill_rnd_data_tc.c
|
||||
../flexric/test/rnd/fill_rnd_data_slice.c
|
||||
)
|
||||
|
||||
target_link_libraries(e2_ran_func_du_cucp_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj)
|
||||
target_compile_definitions(e2_ran_func_du_cucp_cuup PUBLIC ${E2AP_VERSION} ${KPM_VERSION} NGRAN_GNB_DU NGRAN_GNB_CUCP NGRAN_GNB_CUUP)
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
add_library(e2_ran_func_cust STATIC
|
||||
ran_func_gtp.c
|
||||
ran_func_mac.c
|
||||
ran_func_pdcp.c
|
||||
ran_func_rlc.c
|
||||
ran_func_slice.c
|
||||
ran_func_tc.c
|
||||
# For testing purposes
|
||||
../../flexric/test/rnd/fill_rnd_data_gtp.c
|
||||
../../flexric/test/rnd/fill_rnd_data_tc.c
|
||||
../../flexric/test/rnd/fill_rnd_data_mac.c
|
||||
../../flexric/test/rnd/fill_rnd_data_rlc.c
|
||||
../../flexric/test/rnd/fill_rnd_data_pdcp.c
|
||||
../../flexric/test/rnd/fill_rnd_data_slice.c
|
||||
../../flexric/src/util/time_now_us.c
|
||||
)
|
||||
|
||||
target_link_libraries(e2_ran_func_cust PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs)
|
||||
# This dependency sucks! Create pointers and forward declarations!
|
||||
target_compile_definitions(e2_ran_func_cust PRIVATE ${E2AP_VERSION} ${KPM_VERSION} )
|
||||
@@ -23,15 +23,15 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_gtp.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "openair2/E2AP/flexric/src/util/time_now_us.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
|
||||
#if defined (NGRAN_GNB_CUCP)
|
||||
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
|
||||
|
||||
|
||||
static
|
||||
const int mod_id = 0;
|
||||
#endif
|
||||
|
||||
bool read_gtp_sm(void * data)
|
||||
{
|
||||
@@ -42,45 +42,46 @@ bool read_gtp_sm(void * data)
|
||||
|
||||
gtp->msg.tstamp = time_now_us();
|
||||
|
||||
NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
size_t num_ues = 0;
|
||||
UE_iterator(UE_info->list, ue) {
|
||||
if (ue)
|
||||
num_ues += 1;
|
||||
}
|
||||
|
||||
uint64_t ue_id_list[MAX_MOBILES_PER_GNB];
|
||||
size_t num_ues = nr_pdcp_get_num_ues(ue_id_list, MAX_MOBILES_PER_GNB);
|
||||
|
||||
gtp->msg.len = num_ues;
|
||||
if(gtp->msg.len > 0){
|
||||
gtp->msg.ngut = calloc(gtp->msg.len, sizeof(gtp_ngu_t_stats_t) );
|
||||
assert(gtp->msg.ngut != NULL);
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
UE_iterator(UE_info->list, UE)
|
||||
{
|
||||
uint16_t const rnti = UE->rnti;
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context_by_rnti_any_du(RC.nrrrc[mod_id], rnti);
|
||||
if (ue_context_p != NULL) {
|
||||
gtp->msg.ngut[i].rnti = ue_context_p->ue_context.rnti;
|
||||
int nb_pdu_session = ue_context_p->ue_context.nb_of_pdusessions;
|
||||
if (nb_pdu_session > 0) {
|
||||
int nb_pdu_idx = nb_pdu_session - 1;
|
||||
gtp->msg.ngut[i].teidgnb = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.gNB_teid_N3;
|
||||
gtp->msg.ngut[i].teidupf = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.UPF_teid_N3;
|
||||
// TODO: one PDU session has multiple QoS Flow
|
||||
int nb_qos_flow = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.nb_qos;
|
||||
if (nb_qos_flow > 0) {
|
||||
gtp->msg.ngut[i].qfi = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.qos[nb_qos_flow - 1].qfi;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_W(NR_RRC,"rrc_gNB_get_ue_context return NULL\n");
|
||||
// if (gtp->msg.ngut != NULL) free(gtp->msg.ngut);
|
||||
}
|
||||
i++;
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return num_ues > 0;
|
||||
#if defined (NGRAN_GNB_CUCP) && defined (NGRAN_GNB_CUUP)
|
||||
if (RC.nrrrc[0]->node_type == ngran_gNB_DU || RC.nrrrc[0]->node_type == ngran_gNB_CUCP) return false;
|
||||
assert((RC.nrrrc[0]->node_type == ngran_gNB_CU || RC.nrrrc[0]->node_type == ngran_gNB) && "Expected node types: CU or gNB-mono");
|
||||
|
||||
for (size_t i = 0; i < num_ues; i++) {
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[0], ue_id_list[i]);
|
||||
|
||||
gtp->msg.ngut[i].rnti = ue_id_list[i];
|
||||
int nb_pdu_session = ue_context_p->ue_context.nb_of_pdusessions;
|
||||
if (nb_pdu_session > 0) {
|
||||
int nb_pdu_idx = nb_pdu_session - 1;
|
||||
gtp->msg.ngut[i].teidgnb = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.gNB_teid_N3;
|
||||
gtp->msg.ngut[i].teidupf = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.UPF_teid_N3;
|
||||
// TODO: one PDU session has multiple QoS Flow
|
||||
int nb_qos_flow = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.nb_qos;
|
||||
if (nb_qos_flow > 0) {
|
||||
gtp->msg.ngut[i].qfi = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.qos[nb_qos_flow - 1].qfi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
#elif defined (NGRAN_GNB_CUUP)
|
||||
// For the moment, CU-UP doesn't store PDU session information
|
||||
printf("GTP SM not yet implemented in CU-UP\n");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void read_gtp_setup_sm(void* data)
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "ran_func_mac.h"
|
||||
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_mac.h"
|
||||
#include <assert.h>
|
||||
|
||||
static
|
||||
|
||||
@@ -19,41 +19,64 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "ran_func_pdcp.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_pdcp.h"
|
||||
#include "ran_func_pdcp.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "openair2/E2AP/flexric/src/util/time_now_us.h"
|
||||
|
||||
#if defined (NGRAN_GNB_DU)
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#endif
|
||||
|
||||
static
|
||||
const int mod_id = 0;
|
||||
#if defined (NGRAN_GNB_CUCP)
|
||||
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
|
||||
#endif
|
||||
|
||||
static
|
||||
uint32_t num_act_rb(NR_UEs_t* UE_info)
|
||||
#if defined (NGRAN_GNB_CUUP)
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
#endif
|
||||
|
||||
#if defined (NGRAN_GNB_CUUP)
|
||||
void fill_pdcp_stats_for_all_rbs(pdcp_radio_bearer_stats_t* rb, const size_t num_ues, const uint64_t* ue_id_list)
|
||||
{
|
||||
assert(UE_info!= NULL);
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < num_ues; i++) {
|
||||
for (int rb_id = 1; rb_id < 6; ++rb_id) {
|
||||
nr_pdcp_statistics_t rb_pdcp = {0};
|
||||
|
||||
uint32_t act_rb = 0;
|
||||
UE_iterator(UE_info->list, UE) {
|
||||
uint16_t const rnti = UE->rnti;
|
||||
for(int rb_id = 1; rb_id < 6; ++rb_id ){
|
||||
nr_rlc_statistics_t rlc = {0};
|
||||
const int srb_flag = 0;
|
||||
const bool rc = nr_rlc_get_statistics(rnti, srb_flag, rb_id, &rlc);
|
||||
if(rc) ++act_rb;
|
||||
const bool rc = nr_pdcp_get_statistics(ue_id_list[i], srb_flag, rb_id, &rb_pdcp);
|
||||
|
||||
if (!rc) continue;
|
||||
|
||||
pdcp_radio_bearer_stats_t *rd = &rb[j++];
|
||||
|
||||
rd->txpdu_pkts = rb_pdcp.txpdu_pkts; /* aggregated number of tx packets */
|
||||
rd->txpdu_bytes = rb_pdcp.txpdu_bytes; /* aggregated bytes of tx packets */
|
||||
rd->txpdu_sn = rb_pdcp.txpdu_sn; /* current sequence number of last tx packet (or TX_NEXT) */
|
||||
rd->rxpdu_pkts = rb_pdcp.rxpdu_pkts; /* aggregated number of rx packets */
|
||||
rd->rxpdu_bytes = rb_pdcp.rxpdu_bytes; /* aggregated bytes of rx packets */
|
||||
rd->rxpdu_sn = rb_pdcp.rxpdu_sn; /* current sequence number of last rx packet (or RX_NEXT) */
|
||||
rd->rxpdu_oo_pkts = rb_pdcp.rxpdu_oo_pkts; /* aggregated number of out-of-order rx pkts (or RX_REORD) */
|
||||
rd->rxpdu_oo_bytes = rb_pdcp.rxpdu_oo_bytes; /* aggregated amount of out-of-order rx bytes */
|
||||
rd->rxpdu_dd_pkts = rb_pdcp.rxpdu_dd_pkts; /* aggregated number of duplicated discarded packets (or dropped packets because of other reasons such as integrity failure) (or RX_DELIV) */
|
||||
rd->rxpdu_dd_bytes = rb_pdcp.rxpdu_dd_bytes; /* aggregated amount of discarded packets' bytes */
|
||||
rd->rxpdu_ro_count = rb_pdcp.rxpdu_ro_count; /* this state variable indicates the COUNT value following the COUNT value associated with the PDCP Data PDU which triggered t-Reordering. (RX_REORD) */
|
||||
rd->txsdu_pkts = rb_pdcp.txsdu_pkts; /* number of SDUs delivered */
|
||||
rd->txsdu_bytes = rb_pdcp.txsdu_bytes; /* number of bytes of SDUs delivered */
|
||||
rd->rxsdu_pkts = rb_pdcp.rxsdu_pkts; /* number of SDUs received */
|
||||
rd->rxsdu_bytes = rb_pdcp.rxsdu_bytes; /* number of bytes of SDUs received */
|
||||
rd->rnti = ue_id_list[i];
|
||||
rd->mode = rb_pdcp.mode; /* 0: PDCP AM, 1: PDCP UM, 2: PDCP TM */
|
||||
rd->rbid = rb_id;
|
||||
}
|
||||
}
|
||||
return act_rb;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool read_pdcp_sm(void* data)
|
||||
{
|
||||
@@ -61,127 +84,60 @@ bool read_pdcp_sm(void* data)
|
||||
//assert(data->type == PDCP_STATS_V0);
|
||||
|
||||
pdcp_ind_data_t* pdcp = (pdcp_ind_data_t*)data;
|
||||
//fill_pdcp_ind_data(pdcp);
|
||||
// TODO: Need to improve, not good
|
||||
if (NODE_IS_CU(RC.nrrrc[mod_id]->node_type)) {
|
||||
|
||||
uint32_t act_rb = 0;
|
||||
struct rrc_gNB_ue_context_s *ue_context_p1 = NULL;
|
||||
RB_FOREACH(ue_context_p1, rrc_nr_ue_tree_s, &RC.nrrrc[mod_id]->rrc_ue_head) {
|
||||
uint16_t const rnti = ue_context_p1->ue_context.rnti;
|
||||
for(int rb_id = 1; rb_id < 6; ++rb_id ){
|
||||
nr_pdcp_statistics_t rb_pdcp = {0};
|
||||
const int srb_flag = 0;
|
||||
const bool rc = nr_pdcp_get_statistics(rnti, srb_flag, rb_id, &rb_pdcp);
|
||||
if(rc) ++act_rb;
|
||||
}
|
||||
pdcp->msg.tstamp = time_now_us();
|
||||
|
||||
size_t num_ues = 0;
|
||||
uint64_t ue_id_list[MAX_MOBILES_PER_GNB];
|
||||
size_t total_num_rb = 0;
|
||||
|
||||
#if defined (NGRAN_GNB_CUCP) && defined (NGRAN_GNB_CUUP)
|
||||
if (RC.nrrrc[0]->node_type == ngran_gNB_DU || RC.nrrrc[0]->node_type == ngran_gNB_CUCP) return false;
|
||||
assert((RC.nrrrc[0]->node_type == ngran_gNB_CU || RC.nrrrc[0]->node_type == ngran_gNB) && "Expected node types: CU or gNB-mono");
|
||||
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &RC.nrrrc[0]->rrc_ue_head) {
|
||||
ue_id_list[num_ues] = ue_context_p->ue_context.rrc_ue_id;
|
||||
|
||||
for(int rb_id = 1; rb_id < 6; ++rb_id ){
|
||||
nr_pdcp_statistics_t rb_pdcp = {0};
|
||||
const int srb_flag = 0;
|
||||
const bool rc = nr_pdcp_get_statistics(ue_id_list[num_ues], srb_flag, rb_id, &rb_pdcp);
|
||||
if(rc) ++total_num_rb;
|
||||
}
|
||||
num_ues++;
|
||||
|
||||
pdcp->msg.tstamp = time_now_us();
|
||||
|
||||
pdcp->msg.len = act_rb;
|
||||
if (pdcp->msg.len > 0) {
|
||||
pdcp->msg.rb = calloc(pdcp->msg.len, sizeof(pdcp_radio_bearer_stats_t));
|
||||
assert(pdcp->msg.rb != NULL && "Memory exhausted!");
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
struct rrc_gNB_ue_context_s *ue_context_p2 = NULL;
|
||||
RB_FOREACH(ue_context_p2, rrc_nr_ue_tree_s, &RC.nrrrc[mod_id]->rrc_ue_head) {
|
||||
// TODO: Need to handel multiple UEs
|
||||
uint16_t const rnti = ue_context_p2->ue_context.rnti;
|
||||
|
||||
for (size_t rb_id = 1; rb_id < 6; ++rb_id) {
|
||||
nr_pdcp_statistics_t rb_pdcp = {0};
|
||||
|
||||
const int srb_flag = 0;
|
||||
const bool rc = nr_pdcp_get_statistics(rnti, srb_flag, rb_id, &rb_pdcp);
|
||||
|
||||
if (!rc) continue;
|
||||
|
||||
pdcp_radio_bearer_stats_t *rd = &pdcp->msg.rb[i];
|
||||
|
||||
rd->txpdu_pkts = rb_pdcp.txpdu_pkts; /* aggregated number of tx packets */
|
||||
rd->txpdu_bytes = rb_pdcp.txpdu_bytes; /* aggregated bytes of tx packets */
|
||||
rd->txpdu_sn = rb_pdcp.txpdu_sn; /* current sequence number of last tx packet (or TX_NEXT) */
|
||||
rd->rxpdu_pkts = rb_pdcp.rxpdu_pkts; /* aggregated number of rx packets */
|
||||
rd->rxpdu_bytes = rb_pdcp.rxpdu_bytes; /* aggregated bytes of rx packets */
|
||||
rd->rxpdu_sn = rb_pdcp.rxpdu_sn; /* current sequence number of last rx packet (or RX_NEXT) */
|
||||
rd->rxpdu_oo_pkts = rb_pdcp.rxpdu_oo_pkts; /* aggregated number of out-of-order rx pkts (or RX_REORD) */
|
||||
rd->rxpdu_oo_bytes = rb_pdcp.rxpdu_oo_bytes; /* aggregated amount of out-of-order rx bytes */
|
||||
rd->rxpdu_dd_pkts = rb_pdcp.rxpdu_dd_pkts; /* aggregated number of duplicated discarded packets (or dropped packets because of other reasons such as integrity failure) (or RX_DELIV) */
|
||||
rd->rxpdu_dd_bytes = rb_pdcp.rxpdu_dd_bytes; /* aggregated amount of discarded packets' bytes */
|
||||
rd->rxpdu_ro_count = rb_pdcp.rxpdu_ro_count; /* this state variable indicates the COUNT value following the COUNT value associated with the PDCP Data PDU which triggered t-Reordering. (RX_REORD) */
|
||||
rd->txsdu_pkts = rb_pdcp.txsdu_pkts; /* number of SDUs delivered */
|
||||
rd->txsdu_bytes = rb_pdcp.txsdu_bytes; /* number of bytes of SDUs delivered */
|
||||
rd->rxsdu_pkts = rb_pdcp.rxsdu_pkts; /* number of SDUs received */
|
||||
rd->rxsdu_bytes = rb_pdcp.rxsdu_bytes; /* number of bytes of SDUs received */
|
||||
rd->rnti = rnti;
|
||||
rd->mode = rb_pdcp.mode; /* 0: PDCP AM, 1: PDCP UM, 2: PDCP TM */
|
||||
rd->rbid = rb_id;
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return act_rb > 0;
|
||||
|
||||
} else {
|
||||
|
||||
//assert(0!=0 && "Calling PDCP");
|
||||
// for the moment and while we don't have a split base station, we use the
|
||||
// MAC structures to obtain the RNTIs which we use to query the PDCP
|
||||
NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
uint32_t const act_rb = num_act_rb(UE_info);
|
||||
|
||||
pdcp->msg.tstamp = time_now_us();
|
||||
|
||||
pdcp->msg.len = act_rb;
|
||||
if (pdcp->msg.len > 0) {
|
||||
pdcp->msg.rb = calloc(pdcp->msg.len, sizeof(pdcp_radio_bearer_stats_t));
|
||||
assert(pdcp->msg.rb != NULL && "Memory exhausted!");
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
UE_iterator(UE_info->list, UE)
|
||||
{
|
||||
|
||||
const int rnti = UE->rnti;
|
||||
for (size_t rb_id = 1; rb_id < 6; ++rb_id) {
|
||||
nr_pdcp_statistics_t rb_pdcp = {0};
|
||||
|
||||
const int srb_flag = 0;
|
||||
const bool rc = nr_pdcp_get_statistics(rnti, srb_flag, rb_id, &rb_pdcp);
|
||||
|
||||
if (!rc) continue;
|
||||
|
||||
pdcp_radio_bearer_stats_t *rd = &pdcp->msg.rb[i];
|
||||
|
||||
rd->txpdu_pkts = rb_pdcp.txpdu_pkts; /* aggregated number of tx packets */
|
||||
rd->txpdu_bytes = rb_pdcp.txpdu_bytes; /* aggregated bytes of tx packets */
|
||||
rd->txpdu_sn = rb_pdcp.txpdu_sn; /* current sequence number of last tx packet (or TX_NEXT) */
|
||||
rd->rxpdu_pkts = rb_pdcp.rxpdu_pkts; /* aggregated number of rx packets */
|
||||
rd->rxpdu_bytes = rb_pdcp.rxpdu_bytes; /* aggregated bytes of rx packets */
|
||||
rd->rxpdu_sn = rb_pdcp.rxpdu_sn; /* current sequence number of last rx packet (or RX_NEXT) */
|
||||
rd->rxpdu_oo_pkts = rb_pdcp.rxpdu_oo_pkts; /* aggregated number of out-of-order rx pkts (or RX_REORD) */
|
||||
rd->rxpdu_oo_bytes = rb_pdcp.rxpdu_oo_bytes; /* aggregated amount of out-of-order rx bytes */
|
||||
rd->rxpdu_dd_pkts = rb_pdcp.rxpdu_dd_pkts; /* aggregated number of duplicated discarded packets (or dropped packets because of other reasons such as integrity failure) (or RX_DELIV) */
|
||||
rd->rxpdu_dd_bytes = rb_pdcp.rxpdu_dd_bytes; /* aggregated amount of discarded packets' bytes */
|
||||
rd->rxpdu_ro_count = rb_pdcp.rxpdu_ro_count; /* this state variable indicates the COUNT value following the COUNT value associated with the PDCP Data PDU which triggered t-Reordering. (RX_REORD) */
|
||||
rd->txsdu_pkts = rb_pdcp.txsdu_pkts; /* number of SDUs delivered */
|
||||
rd->txsdu_bytes = rb_pdcp.txsdu_bytes; /* number of bytes of SDUs delivered */
|
||||
rd->rxsdu_pkts = rb_pdcp.rxsdu_pkts; /* number of SDUs received */
|
||||
rd->rxsdu_bytes = rb_pdcp.rxsdu_bytes; /* number of bytes of SDUs received */
|
||||
rd->rnti = rnti;
|
||||
rd->mode = rb_pdcp.mode; /* 0: PDCP AM, 1: PDCP UM, 2: PDCP TM */
|
||||
rd->rbid = rb_id;
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return act_rb > 0;
|
||||
AssertFatal(num_ues < MAX_MOBILES_PER_GNB, "cannot have more UEs than global UE number maximum\n");
|
||||
}
|
||||
|
||||
#elif defined (NGRAN_GNB_CUUP)
|
||||
num_ues = nr_pdcp_get_num_ues(ue_id_list, MAX_MOBILES_PER_GNB);
|
||||
for (size_t i = 0; i < num_ues; i++) {
|
||||
for(int rb_id = 1; rb_id < 6; ++rb_id ){
|
||||
nr_pdcp_statistics_t rb_pdcp = {0};
|
||||
const int srb_flag = 0;
|
||||
const bool rc = nr_pdcp_get_statistics(ue_id_list[i], srb_flag, rb_id, &rb_pdcp);
|
||||
if(rc) ++total_num_rb;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
pdcp->msg.len = total_num_rb;
|
||||
if (pdcp->msg.len > 0) {
|
||||
pdcp->msg.rb = calloc(pdcp->msg.len, sizeof(pdcp_radio_bearer_stats_t));
|
||||
assert(pdcp->msg.rb != NULL && "Memory exhausted!");
|
||||
|
||||
// Filling Radio Bearer Statistics
|
||||
#if defined (NGRAN_GNB_CUUP)
|
||||
fill_pdcp_stats_for_all_rbs(pdcp->msg.rb, num_ues, ue_id_list);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void read_pdcp_setup_sm(void* data)
|
||||
@@ -200,5 +156,3 @@ sm_ag_if_ans_t write_ctrl_pdcp_sm(void const* data)
|
||||
sm_ag_if_ans_t ans = {0};
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include "openair2/E2AP/flexric/src/util/time_now_us.h"
|
||||
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_rlc.h"
|
||||
|
||||
static
|
||||
const int mod_id = 0;
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
add_library(e2_ran_func_oran STATIC
|
||||
ran_func_kpm.c
|
||||
ran_func_rc.c
|
||||
# For testing purposes
|
||||
../../flexric/test/rnd/fill_rnd_data_kpm.c
|
||||
../../flexric/test/rnd/fill_rnd_data_rc.c
|
||||
)
|
||||
|
||||
target_link_libraries(e2_ran_func_oran PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs)
|
||||
target_compile_definitions(e2_ran_func_oran PRIVATE ${E2AP_VERSION} ${KPM_VERSION})
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "ran_func_rc.h"
|
||||
#include "../../flexric/test/rnd/fill_rnd_data_rc.h"
|
||||
#include "../../flexric/test/rnd/fill_rnd_data_rc.h" // this dependancy will be taken out once RAN Function Definition is implemented
|
||||
#include "../../flexric/src/sm/rc_sm/ie/ir/lst_ran_param.h"
|
||||
#include "../../flexric/src/sm/rc_sm/ie/ir/ran_param_list.h"
|
||||
#include "../../flexric/src/agent/e2_agent_api.h"
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Please note: current implementation doesn't take split architecture into account, neither CU/DU nor CU-UP/CU-CP
|
||||
|
||||
bool read_rc_sm(void* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
@@ -22,24 +22,35 @@
|
||||
#include "init_ran_func.h"
|
||||
#include "read_setup_ran.h"
|
||||
#include "../flexric/src/agent/e2_agent_api.h"
|
||||
|
||||
#if defined (NGRAN_GNB_DU)
|
||||
#include "CUSTOMIZED/ran_func_mac.h"
|
||||
#include "CUSTOMIZED/ran_func_rlc.h"
|
||||
#include "CUSTOMIZED/ran_func_pdcp.h"
|
||||
#include "CUSTOMIZED/ran_func_slice.h"
|
||||
#endif
|
||||
#if defined (NGRAN_GNB_CUUP)
|
||||
#include "CUSTOMIZED/ran_func_tc.h"
|
||||
#include "CUSTOMIZED/ran_func_gtp.h"
|
||||
#include "CUSTOMIZED/ran_func_pdcp.h"
|
||||
#endif
|
||||
|
||||
#include "O-RAN/ran_func_kpm.h"
|
||||
#include "O-RAN/ran_func_rc.h"
|
||||
|
||||
static
|
||||
void init_read_ind_tbl(read_ind_fp (*read_ind_tbl)[SM_AGENT_IF_READ_V0_END])
|
||||
{
|
||||
#if defined (NGRAN_GNB_DU)
|
||||
(*read_ind_tbl)[MAC_STATS_V0] = read_mac_sm;
|
||||
(*read_ind_tbl)[RLC_STATS_V0] = read_rlc_sm ;
|
||||
(*read_ind_tbl)[PDCP_STATS_V0] = read_pdcp_sm ;
|
||||
(*read_ind_tbl)[SLICE_STATS_V0] = read_slice_sm ;
|
||||
#endif
|
||||
#if defined (NGRAN_GNB_CUUP)
|
||||
(*read_ind_tbl)[TC_STATS_V0] = read_tc_sm ;
|
||||
(*read_ind_tbl)[GTP_STATS_V0] = read_gtp_sm ;
|
||||
(*read_ind_tbl)[PDCP_STATS_V0] = read_pdcp_sm ;
|
||||
#endif
|
||||
|
||||
(*read_ind_tbl)[KPM_STATS_V3_0] = read_kpm_sm ;
|
||||
(*read_ind_tbl)[RAN_CTRL_STATS_V1_03] = read_rc_sm;
|
||||
}
|
||||
@@ -47,12 +58,17 @@ void init_read_ind_tbl(read_ind_fp (*read_ind_tbl)[SM_AGENT_IF_READ_V0_END])
|
||||
static
|
||||
void init_read_setup_tbl(read_e2_setup_fp (*read_setup_tbl)[SM_AGENT_IF_E2_SETUP_ANS_V0_END])
|
||||
{
|
||||
#if defined (NGRAN_GNB_DU)
|
||||
(*read_setup_tbl)[MAC_AGENT_IF_E2_SETUP_ANS_V0] = read_mac_setup_sm;
|
||||
(*read_setup_tbl)[RLC_AGENT_IF_E2_SETUP_ANS_V0] = read_rlc_setup_sm ;
|
||||
(*read_setup_tbl)[PDCP_AGENT_IF_E2_SETUP_ANS_V0] = read_pdcp_setup_sm ;
|
||||
(*read_setup_tbl)[SLICE_AGENT_IF_E2_SETUP_ANS_V0] = read_slice_setup_sm ;
|
||||
#endif
|
||||
#if defined (NGRAN_GNB_CUUP)
|
||||
(*read_setup_tbl)[TC_AGENT_IF_E2_SETUP_ANS_V0] = read_tc_setup_sm ;
|
||||
(*read_setup_tbl)[GTP_AGENT_IF_E2_SETUP_ANS_V0] = read_gtp_setup_sm ;
|
||||
(*read_setup_tbl)[PDCP_AGENT_IF_E2_SETUP_ANS_V0] = read_pdcp_setup_sm ;
|
||||
#endif
|
||||
|
||||
(*read_setup_tbl)[KPM_V3_0_AGENT_IF_E2_SETUP_ANS_V0] = read_kpm_setup_sm ;
|
||||
(*read_setup_tbl)[RAN_CTRL_V1_3_AGENT_IF_E2_SETUP_ANS_V0] = read_rc_setup_sm;
|
||||
}
|
||||
@@ -60,24 +76,34 @@ void init_read_setup_tbl(read_e2_setup_fp (*read_setup_tbl)[SM_AGENT_IF_E2_SETUP
|
||||
static
|
||||
void init_write_ctrl( write_ctrl_fp (*write_ctrl_tbl)[SM_AGENT_IF_WRITE_CTRL_V0_END])
|
||||
{
|
||||
#if defined (NGRAN_GNB_DU)
|
||||
(*write_ctrl_tbl)[MAC_CTRL_REQ_V0] = write_ctrl_mac_sm;
|
||||
(*write_ctrl_tbl)[RLC_CTRL_REQ_V0] = write_ctrl_rlc_sm;
|
||||
(*write_ctrl_tbl)[PDCP_CTRL_REQ_V0] = write_ctrl_pdcp_sm;
|
||||
(*write_ctrl_tbl)[SLICE_CTRL_REQ_V0] = write_ctrl_slice_sm;
|
||||
#endif
|
||||
#if defined (NGRAN_GNB_CUUP)
|
||||
(*write_ctrl_tbl)[TC_CTRL_REQ_V0] = write_ctrl_tc_sm;
|
||||
(*write_ctrl_tbl)[GTP_CTRL_REQ_V0] = write_ctrl_gtp_sm;
|
||||
(*write_ctrl_tbl)[PDCP_CTRL_REQ_V0] = write_ctrl_pdcp_sm;
|
||||
#endif
|
||||
|
||||
(*write_ctrl_tbl)[RAN_CONTROL_CTRL_V1_03] = write_ctrl_rc_sm;
|
||||
}
|
||||
|
||||
static
|
||||
void init_write_subs(write_subs_fp (*write_subs_tbl)[SM_AGENT_IF_WRITE_SUBS_V0_END])
|
||||
{
|
||||
#if defined (NGRAN_GNB_DU)
|
||||
(*write_subs_tbl)[MAC_SUBS_V0] = NULL;
|
||||
(*write_subs_tbl)[RLC_SUBS_V0] = NULL;
|
||||
(*write_subs_tbl)[PDCP_SUBS_V0] = NULL;
|
||||
(*write_subs_tbl)[SLICE_SUBS_V0] = NULL;
|
||||
#endif
|
||||
#if defined (NGRAN_GNB_CUUP)
|
||||
(*write_subs_tbl)[TC_SUBS_V0] = NULL;
|
||||
(*write_subs_tbl)[GTP_SUBS_V0] = NULL;
|
||||
(*write_subs_tbl)[PDCP_SUBS_V0] = NULL;
|
||||
#endif
|
||||
|
||||
(*write_subs_tbl)[KPM_SUBS_V3_0] = NULL;
|
||||
(*write_subs_tbl)[RAN_CTRL_SUBS_V1_03] = write_subs_rc_sm;
|
||||
}
|
||||
@@ -96,4 +122,3 @@ sm_io_ag_ran_t init_ran_func_ag(void)
|
||||
|
||||
return io;
|
||||
}
|
||||
|
||||
|
||||
@@ -1307,3 +1307,15 @@ bool nr_pdcp_get_statistics(ue_id_t ue_id, int srb_flag, int rb_id, nr_pdcp_stat
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nr_pdcp_get_num_ues(ue_id_t *ue_list, int len)
|
||||
{
|
||||
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
|
||||
int num_ues = nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager);
|
||||
nr_pdcp_ue_t **nr_pdcp_ue_list = nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager);
|
||||
for (int i = 0; i < num_ues && i < len; i++)
|
||||
ue_list[i] = nr_pdcp_ue_list[i]->rntiMaybeUEid;
|
||||
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
|
||||
|
||||
return num_ues;
|
||||
}
|
||||
|
||||
@@ -125,6 +125,8 @@ void nr_pdcp_tick(int frame, int subframe);
|
||||
|
||||
nr_pdcp_ue_manager_t *nr_pdcp_sdap_get_ue_manager();
|
||||
|
||||
int nr_pdcp_get_num_ues(ue_id_t *ue_list, int len);
|
||||
|
||||
bool nr_pdcp_get_statistics(ue_id_t ue_id, int srb_flag, int rb_id, nr_pdcp_statistics_t *out);
|
||||
|
||||
#endif /* NR_PDCP_OAI_API_H */
|
||||
|
||||
Reference in New Issue
Block a user