Compare commits

...

17 Commits

Author SHA1 Message Date
Chieh-Chun Chen
4dc01c9826 Add RAN function for LTE MAC 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
90fe4547e9 Add E2 agent and RAN Functions for lte-softmodem 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
bf2a0d58d8 Add stop_agent_api() in nr-softmodem.c 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
4cfc58682d Fix: correct cu_du_id 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
aba541e1ab Add the case for handle no UE connected in KPM RF 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
11235c8a89 Add RLC average SDU waiting time in KPM RF 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
97d3088248 Add DL/UL throughput in KPM RF 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
0d33afed14 Fix KPM RF: get meas info from action definition and add ue info as input to fill kpm ind 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
7b4b6690b4 Fix KPM RF: get correct gnb data from RRC UE context 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
51cbc023e6 Add more RLC stats (GOL-delay and AVG-soujour) and correct the tx/rxsdu_bytes and tx/rxsdu_occ_bytes 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
edee49db17 Enable RAN function for GTP SM 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
7a67122dd9 Enable RAN function for PDCP SM 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
3aee5a3869 Enable RAN function for RLC SM 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
c7564ecf5c Fix: rename rlc delete entity 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
8060ac1409 Enable RAN fcuntion for MAC SM 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
8188b8549b Set default flexric branch to rebased-mir-dev 2023-07-17 12:44:46 +02:00
Chieh-Chun Chen
c736d3a4aa Fix: correct the RAN function CMakeList to include the directories from main CMakeList 2023-07-17 12:44:46 +02:00
76 changed files with 1826 additions and 296 deletions

2
.gitmodules vendored
View File

@@ -1,4 +1,4 @@
[submodule "openair2/E2AP/flexric"]
path = openair2/E2AP/flexric
url = https://gitlab.eurecom.fr/mosaic5g/flexric.git
branch = remotes/origin/mir_dev
branch = rebased-mir-dev

View File

@@ -282,6 +282,57 @@ add_definitions(-DHAVE_NETINET_IN_H)
set(E2_AGENT "OFF" CACHE STRING "O-RAN-compliant E2 Agent")
set_property(CACHE E2_AGENT PROPERTY STRINGS "ON" "OFF")
if(E2_AGENT)
set(E2AP_DIR ${OPENAIR2_DIR}/E2AP)
include_directories ("${E2AP_DIR}")
add_library(nr_e2_ran_func
${E2AP_DIR}/RAN_FUNCTION/NR/init_ran_func.c
${E2AP_DIR}/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_gtp.c
${E2AP_DIR}/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_mac.c
${E2AP_DIR}/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_pdcp.c
${E2AP_DIR}/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_rlc.c
${E2AP_DIR}/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_slice.c
${E2AP_DIR}/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_tc.c
${E2AP_DIR}/RAN_FUNCTION/NR/O-RAN/ran_func_kpm.c
${E2AP_DIR}/RAN_FUNCTION/NR/O-RAN/ran_func_rc.c
# For testing purposes
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_mac.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_rlc.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_pdcp.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_gtp.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_slice.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_tc.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_kpm.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_rc.c
${E2AP_DIR}/flexric/src/util/time_now_us.c
)
target_link_libraries(nr_e2_ran_func PRIVATE nr_rrc asn1_nr_rrc_hdrs lte_rrc asn1_lte_rrc_hdrs)
add_library(e2_ran_func
${E2AP_DIR}/RAN_FUNCTION/LTE/init_ran_func.c
${E2AP_DIR}/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_gtp.c
${E2AP_DIR}/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_mac.c
${E2AP_DIR}/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_pdcp.c
${E2AP_DIR}/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_rlc.c
${E2AP_DIR}/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_slice.c
${E2AP_DIR}/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_tc.c
${E2AP_DIR}/RAN_FUNCTION/LTE/O-RAN/ran_func_kpm.c
${E2AP_DIR}/RAN_FUNCTION/LTE/O-RAN/ran_func_rc.c
# For testing purposes
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_mac.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_rlc.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_pdcp.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_gtp.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_slice.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_tc.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_kpm.c
${E2AP_DIR}/flexric/test/rnd/fill_rnd_data_rc.c
${E2AP_DIR}/flexric/src/util/time_now_us.c
)
target_link_libraries(e2_ran_func PRIVATE nr_rrc asn1_nr_rrc_hdrs lte_rrc asn1_lte_rrc_hdrs)
endif()
##################################################
# ASN.1 grammar C code generation & dependencies #
##################################################
@@ -1456,7 +1507,7 @@ target_link_libraries(e1_pdcp_if PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap)
if(E2_AGENT)
target_link_libraries(L2_NR PUBLIC e2_agent e2_ran_func)
target_link_libraries(L2_NR PUBLIC e2_agent nr_e2_ran_func)
target_compile_definitions(L2_NR PRIVATE E2_AGENT)
endif()

View File

@@ -52,6 +52,11 @@
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
#ifdef E2_AGENT
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
#include "openair2/E2AP/RAN_FUNCTION/LTE/init_ran_func.h"
#endif
#include <openair1/PHY/phy_extern_ue.h>
#include "PHY/phy_vars.h"
@@ -519,6 +524,40 @@ int main ( int argc, char **argv )
pdcp_run(&ctxt);
}
#ifdef E2_AGENT
//////////////////////////////////
//////////////////////////////////
//// Init the E2 Agent
sm_io_ag_ran_t io = init_ran_func_ag();
// OAI Wrapper
e2_agent_args_t oai_args = RCconfig_E2agent();
AssertFatal(oai_args.sm_dir != NULL , "Please, specify the directory where the SMs are located in the config file, i.e., e2_agent = {near_ric_ip_addr = \"127.0.0.1\"; sm_dir = \"/usr/local/lib/flexric/\");} ");
AssertFatal(oai_args.ip != NULL , "Please, specify the IP address of the nearRT-RIC in the config file, i.e., e2_agent = {near_ric_ip_addr = \"127.0.0.1\"; sm_dir = \"/usr/local/lib/flexric/\"");
fr_args_t args = {.ip = oai_args.ip}; // init_fr_args(0, NULL);
memcpy(args.libs_dir, oai_args.sm_dir, 128);
sleep(1);
const eNB_RRC_INST* rrc = RC.rrc[0]; // mod_id = 0
assert(rrc != NULL && "rrc cannot be NULL");
const int mcc = rrc->configuration.mcc[0];
const int mnc = rrc->configuration.mnc[0];
const int mnc_digit_len = rrc->configuration.mnc_digit_length[0];
const ngran_node_t node_type = ngran_eNB;
int nb_id = rrc->configuration.cell_identity;
int cu_du_id = 0;
printf("[E2-AGENT]: mcc = %d mnc = %d mnc_digit = %d nd_id = %d \n", mcc, mnc, mnc_digit_len, nb_id);
bool init_agent = false;
init_agent_api(mcc, mnc, mnc_digit_len, nb_id, cu_du_id, node_type, io, &args);
init_agent = true;
#endif // E2_AGENT
// init UE_PF_PO and mutex lock
pthread_mutex_init(&ue_pf_po_mutex, NULL);
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*MAX_MOBILES_PER_ENB*MAX_NUM_CCs);
@@ -642,6 +681,10 @@ int main ( int argc, char **argv )
LOG_I(ENB_APP,"oai_exit=%d\n",oai_exit);
// stop threads
#ifdef E2_AGENT
if (init_agent) stop_agent_api();
#endif
#if 0 //Disable clean up because this tends to crash (and unnecessary)
if (RC.nb_inst == 0) {
if(IS_SOFTMODEM_DOSCOPE)

View File

@@ -84,7 +84,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#ifdef E2_AGENT
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
#include "openair2/E2AP/RAN_FUNCTION/init_ran_func.h"
#include "openair2/E2AP/RAN_FUNCTION/NR/init_ran_func.h"
#endif
@@ -721,19 +721,20 @@ int main( int argc, char **argv ) {
if (node_type == ngran_gNB) {
nb_id = rrc->configuration.cell_identity;
} else if (node_type == ngran_gNB_DU) {
cu_du_id = rrc->node_id + 1; // Hack to avoid been 0
nb_id = rrc->configuration.cell_identity;
cu_du_id = rrc->configuration.cell_identity;
} else if (node_type == ngran_gNB_CU) {
cu_du_id = rrc->node_id + 1;
nb_id = rrc->configuration.cell_identity;
cu_du_id = rrc->node_id;
} else {
LOG_E(NR_RRC, "not supported ran type detect\n");
}
printf("[E2 NODE]: mcc = %d mnc = %d mnc_digit = %d nb_id = %d \n", mcc, mnc, mnc_digit_len, nb_id);
printf("[E2-AGENT]: mcc = %d mnc = %d mnc_digit = %d nd_id = %d \n", mcc, mnc, mnc_digit_len, nb_id);
bool init_agent = false;
init_agent_api(mcc, mnc, mnc_digit_len, nb_id, cu_du_id, node_type, io, &args);
// }
init_agent = true;
#endif // E2_AGENT
@@ -794,6 +795,10 @@ int main( int argc, char **argv ) {
oai_exit=1;
printf("oai_exit=%d\n",oai_exit);
#ifdef E2_AGENT
if (init_agent) stop_agent_api();
#endif
// cleanup
if (RC.nb_nr_L1_inst > 0)
stop_gNB(RC.nb_nr_L1_inst);

View File

@@ -2,7 +2,7 @@
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/flexric/CMakeLists.txt)
message(STATUS "E2AP submoduled not detected, therefore $git submodule init && git submodule update.")
execute_process(COMMAND git submodule init)
execute_process(COMMAND git submodule update)
execute_process(COMMAND git submodule update --init --recursive --remote)
else()
message(STATUS "E2AP submodule detected.")
endif()

View File

@@ -1,12 +1,2 @@
add_subdirectory(CUSTOMIZED)
add_subdirectory(O-RAN)
add_library(e2_ran_func STATIC
init_ran_func.c
)
target_link_libraries(e2_ran_func
PUBLIC
e2_ran_func_cust
e2_ran_func_oran
)
add_subdirectory(LTE)
add_subdirectory(NR)

View File

@@ -1,17 +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
)

View File

@@ -1,13 +0,0 @@
#ifndef RAN_FUNC_SM_GTP_READ_WRITE_AGENT_H
#define RAN_FUNC_SM_GTP_READ_WRITE_AGENT_H
#include "../../flexric/src/agent/e2_agent_api.h"
void read_gtp_sm(void*);
void read_gtp_setup_sm(void*);
sm_ag_if_ans_t write_ctrl_gtp_sm(void const*);
#endif

View File

@@ -1,24 +0,0 @@
#include "ran_func_mac.h"
#include "../../flexric/test/rnd/fill_rnd_data_mac.h"
#include <assert.h>
void read_mac_sm(void* data)
{
assert(data != NULL);
mac_ind_data_t* mac = (mac_ind_data_t*)data;
fill_mac_ind_data(mac);
}
void read_mac_setup_sm(void* data)
{
assert(data != NULL);
assert(0 !=0 && "Not supported");
}
sm_ag_if_ans_t write_ctrl_mac_sm(void const* data)
{
assert(data != NULL);
assert(0 !=0 && "Not supported");
}

View File

@@ -1,12 +0,0 @@
#ifndef SM_MAC_READ_WRITE_AGENT_H
#define SM_MAC_READ_WRITE_AGENT_H
#include "../../flexric/src/agent/e2_agent_api.h"
void read_mac_sm(void*);
void read_mac_setup_sm(void*);
sm_ag_if_ans_t write_ctrl_mac_sm(void const*);
#endif

View File

@@ -1,13 +0,0 @@
#ifndef RAN_FUNC_SM_PDCP_READ_WRITE_AGENT_H
#define RAN_FUNC_SM_PDCP_READ_WRITE_AGENT_H
#include "../../flexric/src/agent/e2_agent_api.h"
void read_pdcp_sm(void*);
void read_pdcp_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_pdcp_sm(void const* data);
#endif

View File

@@ -1,13 +0,0 @@
#ifndef RAN_FUNC_SM_RLC_READ_WRITE_AGENT_H
#define RAN_FUNC_SM_RLC_READ_WRITE_AGENT_H
#include "../../flexric/src/agent/e2_agent_api.h"
void read_rlc_sm(void*);
void read_rlc_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_rlc_sm(void const* data);
#endif

View File

@@ -1,13 +0,0 @@
#ifndef RAN_FUNC_SM_SLICE_READ_WRITE_AGENT_H
#define RAN_FUNC_SM_SLICE_READ_WRITE_AGENT_H
#include "../../flexric/src/agent/e2_agent_api.h"
void read_slice_sm(void*);
void read_slice_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_slice_sm(void const* data);
#endif

View File

@@ -1,13 +0,0 @@
#ifndef RAN_FUNC_SM_TC_READ_WRITE_AGENT_H
#define RAN_FUNC_SM_TC_READ_WRITE_AGENT_H
#include "../../flexric/src/agent/e2_agent_api.h"
void read_tc_sm(void*);
void read_tc_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_tc_sm(void const* data);
#endif

View File

@@ -0,0 +1,2 @@
add_subdirectory(CUSTOMIZED)
add_subdirectory(O-RAN)

View File

@@ -0,0 +1,2 @@

View File

@@ -1,5 +1,5 @@
#include "ran_func_gtp.h"
#include "../../flexric/test/rnd/fill_rnd_data_gtp.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_gtp.h"
#include <assert.h>
void read_gtp_sm(void * data)

View File

@@ -0,0 +1,13 @@
#ifndef LTE_RAN_FUNC_SM_GTP_READ_WRITE_AGENT_H
#define LTE_RAN_FUNC_SM_GTP_READ_WRITE_AGENT_H
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
void read_gtp_sm(void*);
void read_gtp_setup_sm(void*);
sm_ag_if_ans_t write_ctrl_gtp_sm(void const*);
#endif

View File

@@ -0,0 +1,104 @@
#include "ran_func_mac.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_mac.h"
#include <assert.h>
static
const int mod_id = 0;
static
const int CC_id = 0;
void read_mac_sm(void* data)
{
assert(data != NULL);
mac_ind_data_t* mac = (mac_ind_data_t*)data;
//fill_mac_ind_data(mac);
mac->msg.tstamp = time_now_us();
const size_t num_ues = RC.mac[mod_id]->UE_info.num_UEs;
mac->msg.len_ue_stats = num_ues;
if (mac->msg.len_ue_stats > 0) {
mac->msg.ue_stats = calloc(mac->msg.len_ue_stats, sizeof(mac_ue_stats_impl_t));
assert(mac->msg.ue_stats != NULL && "Memory exhausted" );
}
const UE_list_t* ue_list = &RC.mac[mod_id]->UE_info.list;
size_t i = 0; //TODO
for (int ue_id = ue_list->head; ue_id >= 0; ue_id = ue_list->next[ue_id]) {
const eNB_UE_STATS* uestats = &RC.mac[mod_id]->UE_info.eNB_UE_stats[CC_id][ue_id];
const UE_sched_ctrl_t *sched_ctrl = &RC.mac[mod_id]->UE_info.UE_sched_ctrl[ue_id];
const UE_TEMPLATE *template = &RC.mac[mod_id]->UE_info.UE_template[CC_id][ue_id];
mac_ue_stats_impl_t* rd = &mac->msg.ue_stats[i];
rd->frame = 0; // TODO
rd->slot = 0; // TODO
rd->dl_aggr_tbs = uestats->total_pdu_bytes;
rd->ul_aggr_tbs = uestats->total_ulsch_TBS;
rd->dl_curr_tbs = uestats->TBS;
rd->dl_sched_rb = uestats->rbs_used;
rd->ul_curr_tbs = uestats->ulsch_TBS;
rd->ul_sched_rb = uestats->rbs_used_rx;
rd->rnti = uestats->crnti;
rd->dl_aggr_prb = uestats->total_rbs_used;
rd->ul_aggr_prb = uestats->total_rbs_used_rx;
rd->dl_aggr_retx_prb = uestats->rbs_used_retx;
rd->ul_aggr_retx_prb = uestats->rbs_used_retx_rx;
rd->dl_aggr_bytes_sdus = uestats->total_sdu_bytes;
uint64_t ul_sdu_bytes = 0;
for (int i = 0; i < NB_RB_MAX; ++i)
ul_sdu_bytes += uestats->num_bytes_rx[i];
rd->ul_aggr_bytes_sdus = ul_sdu_bytes;
rd->dl_aggr_sdus = uestats->num_mac_sdu_tx;
rd->ul_aggr_sdus = uestats->num_mac_sdu_rx;
rd->pusch_snr = sched_ctrl->pusch_snr[CC_id];
rd->pucch_snr = sched_ctrl->pucch1_snr[CC_id];
rd->wb_cqi = sched_ctrl->dl_cqi[CC_id];
rd->dl_mcs1 = uestats->dlsch_mcs1;
rd->dl_bler = 0; // TODO
rd->ul_mcs1 = uestats->ulsch_mcs1;
rd->ul_bler = sched_ctrl->pusch_bler[CC_id];
rd->dl_mcs2 = uestats->dlsch_mcs2;
rd->ul_mcs2 = uestats->ulsch_mcs2;
rd->phr = template->phr_info;
const uint32_t bufferSize = template->estimated_ul_buffer - template->scheduled_ul_bytes;
rd->bsr = bufferSize;
const size_t numDLHarq = 4;
rd->dl_num_harq = numDLHarq;
for (uint8_t j = 0; j < numDLHarq; ++j)
rd->dl_harq[j] = uestats->dlsch_rounds[j];
rd->dl_harq[numDLHarq] = uestats->dlsch_errors;
const size_t numUlHarq = 4;
rd->ul_num_harq = numUlHarq;
for (uint8_t j = 0; j < numUlHarq; ++j)
rd->ul_harq[j] = uestats->ulsch_rounds[j];
rd->ul_harq[numUlHarq] = uestats->ulsch_errors;
++i;
}
}
void read_mac_setup_sm(void* data)
{
assert(data != NULL);
assert(0 !=0 && "Not supported");
}
sm_ag_if_ans_t write_ctrl_mac_sm(void const* data)
{
assert(data != NULL);
assert(0 !=0 && "Not supported");
}

View File

@@ -0,0 +1,15 @@
#ifndef LTE_RAN_FUNC_SM_MAC_READ_WRITE_AGENT_H
#define LTE_RAN_FUNC_SM_MAC_READ_WRITE_AGENT_H
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
#include "common/ran_context.h"
#include "openair2/LAYER2/MAC/mac.h"
#include "openair2/E2AP/flexric/src/util/time_now_us.h"
void read_mac_sm(void*);
void read_mac_setup_sm(void*);
sm_ag_if_ans_t write_ctrl_mac_sm(void const*);
#endif

View File

@@ -1,5 +1,5 @@
#include "ran_func_pdcp.h"
#include "../../flexric/test/rnd/fill_rnd_data_pdcp.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_pdcp.h"
#include <assert.h>
void read_pdcp_sm(void* data)

View File

@@ -0,0 +1,13 @@
#ifndef LTE_RAN_FUNC_SM_PDCP_READ_WRITE_AGENT_H
#define LTE_RAN_FUNC_SM_PDCP_READ_WRITE_AGENT_H
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
void read_pdcp_sm(void*);
void read_pdcp_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_pdcp_sm(void const* data);
#endif

View File

@@ -1,5 +1,5 @@
#include "ran_func_rlc.h"
#include "../../flexric/test/rnd/fill_rnd_data_rlc.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_rlc.h"
void read_rlc_sm(void* data)
{

View File

@@ -0,0 +1,13 @@
#ifndef LTE_RAN_FUNC_SM_RLC_READ_WRITE_AGENT_H
#define LTE_RAN_FUNC_SM_RLC_READ_WRITE_AGENT_H
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
void read_rlc_sm(void*);
void read_rlc_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_rlc_sm(void const* data);
#endif

View File

@@ -1,5 +1,5 @@
#include "ran_func_slice.h"
#include "../../flexric/test/rnd/fill_rnd_data_slice.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_slice.h"
#include <assert.h>
#include <stdio.h>

View File

@@ -0,0 +1,13 @@
#ifndef LTE_RAN_FUNC_SM_SLICE_READ_WRITE_AGENT_H
#define LTE_RAN_FUNC_SM_SLICE_READ_WRITE_AGENT_H
#include "E2AP/flexric/src/agent/e2_agent_api.h"
void read_slice_sm(void*);
void read_slice_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_slice_sm(void const* data);
#endif

View File

@@ -1,5 +1,5 @@
#include "ran_func_tc.h"
#include "../../flexric/test/rnd/fill_rnd_data_tc.h"
#include "E2AP/flexric/test/rnd/fill_rnd_data_tc.h"
#include <assert.h>
void read_tc_sm(void* data)

View File

@@ -0,0 +1,13 @@
#ifndef LTE_RAN_FUNC_SM_TC_READ_WRITE_AGENT_H
#define LTE_RAN_FUNC_SM_TC_READ_WRITE_AGENT_H
#include "E2AP/flexric/src/agent/e2_agent_api.h"
void read_tc_sm(void*);
void read_tc_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_tc_sm(void const* data);
#endif

View File

@@ -1,43 +1,38 @@
#include "ran_func_kpm.h"
#include "../../flexric/test/rnd/fill_rnd_data_kpm.h"
#include "../../flexric/src/util/time_now_us.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_kpm.h"
#include "openair2/E2AP/flexric/src/util/time_now_us.h"
#include <assert.h>
#include <stdio.h>
static
gnb_e2sm_t fill_gnb_data(void)
static
gnb_e2sm_t fill_rnd_gnb_data(void)
{
gnb_e2sm_t gnb = {0};
// 6.2.3.16
// Mandatory
// AMF UE NGAP ID
gnb.amf_ue_ngap_id = 112358132134; // % 2^40;
// Mandatory
//GUAMI 6.2.3.17
gnb.amf_ue_ngap_id = (rand() % 2^40) + 0;
gnb.guami.plmn_id = (e2sm_plmn_t) {.mcc = 505, .mnc = 1, .mnc_digit_len = 2};
gnb.guami.amf_region_id = (rand() % 2^8) + 0;
gnb.guami.amf_set_id = (rand() % 2^10) + 0;
gnb.guami.amf_ptr = (rand() % 2^6) + 0;
return gnb;
}
static
ue_id_e2sm_t fill_ue_id_data(void)
static
ue_id_e2sm_t fill_rnd_ue_id_data()
{
ue_id_e2sm_t ue_id_data = {0};
ue_id_data.type = GNB_UE_ID_E2SM;
ue_id_data.gnb = fill_gnb_data();
ue_id_data.gnb = fill_rnd_gnb_data();
return ue_id_data;
}
void copy_ba_to_str(const uint8_t* buffer, size_t length, char* str) {
memcpy(str, buffer, length);
str[length] = '\0';
}
static
kpm_ind_msg_format_1_t fill_kpm_ind_msg_frm_1(void)
kpm_ind_msg_format_1_t fill_kpm_ind_msg_frm_1(kpm_act_def_format_1_t const act_def_fr1)
{
kpm_ind_msg_format_1_t msg_frm_1 = {0};
@@ -47,28 +42,65 @@ kpm_ind_msg_format_1_t fill_kpm_ind_msg_frm_1(void)
msg_frm_1.meas_data_lst = calloc(msg_frm_1.meas_data_lst_len, sizeof(*msg_frm_1.meas_data_lst));
assert(msg_frm_1.meas_data_lst != NULL && "Memory exhausted" );
for (size_t i = 0; i < msg_frm_1.meas_data_lst_len; i++){
// Measurement Record
msg_frm_1.meas_data_lst[i].meas_record_len = 1; // (rand() % 65535) + 1;
msg_frm_1.meas_data_lst[i].meas_record_lst = calloc(msg_frm_1.meas_data_lst[i].meas_record_len, sizeof(meas_record_lst_t));
assert(msg_frm_1.meas_data_lst[i].meas_record_lst != NULL && "Memory exhausted" );
for (size_t j = 0; j < msg_frm_1.meas_data_lst[i].meas_record_len; j++){
msg_frm_1.meas_data_lst[i].meas_record_lst[j].value = REAL_MEAS_VALUE; // rand()%END_MEAS_VALUE;
msg_frm_1.meas_data_lst[i].meas_record_lst[j].real_val = (rand() % 256) + 0.1;
size_t const rec_data_len = act_def_fr1.meas_info_lst_len; // Recoding Data Length
for (size_t i = 0; i < msg_frm_1.meas_data_lst_len; i++) {
// Measurement Record
meas_data_lst_t* meas_data = &msg_frm_1.meas_data_lst[i];
meas_data->meas_record_len = rec_data_len;
meas_data->meas_record_lst = calloc(meas_data->meas_record_len, sizeof(meas_record_lst_t));
assert(meas_data->meas_record_lst != NULL && "Memory exhausted");
for (size_t j = 0; j < meas_data->meas_record_len; j++) {
meas_record_lst_t* meas_record = &meas_data->meas_record_lst[j];
meas_type_t meas_info_type = act_def_fr1.meas_info_lst[j].meas_type;
if (meas_info_type.type == NAME_MEAS_TYPE) {
// Get Meas Info Name from Action Definition
size_t length = meas_info_type.name.len;
char meas_info_name_str[length + 1];
copy_ba_to_str(meas_info_type.name.buf, length, meas_info_name_str);
// Get value based on Meas Info Name
if (strcmp(meas_info_name_str, "DRB.IPThpDl.QCI") == 0 ? true : false) {
meas_record->value = REAL_MEAS_VALUE;
meas_record->real_val = (rand() % 256) + 0;
} else if (strcmp(meas_info_name_str, "DRB.IPThpUl.QCI") == 0 ? true : false) {
meas_record->value = REAL_MEAS_VALUE;
meas_record->real_val = (rand() % 256) + 0;
} else if (strcmp(meas_info_name_str, "DRB.RlcSduDelayDl") == 0 ? true : false) {
meas_record->value = REAL_MEAS_VALUE;
meas_record->real_val = (rand() % 256) + 0;
} else {
printf("not implement value for measurement name %s\n", meas_info_name_str);
meas_record->value = REAL_MEAS_VALUE;
meas_record->real_val = 1234;
}
} else {
printf("not implement value for measurement type %d\n", meas_info_type.type);
meas_record->value = REAL_MEAS_VALUE;
meas_record->real_val = 1234;
}
}
}
// Measurement Information - OPTIONAL
msg_frm_1.meas_info_lst_len = num_drbs;
msg_frm_1.meas_info_lst_len = rec_data_len;
msg_frm_1.meas_info_lst = calloc(msg_frm_1.meas_info_lst_len, sizeof(meas_info_format_1_lst_t));
assert(msg_frm_1.meas_info_lst != NULL && "Memory exhausted" );
// Get measInfo from action definition
for (size_t i = 0; i < msg_frm_1.meas_info_lst_len; i++) {
// Measurement Type
msg_frm_1.meas_info_lst[i].meas_type.type = ID_MEAS_TYPE;
// DRB ID
msg_frm_1.meas_info_lst[i].meas_type.id = i;
msg_frm_1.meas_info_lst[i].meas_type.type = act_def_fr1.meas_info_lst[i].meas_type.type;
// Measurement Name
if (act_def_fr1.meas_info_lst[i].meas_type.type == NAME_MEAS_TYPE) {
msg_frm_1.meas_info_lst[i].meas_type.name.buf = calloc(act_def_fr1.meas_info_lst[i].meas_type.name.len, sizeof(uint8_t));
memcpy(msg_frm_1.meas_info_lst[i].meas_type.name.buf, act_def_fr1.meas_info_lst[i].meas_type.name.buf, act_def_fr1.meas_info_lst[i].meas_type.name.len);
msg_frm_1.meas_info_lst[i].meas_type.name.len = act_def_fr1.meas_info_lst[i].meas_type.name.len;
} else {
msg_frm_1.meas_info_lst[i].meas_type.id = act_def_fr1.meas_info_lst[i].meas_type.id;
}
// Label Information
msg_frm_1.meas_info_lst[i].label_info_lst_len = 1;
@@ -84,23 +116,23 @@ kpm_ind_msg_format_1_t fill_kpm_ind_msg_frm_1(void)
return msg_frm_1;
}
static
kpm_ind_msg_format_3_t fill_kpm_ind_msg_frm_3_sta(void)
static
kpm_ind_msg_format_3_t fill_kpm_ind_msg_frm_3_sta(kpm_act_def_format_1_t const act_def_fr1)
{
kpm_ind_msg_format_3_t msg_frm_3 = {0};
uint32_t num_ues = 1;
msg_frm_3.ue_meas_report_lst_len = num_ues; // (rand() % 65535) + 1;
msg_frm_3.ue_meas_report_lst_len = 2; // (rand() % 65535) + 1;
msg_frm_3.meas_report_per_ue = calloc(msg_frm_3.ue_meas_report_lst_len, sizeof(meas_report_per_ue_t));
assert(msg_frm_3.meas_report_per_ue != NULL && "Memory exhausted");
for (size_t i = 0; i < msg_frm_3.ue_meas_report_lst_len; i++)
{
msg_frm_3.meas_report_per_ue[i].ue_meas_report_lst = fill_ue_id_data();
msg_frm_3.meas_report_per_ue[i].ind_msg_format_1 = fill_kpm_ind_msg_frm_1();
msg_frm_3.meas_report_per_ue[i].ue_meas_report_lst = fill_rnd_ue_id_data();
msg_frm_3.meas_report_per_ue[i].ind_msg_format_1 = fill_kpm_ind_msg_frm_1(act_def_fr1);
}
return msg_frm_3;
}
@@ -147,7 +179,7 @@ void read_kpm_sm(void* data)
assert(data != NULL);
//assert(data->type == KPM_STATS_V3_0);
kpm_rd_ind_data_t* kpm = (kpm_rd_ind_data_t*)data;
kpm_rd_ind_data_t* const kpm = (kpm_rd_ind_data_t*)data;
assert(kpm->act_def!= NULL && "Cannot be NULL");
if(kpm->act_def->type == FORMAT_4_ACTION_DEFINITION){
@@ -157,13 +189,14 @@ void read_kpm_sm(void* data)
printf("Matching condition: UEs with CQI greater than %ld \n", *kpm->act_def->frm_4.matching_cond_lst[0].test_info_lst.int_value );
}
printf("Parameter to report: %s \n", kpm->act_def->frm_4.action_def_format_1.meas_info_lst->meas_type.name.buf);
for (size_t i = 0; i < kpm->act_def->frm_4.action_def_format_1.meas_info_lst_len; i++)
printf("Parameter to report: %s \n", kpm->act_def->frm_4.action_def_format_1.meas_info_lst[i].meas_type.name.buf);
kpm->ind.hdr = fill_kpm_ind_hdr_sta();
// 7.8 Supported RIC Styles and E2SM IE Formats
// Format 4 corresponds to indication message 3
kpm->ind.msg.type = FORMAT_3_INDICATION_MESSAGE;
kpm->ind.msg.frm_3 = fill_kpm_ind_msg_frm_3_sta();
kpm->ind.msg.frm_3 = fill_kpm_ind_msg_frm_3_sta(kpm->act_def->frm_4.action_def_format_1);
} else {
kpm->ind.hdr = fill_kpm_ind_hdr();
kpm->ind.msg = fill_kpm_ind_msg();

View File

@@ -0,0 +1,13 @@
#ifndef LTE_RAN_FUNC_SM_KPM_READ_WRITE_AGENT_H
#define LTE_RAN_FUNC_SM_KPM_READ_WRITE_AGENT_H
#include "E2AP/flexric/src/agent/e2_agent_api.h"
void read_kpm_sm(void*);
void read_kpm_setup_sm(void*);
sm_ag_if_ans_t write_ctrl_kpm_sm(void const* src);
#endif

View File

@@ -1,7 +1,7 @@
#include "ran_func_rc.h"
#include "../../flexric/test/rnd/fill_rnd_data_rc.h"
#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 "openair2/E2AP/flexric/test/rnd/fill_rnd_data_rc.h"
#include "openair2/E2AP/flexric/src/sm/rc_sm/ie/ir/lst_ran_param.h"
#include "openair2/E2AP/flexric/src/sm/rc_sm/ie/ir/ran_param_list.h"
#include <assert.h>
#include <stdio.h>
#include <pthread.h>

View File

@@ -0,0 +1,15 @@
#ifndef LTE_RAN_FUNC_SM_RAN_CTRL_READ_WRITE_AGENT_H
#define LTE_RAN_FUNC_SM_RAN_CTRL_READ_WRITE_AGENT_H
#include "E2AP/flexric/src/agent/e2_agent_api.h"
void read_rc_sm(void *);
void read_rc_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_rc_sm(void const* data);
sm_ag_if_ans_t write_subs_rc_sm(void const* src);
#endif

View File

@@ -0,0 +1,73 @@
#include "init_ran_func.h"
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
#include "E2AP/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_mac.h"
#include "E2AP/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_rlc.h"
#include "E2AP/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_pdcp.h"
#include "E2AP/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_slice.h"
#include "E2AP/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_tc.h"
#include "E2AP/RAN_FUNCTION/LTE/CUSTOMIZED/ran_func_gtp.h"
#include "E2AP/RAN_FUNCTION/LTE/O-RAN/ran_func_kpm.h"
#include "E2AP/RAN_FUNCTION/LTE/O-RAN/ran_func_rc.h"
static
void init_read_ind_tbl(read_ind_fp (*read_ind_tbl)[SM_AGENT_IF_READ_V0_END])
{
(*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 ;
(*read_ind_tbl)[TC_STATS_V0] = read_tc_sm ;
(*read_ind_tbl)[GTP_STATS_V0] = read_gtp_sm ;
(*read_ind_tbl)[KPM_STATS_V3_0] = read_kpm_sm ;
(*read_ind_tbl)[RAN_CTRL_STATS_V1_03] = read_rc_sm;
}
static
void init_read_setup_tbl(read_e2_setup_fp (*read_setup_tbl)[SM_AGENT_IF_E2_SETUP_ANS_V0_END])
{
(*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 ;
(*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)[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;
}
static
void init_write_ctrl( write_ctrl_fp (*write_ctrl_tbl)[SM_AGENT_IF_WRITE_CTRL_V0_END])
{
(*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;
(*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)[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])
{
(*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;
(*write_subs_tbl)[TC_SUBS_V0] = NULL;
(*write_subs_tbl)[GTP_SUBS_V0] = NULL;
(*write_subs_tbl)[KPM_SUBS_V3_0] = NULL;
(*write_subs_tbl)[RAN_CTRL_SUBS_V1_03] = write_subs_rc_sm;
}
sm_io_ag_ran_t init_ran_func_ag(void)
{
sm_io_ag_ran_t io = {0};
init_read_ind_tbl(&io.read_ind_tbl);
init_read_setup_tbl(&io.read_setup_tbl);
init_write_ctrl(&io.write_ctrl_tbl);
init_write_subs(&io.write_subs_tbl);
return io;
}

View File

@@ -0,0 +1,32 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef LTE_RAN_FUNC_INIT_E2_H
#define LTE_RAN_FUNC_INIT_E2_H
#include "E2AP/flexric/src/sm/sm_io.h"
sm_io_ag_ran_t init_ran_func_ag(void);
#endif

View File

@@ -0,0 +1,2 @@
add_subdirectory(CUSTOMIZED)
add_subdirectory(O-RAN)

View File

@@ -0,0 +1,2 @@

View File

@@ -0,0 +1,68 @@
#include "ran_func_gtp.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_gtp.h"
#include <assert.h>
static
const int mod_id = 0;
void read_gtp_sm(void * data)
{
assert(data != NULL);
gtp_ind_data_t* gtp = (gtp_ind_data_t*)(data);
//fill_gtp_ind_data(gtp);
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;
}
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(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++;
}
}
void read_gtp_setup_sm(void* data)
{
assert(data != NULL);
assert(0 !=0 && "Not supported");
}
sm_ag_if_ans_t write_ctrl_gtp_sm(void const* src)
{
assert(src != NULL);
assert(0 !=0 && "Not supported");
}

View File

@@ -0,0 +1,17 @@
#ifndef NR_RAN_FUNC_SM_GTP_READ_WRITE_AGENT_H
#define NR_RAN_FUNC_SM_GTP_READ_WRITE_AGENT_H
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.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/RRC/NR/rrc_gNB_UE_context.h"
void read_gtp_sm(void*);
void read_gtp_setup_sm(void*);
sm_ag_if_ans_t write_ctrl_gtp_sm(void const*);
#endif

View File

@@ -0,0 +1,104 @@
#include "ran_func_mac.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_mac.h"
#include <assert.h>
static
const int mod_id = 0;
void read_mac_sm(void* data)
{
assert(data != NULL);
mac_ind_data_t* mac = (mac_ind_data_t*)data;
//fill_mac_ind_data(mac);
mac->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;
}
mac->msg.len_ue_stats = num_ues;
if(mac->msg.len_ue_stats > 0){
mac->msg.ue_stats = calloc(mac->msg.len_ue_stats, sizeof(mac_ue_stats_impl_t));
assert(mac->msg.ue_stats != NULL && "Memory exhausted" );
}
size_t i = 0; //TODO
UE_iterator(UE_info->list, UE) {
const NR_UE_sched_ctrl_t* sched_ctrl = &UE->UE_sched_ctrl;
mac_ue_stats_impl_t* rd = &mac->msg.ue_stats[i];
rd->frame = RC.nrmac[mod_id]->frame;
rd->slot = RC.nrmac[mod_id]->slot;
rd->dl_aggr_tbs = UE->mac_stats.dl.total_bytes;
rd->ul_aggr_tbs = UE->mac_stats.ul.total_bytes;
if (is_xlsch_in_slot(RC.nrmac[mod_id]->dlsch_slot_bitmap[rd->slot / 64], rd->slot)) {
rd->dl_curr_tbs = UE->mac_stats.dl.current_bytes;
rd->dl_sched_rb = UE->mac_stats.dl.current_rbs;
}
if (is_xlsch_in_slot(RC.nrmac[mod_id]->ulsch_slot_bitmap[rd->slot / 64], rd->slot)) {
rd->ul_curr_tbs = UE->mac_stats.ul.current_bytes;
rd->ul_sched_rb = sched_ctrl->sched_pusch.rbSize;
}
rd->rnti = UE->rnti;
rd->dl_aggr_prb = UE->mac_stats.dl.total_rbs;
rd->ul_aggr_prb = UE->mac_stats.ul.total_rbs;
rd->dl_aggr_retx_prb = UE->mac_stats.dl.total_rbs_retx;
rd->ul_aggr_retx_prb = UE->mac_stats.ul.total_rbs_retx;
rd->dl_aggr_bytes_sdus = UE->mac_stats.dl.lc_bytes[3];
rd->ul_aggr_bytes_sdus = UE->mac_stats.ul.lc_bytes[3];
rd->dl_aggr_sdus = UE->mac_stats.dl.num_mac_sdu;
rd->ul_aggr_sdus = UE->mac_stats.ul.num_mac_sdu;
rd->pusch_snr = (float) sched_ctrl->pusch_snrx10 / 10; //: float = -64;
rd->pucch_snr = (float) sched_ctrl->pucch_snrx10 / 10; //: float = -64;
rd->wb_cqi = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb;
rd->dl_mcs1 = sched_ctrl->dl_bler_stats.mcs;
rd->dl_bler = sched_ctrl->dl_bler_stats.bler;
rd->ul_mcs1 = sched_ctrl->ul_bler_stats.mcs;
rd->ul_bler = sched_ctrl->ul_bler_stats.bler;
rd->dl_mcs2 = 0;
rd->ul_mcs2 = 0;
rd->phr = sched_ctrl->ph;
const uint32_t bufferSize = sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes;
rd->bsr = bufferSize;
const size_t numDLHarq = 4;
rd->dl_num_harq = numDLHarq;
for (uint8_t j = 0; j < numDLHarq; ++j)
rd->dl_harq[j] = UE->mac_stats.dl.rounds[j];
rd->dl_harq[numDLHarq] = UE->mac_stats.dl.errors;
const size_t numUlHarq = 4;
rd->ul_num_harq = numUlHarq;
for (uint8_t j = 0; j < numUlHarq; ++j)
rd->ul_harq[j] = UE->mac_stats.ul.rounds[j];
rd->ul_harq[numUlHarq] = UE->mac_stats.ul.errors;
++i;
}
}
void read_mac_setup_sm(void* data)
{
assert(data != NULL);
assert(0 !=0 && "Not supported");
}
sm_ag_if_ans_t write_ctrl_mac_sm(void const* data)
{
assert(data != NULL);
assert(0 !=0 && "Not supported");
}

View File

@@ -0,0 +1,15 @@
#ifndef NR_RAN_FUNC_SM_MAC_READ_WRITE_AGENT_H
#define NR_RAN_FUNC_SM_MAC_READ_WRITE_AGENT_H
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.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"
void read_mac_sm(void*);
void read_mac_setup_sm(void*);
sm_ag_if_ans_t write_ctrl_mac_sm(void const*);
#endif

View File

@@ -0,0 +1,167 @@
#include "ran_func_pdcp.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_pdcp.h"
#include <assert.h>
static
const int mod_id = 0;
static
uint32_t num_act_rb(NR_UEs_t* UE_info)
{
assert(UE_info!= NULL);
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;
}
}
return act_rb;
}
void read_pdcp_sm(void* data)
{
assert(data != NULL);
//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();
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;
}
}
} 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;
}
}
}
}
void read_pdcp_setup_sm(void* data)
{
assert(data != NULL);
// assert(data->type == PDCP_AGENT_IF_E2_SETUP_ANS_V0 );
assert(0 !=0 && "Not supported");
}
sm_ag_if_ans_t write_ctrl_pdcp_sm(void const* data)
{
assert(data != NULL);
// assert(data->type == PDCP_CTRL_REQ_V0 );
assert(0 !=0 && "Not supported");
sm_ag_if_ans_t ans = {0};
return ans;
}

View File

@@ -0,0 +1,20 @@
#ifndef NR_RAN_FUNC_SM_PDCP_READ_WRITE_AGENT_H
#define NR_RAN_FUNC_SM_PDCP_READ_WRITE_AGENT_H
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
#include "common/ran_context.h"
#include "common/ngran_types.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"
void read_pdcp_sm(void*);
void read_pdcp_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_pdcp_sm(void const* data);
#endif

View File

@@ -0,0 +1,147 @@
#include "ran_func_rlc.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_rlc.h"
static
const int mod_id = 0;
uint32_t num_act_rb(NR_UEs_t* const UE_info)
{
assert(UE_info!= NULL);
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;
}
}
return act_rb;
}
void active_avg_to_tx(NR_UEs_t* const UE_info)
{
assert(UE_info!= NULL);
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) nr_rlc_activate_avg_time_to_tx(rnti, rb_id, 1);
}
}
}
void read_rlc_sm(void* data)
{
assert(data != NULL);
// assert(data->type == RLC_STATS_V0);
rlc_ind_data_t* rlc = (rlc_ind_data_t*)data;
//fill_rlc_ind_data(rlc);
// use MAC structures to get RNTIs
NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info;
uint32_t const act_rb = num_act_rb(UE_info);
//assert(0!=0 && "Read RLC called");
// activate the rlc to calculate the average tx time
active_avg_to_tx(UE_info);
rlc->msg.len = act_rb;
if(rlc->msg.len > 0){
rlc->msg.rb = calloc(rlc->msg.len, sizeof(rlc_radio_bearer_stats_t));
assert(rlc->msg.rb != NULL && "Memory exhausted");
}
rlc->msg.tstamp = time_now_us();
uint32_t i = 0;
UE_iterator(UE_info->list, UE) {
uint16_t const rnti = UE->rnti;
//for every LC ID
for(int rb_id = 1; rb_id < 6; ++rb_id ){
nr_rlc_statistics_t rb_rlc = {0};
const int srb_flag = 0;
const bool rc = nr_rlc_get_statistics(rnti, srb_flag, rb_id, &rb_rlc);
if(!rc) continue;
rlc_radio_bearer_stats_t* sm_rb = &rlc->msg.rb[i];
/* TX */
sm_rb->txpdu_pkts = rb_rlc.txpdu_pkts;
sm_rb->txpdu_bytes = rb_rlc.txpdu_bytes; /* aggregated amount of transmitted bytes in RLC PDUs */
/* TODO? */
/* (TO BE DISCUSSED) HOL delay of the packet to be transmitted (RLC delay + MAC delay) */
// sm_rb->txpdu_wt_ms += rb_rlc.txsdu_avg_time_to_tx;
sm_rb->txpdu_dd_pkts = rb_rlc.txpdu_dd_pkts; /* aggregated number of dropped or discarded tx packets by RLC */
sm_rb->txpdu_dd_bytes = rb_rlc.txpdu_dd_bytes; /* aggregated amount of bytes dropped or discarded tx packets by RLC */
sm_rb->txpdu_retx_pkts = rb_rlc.txpdu_retx_pkts; /* aggregated number of tx pdus/pkts to be re-transmitted (only applicable to RLC AM) */
sm_rb->txpdu_retx_bytes = rb_rlc.txpdu_retx_bytes; /* aggregated amount of bytes to be re-transmitted (only applicable to RLC AM) */
sm_rb->txpdu_segmented = rb_rlc.txpdu_segmented; /* aggregated number of segmentations */
sm_rb->txpdu_status_pkts = rb_rlc.txpdu_status_pkts; /* aggregated number of tx status pdus/pkts (only applicable to RLC AM) */
sm_rb->txpdu_status_bytes = rb_rlc.txpdu_status_bytes; /* aggregated amount of tx status bytes (only applicable to RLC AM) */
sm_rb->txbuf_occ_bytes = rb_rlc.txbuf_occ_bytes; /* (IMPLEMENTED) transmitting bytes currently in buffer */
sm_rb->txbuf_occ_pkts = rb_rlc.txbuf_occ_pkts; /* current tx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */
/* RX */
sm_rb->rxpdu_pkts = rb_rlc.rxpdu_pkts; /* aggregated number of received RLC PDUs */
sm_rb->rxpdu_bytes = rb_rlc.rxpdu_bytes; /* amount of bytes received by the RLC */
sm_rb->rxpdu_dup_pkts = rb_rlc.rxpdu_dup_pkts; /* aggregated number of duplicate packets */
sm_rb->rxpdu_dup_bytes = rb_rlc.rxpdu_dup_bytes; /* aggregated amount of duplicated bytes */
sm_rb->rxpdu_dd_pkts = rb_rlc.rxpdu_dd_pkts; /* aggregated number of rx packets dropped or discarded by RLC */
sm_rb->rxpdu_dd_bytes = rb_rlc.rxpdu_dd_bytes; /* aggregated amount of rx bytes dropped or discarded by RLC */
sm_rb->rxpdu_ow_pkts = rb_rlc.rxpdu_ow_pkts; /* aggregated number of out of window received RLC pdu */
sm_rb->rxpdu_ow_bytes = rb_rlc.rxpdu_ow_bytes; /* aggregated number of out of window bytes received RLC pdu */
sm_rb->rxpdu_status_pkts = rb_rlc.rxpdu_status_pkts; /* aggregated number of rx status pdus/pkts (only applicable to RLC AM) */
sm_rb->rxpdu_status_bytes = rb_rlc.rxpdu_status_bytes; /* aggregated amount of rx status bytes (only applicable to RLC AM) */
sm_rb->rxbuf_occ_bytes = rb_rlc.rxbuf_occ_bytes; /* (IMPLEMENTED) received bytes currently in buffer */
sm_rb->rxbuf_occ_pkts = rb_rlc.rxbuf_occ_pkts; /* current rx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */
/* TX */
sm_rb->txsdu_pkts = rb_rlc.txsdu_pkts; /* number of SDUs delivered */
sm_rb->txsdu_bytes = rb_rlc.txsdu_bytes; /* (UPDATED) number of SDUs bytes successfully transmitted so far (counter) */
sm_rb->txsdu_avg_time_to_tx = rb_rlc.txsdu_avg_time_to_tx; /* (100ms-windowed) per-packet sojourn (SDU to PDU) in microseconds */
sm_rb->txsdu_wt_us = rb_rlc.txsdu_wt_us; /* HOL delay of the current radio bearer */
/* RX */
sm_rb->rxsdu_pkts = rb_rlc.rxsdu_pkts; /* number of SDUs received */
sm_rb->rxsdu_bytes = rb_rlc.rxsdu_bytes; /* (UPDATED) number of SDUs bytes arrived so far (counter) */
sm_rb->rxsdu_dd_pkts = rb_rlc.rxsdu_dd_pkts; /* number of dropped or discarded SDUs */
sm_rb->rxsdu_dd_bytes = rb_rlc.rxsdu_dd_bytes; /* number of bytes of SDUs dropped or discarded */
sm_rb->mode = rb_rlc.mode; /* 0: RLC AM, 1: RLC UM, 2: RLC TM */
sm_rb->rnti = rnti;
sm_rb->rbid = rb_id;
LOG_D(RLC, "[E2-AGENT] SDU Goodput & HOL-waittime/200ms-sojourn: %lu/%lu (bytes) & %u/%f (microsecs);\n\
Current Buffer: received %u, transmitting %u (bytes).\n",
sm_rb->txsdu_bytes, sm_rb->rxsdu_bytes, sm_rb->txsdu_wt_us, sm_rb->txsdu_avg_time_to_tx,
sm_rb->rxbuf_occ_bytes, sm_rb->txbuf_occ_bytes);
++i;
}
}
}
void read_rlc_setup_sm(void* data)
{
assert(data != NULL);
// assert(data->type == RLC_AGENT_IF_E2_SETUP_ANS_V0 );
assert(0 !=0 && "Not supported");
}
sm_ag_if_ans_t write_ctrl_rlc_sm(void const* data)
{
(void)data;
assert(0!=0 && "Not supported");
}

View File

@@ -0,0 +1,21 @@
#ifndef NR_RAN_FUNC_SM_RLC_READ_WRITE_AGENT_H
#define NR_RAN_FUNC_SM_RLC_READ_WRITE_AGENT_H
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
#include "common/ran_context.h"
#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"
uint32_t num_act_rb(NR_UEs_t* const UE_info);
void active_avg_to_tx(NR_UEs_t* const UE_info);
void read_rlc_sm(void*);
void read_rlc_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_rlc_sm(void const* data);
#endif

View File

@@ -0,0 +1,47 @@
#include "ran_func_slice.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_slice.h"
#include <assert.h>
#include <stdio.h>
void read_slice_sm(void* data)
{
assert(data != NULL);
// assert(data->type == SLICE_STATS_V0);
slice_ind_data_t* slice = (slice_ind_data_t*)data;
fill_slice_ind_data(slice);
}
void read_slice_setup_sm(void* data)
{
assert(data != NULL);
// assert(data->type == SLICE_AGENT_IF_E2_SETUP_ANS_V0 );
assert(0 !=0 && "Not supported");
}
sm_ag_if_ans_t write_ctrl_slice_sm(void const* data)
{
assert(data != NULL);
// assert(data->type == SLICE_CTRL_REQ_V0);
slice_ctrl_req_data_t const* slice_req_ctrl = (slice_ctrl_req_data_t const* )data; // &data->slice_req_ctrl;
slice_ctrl_msg_t const* msg = &slice_req_ctrl->msg;
if(msg->type == SLICE_CTRL_SM_V0_ADD){
printf("[E2 Agent]: SLICE CONTROL ADD rx\n");
} else if (msg->type == SLICE_CTRL_SM_V0_DEL){
printf("[E2 Agent]: SLICE CONTROL DEL rx\n");
} else if (msg->type == SLICE_CTRL_SM_V0_UE_SLICE_ASSOC){
printf("[E2 Agent]: SLICE CONTROL ASSOC rx\n");
} else {
assert(0!=0 && "Unknown msg_type!");
}
sm_ag_if_ans_t ans = {.type = CTRL_OUTCOME_SM_AG_IF_ANS_V0};
ans.ctrl_out.type = SLICE_AGENT_IF_CTRL_ANS_V0;
return ans;
}

View File

@@ -0,0 +1,13 @@
#ifndef NR_RAN_FUNC_SM_SLICE_READ_WRITE_AGENT_H
#define NR_RAN_FUNC_SM_SLICE_READ_WRITE_AGENT_H
#include "E2AP/flexric/src/agent/e2_agent_api.h"
void read_slice_sm(void*);
void read_slice_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_slice_sm(void const* data);
#endif

View File

@@ -0,0 +1,39 @@
#include "ran_func_tc.h"
#include "E2AP/flexric/test/rnd/fill_rnd_data_tc.h"
#include <assert.h>
void read_tc_sm(void* data)
{
assert(data != NULL);
//assert(data->type == TC_STATS_V0);
tc_ind_data_t* tc = (tc_ind_data_t*)data;
fill_tc_ind_data(tc);
}
void read_tc_setup_sm(void* data)
{
assert(data != NULL);
// assert(data->type == TC_AGENT_IF_E2_SETUP_ANS_V0 );
assert(0 !=0 && "Not supported");
}
sm_ag_if_ans_t write_ctrl_tc_sm(void const* data)
{
assert(data != NULL);
// assert(data->type == TC_CTRL_REQ_V0 );
tc_ctrl_req_data_t const* ctrl = (tc_ctrl_req_data_t const*)data;
tc_ctrl_msg_e const t = ctrl->msg.type;
assert(t == TC_CTRL_SM_V0_CLS || t == TC_CTRL_SM_V0_PLC
|| t == TC_CTRL_SM_V0_QUEUE || t ==TC_CTRL_SM_V0_SCH
|| t == TC_CTRL_SM_V0_SHP || t == TC_CTRL_SM_V0_PCR);
sm_ag_if_ans_t ans = {.type = CTRL_OUTCOME_SM_AG_IF_ANS_V0};
ans.ctrl_out.type = TC_AGENT_IF_CTRL_ANS_V0;
return ans;
}

View File

@@ -0,0 +1,13 @@
#ifndef NR_RAN_FUNC_SM_TC_READ_WRITE_AGENT_H
#define NR_RAN_FUNC_SM_TC_READ_WRITE_AGENT_H
#include "E2AP/flexric/src/agent/e2_agent_api.h"
void read_tc_sm(void*);
void read_tc_setup_sm(void* data);
sm_ag_if_ans_t write_ctrl_tc_sm(void const* data);
#endif

View File

@@ -0,0 +1,3 @@
RAN Functions as defined by O-RAN

View File

@@ -0,0 +1,382 @@
#include "ran_func_kpm.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_kpm.h"
#include "openair2/E2AP/flexric/src/util/time_now_us.h"
#include "common/ran_context.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
#include "E2AP/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_rlc.h"
#include <assert.h>
#include <stdio.h>
static
const int mod_id = 0;
static
gnb_e2sm_t fill_gnb_data(uint16_t rnti)
{
gnb_e2sm_t gnb = {0};
// 6.2.3.16
// Mandatory
// AMF UE NGAP ID
// fill with openair3/NGAP/ngap_gNB_ue_context.h:61
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[mod_id], rnti);
gnb.amf_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id;
// Mandatory
//GUAMI 6.2.3.17
gnb.guami.plmn_id = (e2sm_plmn_t) {
.mcc = ue_context_p->ue_context.ue_guami.mcc,
.mnc = ue_context_p->ue_context.ue_guami.mnc,
.mnc_digit_len = ue_context_p->ue_context.ue_guami.mnc_len
};
gnb.guami.amf_region_id = ue_context_p->ue_context.ue_guami.amf_region_id;
gnb.guami.amf_set_id = ue_context_p->ue_context.ue_guami.amf_set_id;
gnb.guami.amf_ptr = ue_context_p->ue_context.ue_guami.amf_pointer;
return gnb;
}
static
gnb_e2sm_t fill_rnd_gnb_data(void)
{
gnb_e2sm_t gnb = {0};
gnb.amf_ue_ngap_id = (rand() % 2^40) + 0;
gnb.guami.plmn_id = (e2sm_plmn_t) {.mcc = 505, .mnc = 1, .mnc_digit_len = 2};
gnb.guami.amf_region_id = (rand() % 2^8) + 0;
gnb.guami.amf_set_id = (rand() % 2^10) + 0;
gnb.guami.amf_ptr = (rand() % 2^6) + 0;
return gnb;
}
static
ue_id_e2sm_t fill_ue_id_data(uint16_t rnti)
{
ue_id_e2sm_t ue_id_data = {0};
ue_id_data.type = GNB_UE_ID_E2SM;
ue_id_data.gnb = fill_gnb_data(rnti);
return ue_id_data;
}
static
ue_id_e2sm_t fill_rnd_ue_id_data()
{
ue_id_e2sm_t ue_id_data = {0};
ue_id_data.type = GNB_UE_ID_E2SM;
ue_id_data.gnb = fill_rnd_gnb_data();
return ue_id_data;
}
void copy_ba_to_str(const uint8_t* buffer, size_t length, char* str) {
memcpy(str, buffer, length);
str[length] = '\0';
}
double dl_thr_st_val[MAX_MOBILES_PER_GNB] = {0};
double dl_thr_avg_val[MAX_MOBILES_PER_GNB] = {0};
int dl_thr_count[MAX_MOBILES_PER_GNB] = {0};
void cal_dl_thr_bps(uint64_t const dl_total_bytes, uint32_t const gran_period_ms, size_t const ue_idx) {
size_t count_max = 1000/gran_period_ms;
// DL
if (dl_thr_count[ue_idx] == 0)
dl_thr_st_val[ue_idx] = dl_total_bytes;
dl_thr_count[ue_idx] += 1;
if (dl_thr_count[ue_idx] == count_max) {
dl_thr_avg_val[ue_idx] = (dl_total_bytes - dl_thr_st_val[ue_idx])*8;
dl_thr_count[ue_idx] = 0;
}
}
double ul_thr_st_val[MAX_MOBILES_PER_GNB] = {0};
double ul_thr_avg_val[MAX_MOBILES_PER_GNB] = {0};
int ul_thr_count[MAX_MOBILES_PER_GNB] = {0};
void cal_ul_thr_bps(uint64_t const ul_total_bytes, uint32_t const gran_period_ms, size_t const ue_idx) {
size_t count_max = 1000/gran_period_ms;
// UL
if (ul_thr_count[ue_idx] == 0)
ul_thr_st_val[ue_idx] = ul_total_bytes;
ul_thr_avg_val[ue_idx] += 1;
if (ul_thr_count[ue_idx] == count_max) {
ul_thr_avg_val[ue_idx] = (ul_total_bytes - ul_thr_st_val[ue_idx])*8;
ul_thr_count[ue_idx] = 0;
}
}
static
kpm_ind_msg_format_1_t fill_kpm_ind_msg_frm_1(NR_UE_info_t* const UE, size_t const ue_idx, kpm_act_def_format_1_t const act_def_fr1)
{
kpm_ind_msg_format_1_t msg_frm_1 = {0};
// Measurement Data
NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info;
uint32_t num_drbs = num_act_rb(UE_info);
msg_frm_1.meas_data_lst_len = num_drbs; // (rand() % 65535) + 1;
msg_frm_1.meas_data_lst = calloc(msg_frm_1.meas_data_lst_len, sizeof(*msg_frm_1.meas_data_lst));
assert(msg_frm_1.meas_data_lst != NULL && "Memory exhausted" );
size_t const rec_data_len = act_def_fr1.meas_info_lst_len; // Recoding Data Length
size_t meas_data_idx = 0;
for (int rb_id = 1; rb_id < 6; ++rb_id) {
nr_rlc_statistics_t rb_rlc = {0};
const int srb_flag = 0;
const bool rc = nr_rlc_get_statistics(UE->rnti, srb_flag, rb_id, &rb_rlc);
if(!rc) continue;
// Measurement Record
meas_data_lst_t* meas_data = &msg_frm_1.meas_data_lst[meas_data_idx];
meas_data->meas_record_len = rec_data_len;
meas_data->meas_record_lst = calloc(meas_data->meas_record_len, sizeof(meas_record_lst_t));
assert(meas_data->meas_record_lst != NULL && "Memory exhausted");
for (size_t j = 0; j < meas_data->meas_record_len; j++) {
meas_record_lst_t* meas_record = &meas_data->meas_record_lst[j];
meas_type_t meas_info_type = act_def_fr1.meas_info_lst[j].meas_type;
if (meas_info_type.type == NAME_MEAS_TYPE) {
// Get Meas Info Name from Action Definition
size_t length = meas_info_type.name.len;
char meas_info_name_str[length + 1];
copy_ba_to_str(meas_info_type.name.buf, length, meas_info_name_str);
// Get value based on Meas Info Name
if (strcmp(meas_info_name_str, "DRB.IPThpDl.QCI") == 0 ? true : false) {
meas_record->value = REAL_MEAS_VALUE;
cal_dl_thr_bps(UE->mac_stats.dl.total_bytes, act_def_fr1.gran_period_ms, ue_idx);
meas_record->real_val = dl_thr_avg_val[ue_idx];
} else if (strcmp(meas_info_name_str, "DRB.IPThpUl.QCI") == 0 ? true : false) {
meas_record->value = REAL_MEAS_VALUE;
cal_ul_thr_bps(UE->mac_stats.ul.total_bytes, act_def_fr1.gran_period_ms, ue_idx);
meas_record->real_val = ul_thr_avg_val[ue_idx];
} else if (strcmp(meas_info_name_str, "DRB.RlcSduDelayDl") == 0 ? true : false) {
meas_record->value = REAL_MEAS_VALUE;
active_avg_to_tx(UE_info);
meas_record->real_val = rb_rlc.txsdu_avg_time_to_tx;
} else {
printf("not implement value for measurement name %s\n", meas_info_name_str);
meas_record->value = REAL_MEAS_VALUE;
meas_record->real_val = 1234;
}
} else {
printf("not implement value for measurement type %d\n", meas_info_type.type);
meas_record->value = REAL_MEAS_VALUE;
meas_record->real_val = 1234;
}
}
meas_data_idx++;
}
// Measurement Information - OPTIONAL
msg_frm_1.meas_info_lst_len = rec_data_len;
msg_frm_1.meas_info_lst = calloc(msg_frm_1.meas_info_lst_len, sizeof(meas_info_format_1_lst_t));
assert(msg_frm_1.meas_info_lst != NULL && "Memory exhausted" );
// Get measInfo from action definition
for (size_t i = 0; i < msg_frm_1.meas_info_lst_len; i++) {
// Measurement Type
msg_frm_1.meas_info_lst[i].meas_type.type = act_def_fr1.meas_info_lst[i].meas_type.type;
// Measurement Name
if (act_def_fr1.meas_info_lst[i].meas_type.type == NAME_MEAS_TYPE) {
msg_frm_1.meas_info_lst[i].meas_type.name.buf = calloc(act_def_fr1.meas_info_lst[i].meas_type.name.len, sizeof(uint8_t));
memcpy(msg_frm_1.meas_info_lst[i].meas_type.name.buf, act_def_fr1.meas_info_lst[i].meas_type.name.buf, act_def_fr1.meas_info_lst[i].meas_type.name.len);
msg_frm_1.meas_info_lst[i].meas_type.name.len = act_def_fr1.meas_info_lst[i].meas_type.name.len;
} else {
msg_frm_1.meas_info_lst[i].meas_type.id = act_def_fr1.meas_info_lst[i].meas_type.id;
}
// Label Information
msg_frm_1.meas_info_lst[i].label_info_lst_len = 1;
msg_frm_1.meas_info_lst[i].label_info_lst = calloc(msg_frm_1.meas_info_lst[i].label_info_lst_len, sizeof(label_info_lst_t));
assert(msg_frm_1.meas_info_lst[i].label_info_lst != NULL && "Memory exhausted" );
for (size_t j = 0; j < msg_frm_1.meas_info_lst[i].label_info_lst_len; j++) {
msg_frm_1.meas_info_lst[i].label_info_lst[j].noLabel = malloc(sizeof(enum_value_e));
*msg_frm_1.meas_info_lst[i].label_info_lst[j].noLabel = TRUE_ENUM_VALUE;
}
}
return msg_frm_1;
}
static kpm_ind_msg_format_1_t fill_rnd_kpm_ind_msg_frm_1(void)
{
kpm_ind_msg_format_1_t msg_frm_1 = {0};
// Measurement Data
msg_frm_1.meas_data_lst_len = 1; // (rand() % 65535) + 1;
msg_frm_1.meas_data_lst = calloc(msg_frm_1.meas_data_lst_len, sizeof(*msg_frm_1.meas_data_lst));
assert(msg_frm_1.meas_data_lst != NULL && "Memory exhausted" );
for (size_t i = 0; i < msg_frm_1.meas_data_lst_len; i++)
{
// Incomplete Flag
msg_frm_1.meas_data_lst[i].incomplete_flag = calloc(1, sizeof(enum_value_e));
assert(msg_frm_1.meas_data_lst[i].incomplete_flag != NULL && "Memory exhausted");
*msg_frm_1.meas_data_lst[i].incomplete_flag = TRUE_ENUM_VALUE;
// Measurement Record
msg_frm_1.meas_data_lst[i].meas_record_len = 1;
msg_frm_1.meas_data_lst[i].meas_record_lst = calloc(msg_frm_1.meas_data_lst[i].meas_record_len, sizeof(meas_record_lst_t));
assert(msg_frm_1.meas_data_lst[i].meas_record_lst != NULL && "Memory exhausted" );
for (size_t j = 0; j < msg_frm_1.meas_data_lst[i].meas_record_len; j++)
{
msg_frm_1.meas_data_lst[i].meas_record_lst[j].value = REAL_MEAS_VALUE;
msg_frm_1.meas_data_lst[i].meas_record_lst[j].real_val = time_now_us();
}
}
// Measurement Information - OPTIONAL
msg_frm_1.meas_info_lst_len = 1;
msg_frm_1.meas_info_lst = calloc(msg_frm_1.meas_info_lst_len, sizeof(meas_info_format_1_lst_t));
assert(msg_frm_1.meas_info_lst != NULL && "Memory exhausted" );
for (size_t i = 0; i < msg_frm_1.meas_info_lst_len; i++)
{
// Measurement Type
char* s = "timestamp";
msg_frm_1.meas_info_lst[i].meas_type.name.len = strlen(s) + 1;
msg_frm_1.meas_info_lst[i].meas_type.name.buf = malloc(strlen(s) + 1);
assert(msg_frm_1.meas_info_lst[i].meas_type.name.buf != NULL && "memory exhausted");
memcpy(msg_frm_1.meas_info_lst[i].meas_type.name.buf, s, strlen(s));
msg_frm_1.meas_info_lst[i].meas_type.name.buf[strlen(s)] = '\0';
// Label Information
msg_frm_1.meas_info_lst[i].label_info_lst_len = 1;
msg_frm_1.meas_info_lst[i].label_info_lst = calloc(msg_frm_1.meas_info_lst[i].label_info_lst_len, sizeof(label_info_lst_t));
assert(msg_frm_1.meas_info_lst[i].label_info_lst != NULL && "Memory exhausted" );
for (size_t j = 0; j < msg_frm_1.meas_info_lst[i].label_info_lst_len; j++)
{
msg_frm_1.meas_info_lst[i].label_info_lst[j].noLabel = malloc(sizeof(enum_value_e));
*msg_frm_1.meas_info_lst[i].label_info_lst[j].noLabel = TRUE_ENUM_VALUE;
}
}
return msg_frm_1;
}
static
kpm_ind_msg_format_3_t fill_kpm_ind_msg_frm_3_sta(kpm_act_def_format_1_t const act_def_fr1)
{
kpm_ind_msg_format_3_t msg_frm_3 = {0};
// get the number of connected UEs
NR_UEs_t *UE_info = &RC.nrmac[mod_id]->UE_info;
uint32_t num_ues = 0;
UE_iterator(UE_info->list, ue) {
if (ue)
num_ues += 1;
}
msg_frm_3.ue_meas_report_lst_len = num_ues == 0 ? 1: num_ues; // (rand() % 65535) + 1;
msg_frm_3.meas_report_per_ue = calloc(msg_frm_3.ue_meas_report_lst_len, sizeof(meas_report_per_ue_t));
assert(msg_frm_3.meas_report_per_ue != NULL && "Memory exhausted");
// TODO: handle the case when the number of UE is 0, if (msg_frm_3.ue_meas_report_lst_len > 0)
if (num_ues > 0) {
size_t ue_idx = 0;
UE_iterator(UE_info->list, UE)
{
uint16_t const rnti = UE->rnti;
msg_frm_3.meas_report_per_ue[ue_idx].ue_meas_report_lst = fill_ue_id_data(rnti);
msg_frm_3.meas_report_per_ue[ue_idx].ind_msg_format_1 = fill_kpm_ind_msg_frm_1(UE, ue_idx, act_def_fr1);
ue_idx+=1;
}
} else {
msg_frm_3.meas_report_per_ue[0].ue_meas_report_lst = fill_rnd_ue_id_data();
msg_frm_3.meas_report_per_ue[0].ind_msg_format_1 = fill_rnd_kpm_ind_msg_frm_1();
}
return msg_frm_3;
}
static
kpm_ric_ind_hdr_format_1_t fill_kpm_ind_hdr_frm_1(void)
{
kpm_ric_ind_hdr_format_1_t hdr_frm_1 = {0};
hdr_frm_1.collectStartTime = time_now_us();
hdr_frm_1.fileformat_version = NULL;
hdr_frm_1.sender_name = calloc(1, sizeof(byte_array_t));
hdr_frm_1.sender_name->buf = calloc(strlen("My OAI-MONO") + 1, sizeof(char));
memcpy(hdr_frm_1.sender_name->buf, "My OAI-MONO", strlen("My OAI-MONO"));
hdr_frm_1.sender_name->len = strlen("My OAI-MONO");
hdr_frm_1.sender_type = calloc(1, sizeof(byte_array_t));
hdr_frm_1.sender_type->buf = calloc(strlen("MONO") + 1, sizeof(char));
memcpy(hdr_frm_1.sender_type->buf, "MONO", strlen("MONO"));
hdr_frm_1.sender_type->len = strlen("MONO");
hdr_frm_1.vendor_name = calloc(1, sizeof(byte_array_t));
hdr_frm_1.vendor_name->buf = calloc(strlen("OAI") + 1, sizeof(char));
memcpy(hdr_frm_1.vendor_name->buf, "OAI", strlen("OAI"));
hdr_frm_1.vendor_name->len = strlen("OAI");
return hdr_frm_1;
}
static
kpm_ind_hdr_t fill_kpm_ind_hdr_sta(void)
{
kpm_ind_hdr_t hdr = {0};
hdr.type = FORMAT_1_INDICATION_HEADER;
hdr.kpm_ric_ind_hdr_format_1 = fill_kpm_ind_hdr_frm_1();
return hdr;
}
void read_kpm_sm(void* data)
{
assert(data != NULL);
//assert(data->type == KPM_STATS_V3_0);
kpm_rd_ind_data_t* const kpm = (kpm_rd_ind_data_t*)data;
assert(kpm->act_def!= NULL && "Cannot be NULL");
if(kpm->act_def->type == FORMAT_4_ACTION_DEFINITION){
if(kpm->act_def->frm_4.matching_cond_lst[0].test_info_lst.test_cond_type == CQI_TEST_COND_TYPE
&& *kpm->act_def->frm_4.matching_cond_lst[0].test_info_lst.test_cond == GREATERTHAN_TEST_COND){
printf("Matching condition: UEs with CQI greater than %ld \n", *kpm->act_def->frm_4.matching_cond_lst[0].test_info_lst.int_value );
}
for (size_t i = 0; i < kpm->act_def->frm_4.action_def_format_1.meas_info_lst_len; i++)
printf("Parameter to report: %s \n", kpm->act_def->frm_4.action_def_format_1.meas_info_lst[i].meas_type.name.buf);
kpm->ind.hdr = fill_kpm_ind_hdr_sta();
// 7.8 Supported RIC Styles and E2SM IE Formats
// Format 4 corresponds to indication message 3
kpm->ind.msg.type = FORMAT_3_INDICATION_MESSAGE;
kpm->ind.msg.frm_3 = fill_kpm_ind_msg_frm_3_sta(kpm->act_def->frm_4.action_def_format_1);
} else {
kpm->ind.hdr = fill_kpm_ind_hdr();
kpm->ind.msg = fill_kpm_ind_msg();
}
}
void read_kpm_setup_sm(void* e2ap)
{
assert(e2ap != NULL);
// assert(e2ap->type == KPM_V3_0_AGENT_IF_E2_SETUP_ANS_V0);
kpm_e2_setup_t* kpm = (kpm_e2_setup_t*)(e2ap);
kpm->ran_func_def = fill_kpm_ran_func_def();
}
sm_ag_if_ans_t write_ctrl_kpm_sm(void const* src)
{
assert(0 !=0 && "Not supported");
(void)src;
sm_ag_if_ans_t ans = {0};
return ans;
}

View File

@@ -0,0 +1,13 @@
#ifndef NR_RAN_FUNC_SM_KPM_READ_WRITE_AGENT_H
#define NR_RAN_FUNC_SM_KPM_READ_WRITE_AGENT_H
#include "E2AP/flexric/src/agent/e2_agent_api.h"
void read_kpm_sm(void*);
void read_kpm_setup_sm(void*);
sm_ag_if_ans_t write_ctrl_kpm_sm(void const* src);
#endif

View File

@@ -0,0 +1,108 @@
#include "ran_func_rc.h"
#include "openair2/E2AP/flexric/test/rnd/fill_rnd_data_rc.h"
#include "openair2/E2AP/flexric/src/sm/rc_sm/ie/ir/lst_ran_param.h"
#include "openair2/E2AP/flexric/src/sm/rc_sm/ie/ir/ran_param_list.h"
#include <assert.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void read_rc_sm(void* data)
{
assert(data != NULL);
// assert(data->type == RAN_CTRL_STATS_V1_03);
assert(0!=0 && "Not implemented");
}
void read_rc_setup_sm(void* data)
{
assert(data != NULL);
// assert(data->type == RAN_CTRL_V1_3_AGENT_IF_E2_SETUP_ANS_V0);
rc_e2_setup_t* rc = (rc_e2_setup_t*)data;
rc->ran_func_def = fill_rc_ran_func_def();
}
sm_ag_if_ans_t write_ctrl_rc_sm(void const* data)
{
assert(data != NULL);
// assert(data->type == RAN_CONTROL_CTRL_V1_03 );
rc_ctrl_req_data_t const* ctrl = (rc_ctrl_req_data_t const*)data;
if(ctrl->hdr.format == FORMAT_1_E2SM_RC_CTRL_HDR){
if(ctrl->hdr.frmt_1.ric_style_type == 1 && ctrl->hdr.frmt_1.ctrl_act_id == 2){
printf("QoS flow mapping configuration \n");
e2sm_rc_ctrl_msg_frmt_1_t const* frmt_1 = &ctrl->msg.frmt_1;
for(size_t i = 0; i < frmt_1->sz_ran_param; ++i){
seq_ran_param_t const* rp = frmt_1->ran_param;
if(rp[i].ran_param_id == 1){
assert(rp[i].ran_param_val.type == ELEMENT_KEY_FLAG_TRUE_RAN_PARAMETER_VAL_TYPE );
printf("DRB ID %ld \n", rp[i].ran_param_val.flag_true->int_ran);
} else if(rp[i].ran_param_id == 2){
assert(rp[i].ran_param_val.type == LIST_RAN_PARAMETER_VAL_TYPE);
printf("List of QoS Flows to be modified \n");
for(size_t j = 0; j < ctrl->msg.frmt_1.ran_param[i].ran_param_val.lst->sz_lst_ran_param; ++j){
lst_ran_param_t const* lrp = rp[i].ran_param_val.lst->lst_ran_param;
// The following assertion should be true, but there is a bug in the std
// check src/sm/rc_sm/enc/rc_enc_asn.c:1085 and src/sm/rc_sm/enc/rc_enc_asn.c:984
// assert(lrp[j].ran_param_id == 3);
assert(lrp[j].ran_param_struct.ran_param_struct[0].ran_param_id == 4) ;
assert(lrp[j].ran_param_struct.ran_param_struct[0].ran_param_val.type == ELEMENT_KEY_FLAG_TRUE_RAN_PARAMETER_VAL_TYPE);
int64_t qfi = lrp[j].ran_param_struct.ran_param_struct[0].ran_param_val.flag_true->int_ran;
assert(qfi > -1 && qfi < 65);
assert(lrp[j].ran_param_struct.ran_param_struct[1].ran_param_id == 5);
assert(lrp[j].ran_param_struct.ran_param_struct[1].ran_param_val.type == ELEMENT_KEY_FLAG_FALSE_RAN_PARAMETER_VAL_TYPE);
int64_t dir = lrp[j].ran_param_struct.ran_param_struct[1].ran_param_val.flag_false->int_ran;
assert(dir == 0 || dir == 1);
printf("qfi = %ld dir %ld \n", qfi, dir);
}
}
}
}
}
sm_ag_if_ans_t ans = {.type = CTRL_OUTCOME_SM_AG_IF_ANS_V0};
ans.ctrl_out.type = RAN_CTRL_V1_3_AGENT_IF_CTRL_ANS_V0;
return ans;
}
static
void* emulate_rrc_msg(void* ptr)
{
uint32_t* ric_id = (uint32_t*)ptr;
for(size_t i = 0; i < 5; ++i){
usleep(rand()%4000);
rc_ind_data_t* d = calloc(1, sizeof(rc_ind_data_t));
assert(d != NULL && "Memory exhausted");
*d = fill_rnd_rc_ind_data();
async_event_agent_api(*ric_id, d);
printf("Event for RIC Req ID %u generated\n", *ric_id);
}
free(ptr);
return NULL;
}
static
pthread_t t_ran_ctrl;
sm_ag_if_ans_t write_subs_rc_sm(void const* src)
{
assert(src != NULL); // && src->type == RAN_CTRL_SUBS_V1_03);
wr_rc_sub_data_t* wr_rc = (wr_rc_sub_data_t*)src;
printf("ric req id %d \n", wr_rc->ric_req_id);
uint32_t* ptr = malloc(sizeof(uint32_t));
assert(ptr != NULL);
*ptr = wr_rc->ric_req_id;
int rc = pthread_create(&t_ran_ctrl, NULL, emulate_rrc_msg, ptr);
assert(rc == 0);
sm_ag_if_ans_t ans = {0};
return ans;
}

View File

@@ -1,7 +1,7 @@
#ifndef RAN_FUNC_SM_RAN_CTRL_READ_WRITE_AGENT_H
#define RAN_FUNC_SM_RAN_CTRL_READ_WRITE_AGENT_H
#ifndef NR_RAN_FUNC_SM_RAN_CTRL_READ_WRITE_AGENT_H
#define NR_RAN_FUNC_SM_RAN_CTRL_READ_WRITE_AGENT_H
#include "../../flexric/src/agent/e2_agent_api.h"
#include "E2AP/flexric/src/agent/e2_agent_api.h"
void read_rc_sm(void *);

View File

@@ -1,13 +1,13 @@
#include "init_ran_func.h"
#include "../flexric/src/agent/e2_agent_api.h"
#include "CUSTOMIZED/ran_func_mac.h"
#include "CUSTOMIZED/ran_func_rlc.h"
#include "CUSTOMIZED/ran_func_pdcp.h"
#include "CUSTOMIZED/ran_func_slice.h"
#include "CUSTOMIZED/ran_func_tc.h"
#include "CUSTOMIZED/ran_func_gtp.h"
#include "O-RAN/ran_func_kpm.h"
#include "O-RAN/ran_func_rc.h"
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
#include "E2AP/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_mac.h"
#include "E2AP/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_rlc.h"
#include "E2AP/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_pdcp.h"
#include "E2AP/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_slice.h"
#include "E2AP/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_tc.h"
#include "E2AP/RAN_FUNCTION/NR/CUSTOMIZED/ran_func_gtp.h"
#include "E2AP/RAN_FUNCTION/NR/O-RAN/ran_func_kpm.h"
#include "E2AP/RAN_FUNCTION/NR/O-RAN/ran_func_rc.h"
static
void init_read_ind_tbl(read_ind_fp (*read_ind_tbl)[SM_AGENT_IF_READ_V0_END])

View File

@@ -21,10 +21,10 @@
#ifndef RAN_FUNC_INIT_E2_H
#define RAN_FUNC_INIT_E2_H
#ifndef NR_RAN_FUNC_INIT_E2_H
#define NR_RAN_FUNC_INIT_E2_H
#include "../flexric/src/sm/sm_io.h"
#include "E2AP/flexric/src/sm/sm_io.h"
sm_io_ag_ran_t init_ran_func_ag(void);

View File

@@ -1,7 +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
)

View File

@@ -1,13 +0,0 @@
#ifndef RAN_FUNC_SM_KPM_READ_WRITE_AGENT_H
#define RAN_FUNC_SM_KPM_READ_WRITE_AGENT_H
#include "../../flexric/src/agent/e2_agent_api.h"
void read_kpm_sm(void*);
void read_kpm_setup_sm(void*);
sm_ag_if_ans_t write_ctrl_kpm_sm(void const* src);
#endif

View File

@@ -2935,14 +2935,18 @@ e2_agent_args_t RCconfig_E2agent(void)
paramdef_t e2agent_params[] = E2AGENT_PARAMS_DESC;
int ret = config_get(e2agent_params, sizeof(e2agent_params) / sizeof(paramdef_t), CONFIG_STRING_E2AGENT);
if (ret < 0) {
LOG_W(GNB_APP, "configuration file does not contain a \"%s\" section, applying default parameters\n", CONFIG_STRING_E2AGENT);
LOG_W(ENB_APP, "configuration file does not contain a \"%s\" section, applying default parameters\n", CONFIG_STRING_E2AGENT);
return (e2_agent_args_t) {0};
}
return (e2_agent_args_t) {
.ip = *e2agent_params[E2AGENT_CONFIG_IP_IDX].strptr,
.port = *e2agent_params[E2AGENT_CONFIG_PORT_IDX].u16ptr,
.sm_dir = *e2agent_params[E2AGENT_CONFIG_SMDIR_IDX].strptr,
};
e2_agent_args_t dst = {0};
if (e2agent_params[E2AGENT_CONFIG_SMDIR_IDX].strptr != NULL)
dst.sm_dir = *e2agent_params[E2AGENT_CONFIG_SMDIR_IDX].strptr;
if (e2agent_params[E2AGENT_CONFIG_IP_IDX].strptr != NULL)
dst.ip = *e2agent_params[E2AGENT_CONFIG_IP_IDX].strptr;
return dst;
}

View File

@@ -36,10 +36,36 @@ static void nr_rlc_entity_get_stats(
nr_rlc_statistics_t *out)
{
// printf("Stats from the RLC entity asked\n");
uint64_t time_now = time_average_now();
*out = entity->stats;
// Get the correct HOL RLC-SDU
nr_rlc_sdu_segment_t* sdu;
if (entity->stats.mode == NR_RLC_AM) {
nr_rlc_entity_am_t* am_entity = (nr_rlc_entity_am_t *) entity;
if (am_entity->retransmit_list != NULL) {
sdu = am_entity->retransmit_list;
} else {
sdu = am_entity->tx_list;
}
} else if (entity->stats.mode == NR_RLC_UM) {
nr_rlc_entity_um_t* um_entity = (nr_rlc_entity_um_t *) entity;
sdu = um_entity->tx_list;
} else {
nr_rlc_entity_tm_t* tm_entity = (nr_rlc_entity_tm_t *) entity;
sdu = tm_entity->tx_list;
}
// Compute HOL waittime, make sure that segmented packets don't have 'zero' time-of-arrival
if (sdu != NULL) {
out->txsdu_wt_us = time_now - sdu->sdu->time_of_arrival;
} else {
// No HOL packets --> wait-time == 0
out->txsdu_wt_us = 0;
}
if (entity->avg_time_is_on)
out->txsdu_avg_time_to_tx = time_average_get_average(entity->txsdu_avg_time_to_tx,
time_average_now());
out->txsdu_avg_time_to_tx = time_average_get_average(entity->txsdu_avg_time_to_tx, time_now);
else
out->txsdu_avg_time_to_tx = 0;
}
@@ -99,7 +125,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_am(
ret->common.set_time = nr_rlc_entity_am_set_time;
ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu;
ret->common.reestablishment = nr_rlc_entity_am_reestablishment;
ret->common.delete = nr_rlc_entity_am_delete;
ret->common.delete_entity = nr_rlc_entity_am_delete;
ret->common.available_tx_space = nr_rlc_entity_am_available_tx_space;
ret->common.get_stats = nr_rlc_entity_get_stats;
@@ -112,8 +138,11 @@ nr_rlc_entity_t *new_nr_rlc_entity_am(
ret->common.stats.mode = NR_RLC_AM;
ret->common.stats.rxsdu_bytes = 0; // init default arrivals (SDU) counter
ret->common.stats.txsdu_bytes = 0; // init default transmits (SDU) counter
/* let's take average over the last 100 milliseconds
* initial_size of 1024 is arbitrary
* initial_size of 1024 (packets) is arbitrary
*/
ret->common.txsdu_avg_time_to_tx = time_average_new(100 * 1000, 1024);
@@ -158,7 +187,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_um(
ret->common.set_time = nr_rlc_entity_um_set_time;
ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu;
ret->common.reestablishment = nr_rlc_entity_um_reestablishment;
ret->common.delete = nr_rlc_entity_um_delete;
ret->common.delete_entity = nr_rlc_entity_um_delete;
ret->common.available_tx_space = nr_rlc_entity_um_available_tx_space;
ret->common.get_stats = nr_rlc_entity_get_stats;
@@ -198,7 +227,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm(
ret->common.set_time = nr_rlc_entity_tm_set_time;
ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu;
ret->common.reestablishment = nr_rlc_entity_tm_reestablishment;
ret->common.delete = nr_rlc_entity_tm_delete;
ret->common.delete_entity = nr_rlc_entity_tm_delete;
ret->common.available_tx_space = nr_rlc_entity_tm_available_tx_space;
ret->common.get_stats = nr_rlc_entity_get_stats;

View File

@@ -42,8 +42,7 @@ typedef struct {
/* TX */
uint32_t txpdu_pkts; /* aggregated number of transmitted RLC PDUs */
uint32_t txpdu_bytes; /* aggregated amount of transmitted bytes in RLC PDUs */
/* TODO? */
uint32_t txpdu_wt_ms; /* aggregated head-of-line tx packet waiting time to be transmitted (i.e. send to the MAC layer) */
uint32_t txpdu_wt_ms; /* TODO: aggregated head-of-line tx packet waiting time to be transmitted (i.e. send to the MAC layer) */
uint32_t txpdu_dd_pkts; /* aggregated number of dropped or discarded tx packets by RLC */
uint32_t txpdu_dd_bytes; /* aggregated amount of bytes dropped or discarded tx packets by RLC */
uint32_t txpdu_retx_pkts; /* aggregated number of tx pdus/pkts to be re-transmitted (only applicable to RLC AM) */
@@ -51,10 +50,8 @@ typedef struct {
uint32_t txpdu_segmented; /* aggregated number of segmentations */
uint32_t txpdu_status_pkts; /* aggregated number of tx status pdus/pkts (only applicable to RLC AM) */
uint32_t txpdu_status_bytes; /* aggregated amount of tx status bytes (only applicable to RLC AM) */
/* TODO? */
uint32_t txbuf_occ_bytes; /* current tx buffer occupancy in terms of amount of bytes (average: NOT IMPLEMENTED) */
/* TODO? */
uint32_t txbuf_occ_pkts; /* current tx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */
uint32_t txbuf_occ_bytes; /* (IMPLEMENTED) transmitting bytes currently in buffer */
uint32_t txbuf_occ_pkts; /* TODO: current tx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */
/* txbuf_wd_ms: the time window for which the txbuf occupancy value is obtained - NOT IMPLEMENTED */
/* RX */
@@ -71,31 +68,28 @@ typedef struct {
/* rxpdu_rotout_ms: flag indicating rx reordering timeout in ms - NOT IMPLEMENTED */
/* rxpdu_potout_ms: flag indicating the poll retransmit time out in ms - NOT IMPLEMENTED */
/* rxpdu_sptout_ms: flag indicating status prohibit timeout in ms - NOT IMPLEMENTED */
/* TODO? */
uint32_t rxbuf_occ_bytes; /* current rx buffer occupancy in terms of amount of bytes (average: NOT IMPLEMENTED) */
/* TODO? */
uint32_t rxbuf_occ_pkts; /* current rx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */
uint32_t rxbuf_occ_bytes; /* (IMPLEMENTED) received bytes currently in buffer */
uint32_t rxbuf_occ_pkts; /* TODO: current rx buffer occupancy in terms of number of packets (average: NOT IMPLEMENTED) */
/* SDU stats */
/* TX */
uint32_t txsdu_pkts; /* number of SDUs delivered */
uint32_t txsdu_bytes; /* number of bytes of SDUs delivered */
uint64_t txsdu_bytes; /* (UPDATED) number of SDUs bytes successfully transmitted so far (counter) */
/* Average time for an SDU to be passed to MAC:
* Actually measures the time it takes for THE FULL SDU to be passed to MAC FOR THE FIRST TIME.
* Since the MAC schedules in advance, it does not measure the time of
* transmission over the air, just the time to reach the MAC layer.
* => to control it, 'txsdu_wt_us' that measures the current HOL-delay is added.
*/
double txsdu_avg_time_to_tx; /* (100ms-windowed) per-packet sojourn (SDU to PDU) in microseconds */
uint32_t txsdu_wt_us; /* HOL delay of the current radio bearer, in microseconds */
/* RX */
uint32_t rxsdu_pkts; /* number of SDUs received */
uint32_t rxsdu_bytes; /* number of bytes of SDUs received */
uint64_t rxsdu_bytes; /* (UPDATED) number of SDUs bytes arrived so far (counter) */
uint32_t rxsdu_dd_pkts; /* number of dropped or discarded SDUs */
uint32_t rxsdu_dd_bytes; /* number of bytes of SDUs dropped or discarded */
/* Average time for an SDU to be passed to MAC.
* Actually measures the time it takes for any part of an SDU to be
* passed to MAC for the first time, that is: the first TX of (part of) the
* SDU.
* Since the MAC schedules in advance, it does not measure the time of
* transmission over the air, just the time to reach the MAC layer.
*/
double txsdu_avg_time_to_tx;
} nr_rlc_statistics_t;
typedef struct {
@@ -120,7 +114,7 @@ typedef struct nr_rlc_entity_t {
void (*reestablishment)(struct nr_rlc_entity_t *entity);
void (*delete)(struct nr_rlc_entity_t *entity);
void (*delete_entity)(struct nr_rlc_entity_t *entity);
int (*available_tx_space)(struct nr_rlc_entity_t *entity);

View File

@@ -224,7 +224,8 @@ static void reassemble_and_deliver(nr_rlc_entity_am_t *entity, int sn)
sdu, so);
entity->common.stats.txsdu_pkts++;
entity->common.stats.txsdu_bytes += so;
/* AM 'txsdu_bytes' now only count successfully transmitted bytes */
// entity->common.stats.txsdu_bytes += so;
}
static void reception_actions(nr_rlc_entity_am_t *entity, nr_rlc_pdu_t *pdu)
@@ -484,6 +485,8 @@ process_wait_list_head:
end_wait_list = prev_wait_list;
if (nr_rlc_free_sdu_segment(cur_wait_list)) {
entity->tx_size -= sdu_size;
// Wait-ACK: count as successfully transmitted bytes
entity->common.stats.txsdu_bytes += sdu_size;
entity->common.sdu_successful_delivery(
entity->common.sdu_successful_delivery_data,
(nr_rlc_entity_t *)entity, upper_layer_id);
@@ -546,6 +549,8 @@ process_retransmit_list_head:
+ cur->size;
if (nr_rlc_free_sdu_segment(cur)) {
entity->tx_size -= sdu_size;
// Retransmit-ACK: count as successfully transmitted bytes
entity->common.stats.txsdu_bytes += sdu_size;
entity->common.sdu_successful_delivery(
entity->common.sdu_successful_delivery_data,
(nr_rlc_entity_t *)entity, upper_layer_id);
@@ -604,6 +609,8 @@ nacks_done:
end_wait_list = prev_wait_list;
if (nr_rlc_free_sdu_segment(cur_wait_list)) {
entity->tx_size -= sdu_size;
// Wait-NACK done: count as successfully transmitted bytes
entity->common.stats.txsdu_bytes += sdu_size;
entity->common.sdu_successful_delivery(
entity->common.sdu_successful_delivery_data,
(nr_rlc_entity_t *)entity, upper_layer_id);
@@ -625,6 +632,8 @@ nacks_done:
+ cur->size;
if (nr_rlc_free_sdu_segment(cur)) {
entity->tx_size -= sdu_size;
// Retransmit-NACK done: count as successfully transmitted bytes
entity->common.stats.txsdu_bytes += sdu_size;
entity->common.sdu_successful_delivery(
entity->common.sdu_successful_delivery_data,
(nr_rlc_entity_t *)entity, upper_layer_id);
@@ -1619,13 +1628,11 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
entity->common.stats.txpdu_pkts++;
entity->common.stats.txpdu_bytes += ret_size;
if (sdu->sdu->time_of_arrival) {
uint64_t time_now = time_average_now();
uint64_t waited_time = time_now - sdu->sdu->time_of_arrival;
/* set time_of_arrival to 0 so as to update stats only once */
sdu->sdu->time_of_arrival = 0;
time_average_add(entity->common.txsdu_avg_time_to_tx, time_now, waited_time);
}
/* No need to 'zero' time-of-arrival;
Segmented packets do need to be duplicated in time-sensitive use cases */
uint64_t time_now = time_average_now();
uint64_t waited_time = time_now - sdu->sdu->time_of_arrival;
time_average_add(entity->common.txsdu_avg_time_to_tx, time_now, waited_time);
return ret_size;
// return serialize_sdu(entity, sdu, buffer, size, p);
@@ -1681,7 +1688,6 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity,
nr_rlc_sdu_segment_t *sdu;
entity->common.stats.rxsdu_pkts++;
entity->common.stats.rxsdu_bytes += size;
if (size > NR_SDU_MAX) {
LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n",
@@ -1705,6 +1711,8 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity,
}
entity->tx_size += size;
// SDU received: Count as arrival bytes
entity->common.stats.rxsdu_bytes += size;
sdu = nr_rlc_new_sdu(buffer, size, sdu_id);
@@ -1893,6 +1901,10 @@ void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id)
+ cur->size;
entity->tx_size -= cur->sdu->size;
/* Uncomment to assert if SDU are ever discarded */
// assert(0 != 0 && "[RLC-TRAP] SDU discard should never be reached!");
nr_rlc_free_sdu_segment(cur);
}

View File

@@ -79,13 +79,11 @@ static int generate_tx_pdu(nr_rlc_entity_tm_t *entity, char *buffer, int size)
entity->common.stats.txpdu_pkts++;
entity->common.stats.txpdu_bytes += size;
if (sdu->sdu->time_of_arrival) {
uint64_t time_now = time_average_now();
uint64_t waited_time = time_now - sdu->sdu->time_of_arrival;
/* set time_of_arrival to 0 so as to update stats only once */
sdu->sdu->time_of_arrival = 0;
time_average_add(entity->common.txsdu_avg_time_to_tx, time_now, waited_time);
}
/* No need to 'zero' time-of-arrival;
Segmented packets do need to be duplicated in time-sensitive use cases */
uint64_t time_now = time_average_now();
uint64_t waited_time = time_now - sdu->sdu->time_of_arrival;
time_average_add(entity->common.txsdu_avg_time_to_tx, time_now, waited_time);
/* update buffer status */
entity->common.bstatus.tx_size -= sdu->size;

View File

@@ -521,13 +521,11 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size)
entity->common.stats.txpdu_pkts++;
entity->common.stats.txpdu_bytes += size;
if (sdu->sdu->time_of_arrival) {
uint64_t time_now = time_average_now();
uint64_t waited_time = time_now - sdu->sdu->time_of_arrival;
/* set time_of_arrival to 0 so as to update stats only once */
sdu->sdu->time_of_arrival = 0;
time_average_add(entity->common.txsdu_avg_time_to_tx, time_now, waited_time);
}
/* No need to 'zero' time-of-arrival;
Segmented packets do need to be duplicated in time-sensitive use cases */
uint64_t time_now = time_average_now();
uint64_t waited_time = time_now - sdu->sdu->time_of_arrival;
time_average_add(entity->common.txsdu_avg_time_to_tx, time_now, waited_time);
nr_rlc_free_sdu_segment(sdu);

View File

@@ -960,13 +960,13 @@ rlc_op_status_t rrc_rlc_config_req (
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ctxt_pP->rntiMaybeUEid);
if (srb_flagP) {
if (ue->srb[rb_idP-1] != NULL) {
ue->srb[rb_idP-1]->delete(ue->srb[rb_idP-1]);
ue->srb[rb_idP-1]->delete_entity(ue->srb[rb_idP-1]);
ue->srb[rb_idP-1] = NULL;
} else
LOG_W(RLC, "removing non allocated SRB %ld, do nothing\n", rb_idP);
} else {
if (ue->drb[rb_idP-1] != NULL) {
ue->drb[rb_idP-1]->delete(ue->drb[rb_idP-1]);
ue->drb[rb_idP-1]->delete_entity(ue->drb[rb_idP-1]);
ue->drb[rb_idP-1] = NULL;
} else
LOG_W(RLC, "removing non allocated DRB %ld, do nothing\n", rb_idP);
@@ -1074,6 +1074,12 @@ const bool nr_rlc_get_statistics(
if (rb != NULL) {
rb->get_stats(rb, out);
ret = true;
// Patch buffer status using OAI results (no need to change anything in the RB)
// rb->set_time(rb, nr_rlc_current_time);
nr_rlc_entity_buffer_status_t oai_stat = rb->buffer_status(rb, 1000*1000);
out->rxbuf_occ_bytes = oai_stat.status_size;
out->txbuf_occ_bytes = oai_stat.tx_size + oai_stat.retx_size;
} else {
ret = false;
}

View File

@@ -35,6 +35,7 @@
#include "NR_RadioBearerConfig.h"
#include "NR_CellGroupConfig.h"
#include "openair2/RRC/NR/nr_rrc_proto.h"
#include "nr_rlc_ue_manager.h"
struct NR_RLC_Config;
struct NR_LogicalChannelConfig;
@@ -63,3 +64,5 @@ void nr_rlc_activate_srb0(int rnti, struct gNB_MAC_INST_s *mac, void *rawUE,
const uint8_t *sdu,
sdu_size_t sdu_len,
void *rawUE));
const bool nr_rlc_get_statistics(int rnti, int srb_flag, int rb_id, nr_rlc_statistics_t *out);

View File

@@ -128,16 +128,16 @@ void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *_m, int rnti)
if (ue->srb0 != NULL) {
/* deliver_sdu_data for srb0 is allocated, needs a free() */
free(ue->srb0->deliver_sdu_data);
ue->srb0->delete(ue->srb0);
ue->srb0->delete_entity(ue->srb0);
}
for (j = 0; j < 3; j++)
if (ue->srb[j] != NULL)
ue->srb[j]->delete(ue->srb[j]);
ue->srb[j]->delete_entity(ue->srb[j]);
for (j = 0; j < MAX_DRBS_PER_UE; j++)
if (ue->drb[j] != NULL)
ue->drb[j]->delete(ue->drb[j]);
ue->drb[j]->delete_entity(ue->drb[j]);
free(ue);

View File

@@ -418,8 +418,8 @@ int test_main(void)
}
}
gnb->delete(gnb);
ue->delete(ue);
gnb->delete_entity(gnb);
ue->delete_entity(ue);
free(sdu);
free(pdu);

View File

@@ -68,7 +68,7 @@ rlc_entity_t *new_rlc_entity_am(
ret->common.reestablishment = rlc_entity_am_reestablishment;
ret->common.delete = rlc_entity_am_delete;
ret->common.delete_entity = rlc_entity_am_delete;
ret->common.deliver_sdu = deliver_sdu;
ret->common.deliver_sdu_data = deliver_sdu_data;
@@ -120,7 +120,7 @@ rlc_entity_t *new_rlc_entity_um(
ret->common.reestablishment = rlc_entity_um_reestablishment;
ret->common.delete = rlc_entity_um_delete;
ret->common.delete_entity = rlc_entity_um_delete;
ret->common.deliver_sdu = deliver_sdu;
ret->common.deliver_sdu_data = deliver_sdu_data;

View File

@@ -48,7 +48,7 @@ typedef struct rlc_entity_t {
void (*reestablishment)(struct rlc_entity_t *entity);
void (*delete)(struct rlc_entity_t *entity);
void (*delete_entity)(struct rlc_entity_t *entity);
/* callbacks provided to the RLC module */
void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_t *entity,

View File

@@ -950,13 +950,13 @@ rlc_op_status_t rrc_rlc_config_req (
ue = rlc_manager_get_ue(rlc_ue_manager, ctxt_pP->rntiMaybeUEid);
if (srb_flagP) {
if (ue->srb[rb_idP-1] != NULL) {
ue->srb[rb_idP-1]->delete(ue->srb[rb_idP-1]);
ue->srb[rb_idP-1]->delete_entity(ue->srb[rb_idP-1]);
ue->srb[rb_idP-1] = NULL;
} else
LOG_W(RLC, "removing non allocated SRB %d, do nothing\n", (int)rb_idP);
} else {
if (ue->drb[rb_idP-1] != NULL) {
ue->drb[rb_idP-1]->delete(ue->drb[rb_idP-1]);
ue->drb[rb_idP-1]->delete_entity(ue->drb[rb_idP-1]);
ue->drb[rb_idP-1] = NULL;
} else
LOG_W(RLC, "removing non allocated DRB %d, do nothing\n", (int)rb_idP);

View File

@@ -127,11 +127,11 @@ void rlc_manager_remove_ue(rlc_ue_manager_t *_m, int rnti)
for (j = 0; j < 2; j++)
if (ue->srb[j] != NULL)
ue->srb[j]->delete(ue->srb[j]);
ue->srb[j]->delete_entity(ue->srb[j]);
for (j = 0; j < 5; j++)
if (ue->drb[j] != NULL)
ue->drb[j]->delete(ue->drb[j]);
ue->drb[j]->delete_entity(ue->drb[j]);
free(ue);

View File

@@ -368,8 +368,8 @@ int test_main(void)
}
}
enb->delete(enb);
ue->delete(ue);
enb->delete_entity(enb);
ue->delete_entity(ue);
free(sdu);
free(pdu);