Add basic E2 agent through git submodule
- Add E2 agent that leverages FlexRIC e2ap library - Add documentation in openair2/E2AP/README.md - Currently, statistics exported are random
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
[submodule "openair2/E2AP/flexric"]
|
||||
path = openair2/E2AP/flexric
|
||||
url = https://gitlab.eurecom.fr/mosaic5g/flexric.git
|
||||
branch = remotes/origin/mir_dev
|
||||
@@ -328,6 +328,18 @@ endif()
|
||||
# asn1c skeletons need this
|
||||
add_definitions(-DHAVE_NETINET_IN_H)
|
||||
|
||||
#########################
|
||||
##### E2 AGENT
|
||||
#########################
|
||||
#add_boolean_option() does not work -- why?
|
||||
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)
|
||||
add_subdirectory ("${E2AP_DIR}")
|
||||
endif()
|
||||
|
||||
##################################################
|
||||
# ASN.1 grammar C code generation & dependencies #
|
||||
##################################################
|
||||
@@ -1567,6 +1579,11 @@ add_library(L2
|
||||
)
|
||||
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_ran_func)
|
||||
target_compile_definitions(L2 PRIVATE E2_AGENT)
|
||||
endif()
|
||||
|
||||
|
||||
add_library(MAC_NR ${MAC_NR_SRC})
|
||||
target_link_libraries(MAC_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
@@ -1597,6 +1614,11 @@ add_library(e1_pdcp_if
|
||||
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_compile_definitions(L2_NR PRIVATE E2_AGENT)
|
||||
endif()
|
||||
|
||||
|
||||
add_library(L2_LTE_NR
|
||||
${L2_RRC_SRC}
|
||||
@@ -2174,6 +2196,10 @@ target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYP
|
||||
target_link_libraries(lte-softmodem PRIVATE ${T_LIB})
|
||||
target_link_libraries(lte-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
|
||||
if(E2_AGENT)
|
||||
target_compile_definitions(lte-softmodem PRIVATE E2_AGENT)
|
||||
endif()
|
||||
|
||||
add_executable(oairu
|
||||
${OPENAIR_DIR}/executables/lte-ru.c
|
||||
${OPENAIR_DIR}/executables/ru_control.c
|
||||
@@ -2285,6 +2311,10 @@ endif()
|
||||
# force the generation of ASN.1 so that we don't need to wait during the build
|
||||
target_link_libraries(nr-softmodem PRIVATE
|
||||
asn1_lte_rrc asn1_nr_rrc asn1_s1ap asn1_ngap asn1_m2ap asn1_m3ap asn1_x2ap asn1_f1ap asn1_lpp)
|
||||
if(E2_AGENT)
|
||||
target_compile_definitions(nr-softmodem PRIVATE E2_AGENT)
|
||||
endif()
|
||||
|
||||
|
||||
add_executable(nr-cuup
|
||||
executables/nr-cuup.c
|
||||
|
||||
@@ -78,6 +78,8 @@ Options:
|
||||
Pass the supplied option verbatim to cmake.
|
||||
-d | --build-dir
|
||||
Sets build directory (will be <oai-root>/cmake_targets/<build-dir>/build)
|
||||
--build-e2
|
||||
Enable the the E2 Agent
|
||||
-I | --install-external-packages
|
||||
Installs required packages such as LibXML, asn1.1 compiler, ...
|
||||
This option will require root password
|
||||
@@ -197,6 +199,10 @@ function main() {
|
||||
-d | --build-dir)
|
||||
BUILD_DIR=$2
|
||||
shift 2;;
|
||||
--build-e2 )
|
||||
CMAKE_CMD="$CMAKE_CMD -DE2_AGENT=ON"
|
||||
shift
|
||||
;;
|
||||
-I | --install-external-packages)
|
||||
INSTALL_EXTERNAL=1
|
||||
echo_info "Will install external packages"
|
||||
|
||||
@@ -82,6 +82,12 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#include "openair2/E1AP/e1ap_common.h"
|
||||
#include "openair2/E1AP/e1ap_api.h"
|
||||
|
||||
#ifdef E2_AGENT
|
||||
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
|
||||
#include "openair2/E2AP/RAN_FUNCTION/init_ran_func.h"
|
||||
#endif
|
||||
|
||||
|
||||
pthread_cond_t nfapi_sync_cond;
|
||||
pthread_mutex_t nfapi_sync_mutex;
|
||||
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
|
||||
@@ -683,6 +689,53 @@ int main( int argc, char **argv ) {
|
||||
|
||||
config_sync_var=0;
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef E2_AGENT
|
||||
|
||||
//////////////////////////////////
|
||||
//////////////////////////////////
|
||||
//// Init the E2 Agent
|
||||
|
||||
sm_io_ag_ran_t io = init_ran_func_ag();
|
||||
fr_args_t args = init_fr_args(0, NULL);
|
||||
|
||||
// OAI Wrapper
|
||||
e2_agent_args_t oai_args = RCconfig_NR_E2agent();
|
||||
if(oai_args.sm_dir != NULL)
|
||||
memcpy(args.libs_dir, oai_args.sm_dir, 128);
|
||||
|
||||
sleep(1);
|
||||
const gNB_RRC_INST* rrc = RC.nrrrc[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 = rrc->node_type;
|
||||
int nb_id = 0;
|
||||
int cu_du_id = 0;
|
||||
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;
|
||||
} else if (node_type == ngran_gNB_CU) {
|
||||
cu_du_id = rrc->node_id + 1;
|
||||
nb_id = rrc->configuration.cell_identity;
|
||||
} 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);
|
||||
|
||||
init_agent_api(mcc, mnc, mnc_digit_len, nb_id, cu_du_id, node_type, io, &args);
|
||||
// }
|
||||
|
||||
#endif // E2_AGENT
|
||||
|
||||
|
||||
if (NFAPI_MODE==NFAPI_MODE_PNF) {
|
||||
wait_nfapi_init("main?");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
# Check that the submodule exists or init+update if not
|
||||
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)
|
||||
else()
|
||||
message(STATUS "E2AP submodule detected.")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/flexric/CMakeLists.txt)
|
||||
message(FATAL_ERROR "The submodules for E2 agent were not downloaded!")
|
||||
endif()
|
||||
|
||||
|
||||
set(BUILDING_LIBRARY "STATIC" CACHE STRING "Static or dynamic library")
|
||||
set_property(CACHE BUILDING_LIBRARY PROPERTY STRINGS "STATIC" "DYNAMIC")
|
||||
message(STATUS "Selected LIBRARY TYPE: ${BUILDING_LIBRARY}")
|
||||
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
if(BUILDING_LIBRARY STREQUAL "STATIC")
|
||||
add_compile_options("-W;-Wall;-Wextra;-g;-Wno-unused-result;")
|
||||
elseif(BUILDING_LIBRARY STREQUAL "DYNAMIC")
|
||||
# -fPIC flag
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
add_compile_options("-W;-Wall;-Wextra;-g")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown building type. Either choose a static or a dynamic library")
|
||||
endif()
|
||||
|
||||
|
||||
set(E2AP_ENCODING "ASN" CACHE STRING "The E2AP encoding to use")
|
||||
set_property(CACHE E2AP_ENCODING PROPERTY STRINGS "ASN" "FLATBUFFERS")
|
||||
message(STATUS "Selected E2AP_ENCODING: ${E2AP_ENCODING}")
|
||||
|
||||
|
||||
#######
|
||||
## Service Models
|
||||
#######
|
||||
|
||||
add_definitions(-DSERVICE_MODEL_DIR_PATH="${SM_DIR_PATH}/")
|
||||
|
||||
# KPM service Model encoding definitions
|
||||
set(SM_ENCODING_KPM "ASN" CACHE STRING "The KPM SM encoding to use")
|
||||
set_property(CACHE SM_ENCODING_KPM PROPERTY STRINGS "PLAIN" "ASN" "FLATBUFFERS")
|
||||
message(STATUS "Selected KPM SM_ENCODING: ${SM_ENCODING_KPM}")
|
||||
|
||||
# RC service Model encoding definitions
|
||||
set(SM_ENCODING_RC "ASN" CACHE STRING "The RC SM encoding to use")
|
||||
set_property(CACHE SM_ENCODING_RC PROPERTY STRINGS "PLAIN" "ASN" "FLATBUFFERS")
|
||||
message(STATUS "Selected RC SM_ENCODING: ${SM_ENCODING_RC}")
|
||||
|
||||
# MAC Service Model
|
||||
set(SM_ENCODING_MAC "PLAIN" CACHE STRING "The MAC SM encoding to use")
|
||||
set_property(CACHE SM_ENCODING_MAC PROPERTY STRINGS "PLAIN" "ASN" "FLATBUFFERS")
|
||||
message(STATUS "Selected MAC SM_ENCODING: ${SM_ENCODING_MAC}")
|
||||
|
||||
# RLC Service Model
|
||||
set(SM_ENCODING_RLC "PLAIN" CACHE STRING "The RLC SM encoding to use")
|
||||
set_property(CACHE SM_ENCODING_RLC PROPERTY STRINGS "PLAIN" "ASN" "FLATBUFFERS")
|
||||
message(STATUS "Selected RLC SM_ENCODING: ${SM_ENCODING_RLC}")
|
||||
|
||||
# PDCP Service Model
|
||||
set(SM_ENCODING_PDCP "PLAIN" CACHE STRING "The PDCP SM encoding to use")
|
||||
set_property(CACHE SM_ENCODING_PDCP PROPERTY STRINGS "PLAIN" "ASN" "FLATBUFFERS")
|
||||
message(STATUS "Selected PDCP SM_ENCODING: ${SM_ENCODING_PDCP}")
|
||||
|
||||
# SLICE Service Model
|
||||
set(SM_ENCODING_SLICE "PLAIN" CACHE STRING "The SLICE SM encoding to use")
|
||||
set_property(CACHE SM_ENCODING_SLICE PROPERTY STRINGS "PLAIN" "ASN" "FLATBUFFERS")
|
||||
message(STATUS "Selected SLICE SM_ENCODING: ${SM_ENCODING_SLICE}")
|
||||
|
||||
# GTP Service Model
|
||||
set(SM_ENCODING_GTP "PLAIN" CACHE STRING "The GTP SM encoding to use")
|
||||
set_property(CACHE SM_ENCODING_GTP PROPERTY STRINGS "PLAIN")
|
||||
message(STATUS "Selected GTP SM_ENCODING: ${SM_ENCODING_GTP}")
|
||||
|
||||
########
|
||||
### Flatbuffer
|
||||
########
|
||||
set(FlatCC_INCLUDE_DIR "" CACHE STRING "The Flatbuffers include directory")
|
||||
set(FlatCC_LIB_DIR "" CACHE STRING "The Flatbuffers lib directory")
|
||||
|
||||
if(E2AP_ENCODING STREQUAL "FLATBUFFERS")
|
||||
find_library(FlatCC
|
||||
NAMES flatccrt_d
|
||||
HINTS ${FlatCC_LIB_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(flexric/src)
|
||||
add_subdirectory(flexric/src/agent)
|
||||
add_subdirectory(flexric/src/lib)
|
||||
add_subdirectory(flexric/src/sm)
|
||||
add_subdirectory(flexric/src/util)
|
||||
add_subdirectory(RAN_FUNCTION)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
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
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
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
|
||||
)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "ran_func_gtp.h"
|
||||
#include "../../flexric/test/rnd/fill_rnd_data_gtp.h"
|
||||
#include <assert.h>
|
||||
|
||||
void read_gtp_sm(void * data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
gtp_ind_data_t* gtp = (gtp_ind_data_t*)(data);
|
||||
fill_gtp_ind_data(gtp);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#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
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#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");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#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
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "ran_func_pdcp.h"
|
||||
#include "../../flexric/test/rnd/fill_rnd_data_pdcp.h"
|
||||
#include <assert.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#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
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "ran_func_rlc.h"
|
||||
#include "../../flexric/test/rnd/fill_rnd_data_rlc.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#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
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "ran_func_slice.h"
|
||||
#include "../../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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#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
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "ran_func_tc.h"
|
||||
#include "../../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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#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
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
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
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
RAN Functions as defined by O-RAN
|
||||
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
#include "ran_func_kpm.h"
|
||||
#include "../../flexric/test/rnd/fill_rnd_data_kpm.h"
|
||||
#include "../../flexric/src/util/time_now_us.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static
|
||||
gnb_e2sm_t fill_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.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)
|
||||
{
|
||||
ue_id_e2sm_t ue_id_data = {0};
|
||||
|
||||
ue_id_data.type = GNB_UE_ID_E2SM;
|
||||
ue_id_data.gnb = fill_gnb_data();
|
||||
|
||||
return ue_id_data;
|
||||
}
|
||||
|
||||
static
|
||||
kpm_ind_msg_format_1_t fill_kpm_ind_msg_frm_1(void)
|
||||
{
|
||||
kpm_ind_msg_format_1_t msg_frm_1 = {0};
|
||||
|
||||
// Measurement Data
|
||||
uint32_t num_drbs = 2;
|
||||
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" );
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Measurement Information - OPTIONAL
|
||||
msg_frm_1.meas_info_lst_len = num_drbs;
|
||||
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
|
||||
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;
|
||||
|
||||
// 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(void)
|
||||
{
|
||||
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.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();
|
||||
}
|
||||
|
||||
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* 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 );
|
||||
}
|
||||
|
||||
printf("Parameter to report: %s \n", kpm->act_def->frm_4.action_def_format_1.meas_info_lst->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();
|
||||
} 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#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
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
#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 <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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef RAN_FUNC_SM_RAN_CTRL_READ_WRITE_AGENT_H
|
||||
#define RAN_FUNC_SM_RAN_CTRL_READ_WRITE_AGENT_H
|
||||
|
||||
#include "../../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
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
#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"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 RAN_FUNC_INIT_E2_H
|
||||
#define RAN_FUNC_INIT_E2_H
|
||||
|
||||
#include "../flexric/src/sm/sm_io.h"
|
||||
|
||||
sm_io_ag_ran_t init_ran_func_ag(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
<h1 align="center">
|
||||
<a href="https://openairinterface.org/"><img src="https://openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png" alt="OAI" width="550"></a>
|
||||
</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-OAI--Public--V1.1-blue" alt="License"></a>
|
||||
<a href="https://releases.ubuntu.com/18.04/"><img src="https://img.shields.io/badge/OS-Ubuntu18-Green" alt="Supported OS Ubuntu 18"></a>
|
||||
<a href="https://releases.ubuntu.com/20.04/"><img src="https://img.shields.io/badge/OS-Ubuntu20-Green" alt="Supported OS Ubuntu 20"></a>
|
||||
<a href="https://releases.ubuntu.com/22.04/"><img src="https://img.shields.io/badge/OS-Ubuntu22-Green" alt="Supported OS Ubuntu 22"></a>
|
||||
<a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux"><img src="https://img.shields.io/badge/OS-RHEL8-Green" alt="Supported OS RHEL8"></a>
|
||||
<a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux"><img src="https://img.shields.io/badge/OS-RHEL9-Green" alt="Supported OS RELH9"></a>
|
||||
<a href="https://getfedora.org/en/workstation/"><img src="https://img.shields.io/badge/OS-Fedore37-Green" alt="Supported OS Fedora 37"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://jenkins-oai.eurecom.fr/job/RAN-Container-Parent/"><img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins-oai.eurecom.fr%2Fjob%2FRAN-Container-Parent%2F&label=build%20Images"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-gnb"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-gnb?label=gNB%20docker%20pulls"></a>
|
||||
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-nr-ue"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-nr-ue?label=NR-UE%20docker%20pulls"></a>
|
||||
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-enb"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-enb?label=eNB%20docker%20pulls"></a>
|
||||
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-lte-ue"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-lte-ue?label=LTE-UE%20docker%20pulls"></a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
# OpenAirInterface License #
|
||||
|
||||
* [OAI License Model](http://www.openairinterface.org/?page_id=101)
|
||||
* [OAI License v1.1 on our website](http://www.openairinterface.org/?page_id=698)
|
||||
|
||||
It is distributed under **OAI Public License V1.1**.
|
||||
|
||||
The license information is distributed under [LICENSE](LICENSE) file in the same directory.
|
||||
|
||||
Please see [NOTICE](NOTICE.md) file for third party software that is included in the sources.
|
||||
|
||||
# Overview
|
||||
|
||||
This tutorial describes the steps of deployment 5G OAI RAN, with integrated E2 agent, with FlexRIC, O-RAN compliant nearRT-RIC.
|
||||
|
||||
# 1. Installation
|
||||
|
||||
## 1.1 Install prerequisites
|
||||
|
||||
- A *recent* CMake (at least v3.15).
|
||||
|
||||
On Ubuntu, you might want to use [this PPA](https://apt.kitware.com/) to install an up-to-date version.
|
||||
|
||||
- SWIG (at least v.4.0).
|
||||
|
||||
We use SWIG as an interface generator to enable the multi-language feature (i.e., C/C++ and Python) for the xApps. Please, check your SWIG version (i.e, `swig
|
||||
-version`) and install it from scratch if necessary as described here: https://swig.org/svn.html or via the code below:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/swig/swig.git
|
||||
cd swig
|
||||
./autogen.sh
|
||||
./configure --prefix=/usr/
|
||||
make
|
||||
make install
|
||||
```
|
||||
|
||||
- Flatbuffer encoding(optional).
|
||||
|
||||
We also provide a flatbuffers encoding/decoding scheme as alternative to ASN.1. In case that you want to use it follow the
|
||||
instructions at https://github.com/dvidelabs/flatcc and provide the path for the lib and include when selecting it at `ccmake ..` from the build directory
|
||||
|
||||
## 1.2 Download the required dependencies.
|
||||
|
||||
Below an example of how to install it in ubuntu
|
||||
```bash
|
||||
sudo apt install libsctp-dev python3.8 cmake-curses-gui libpcre2-dev python-dev
|
||||
```
|
||||
|
||||
# 2. Deployment
|
||||
|
||||
## 2.1 OAI RAN
|
||||
|
||||
### 2.1.1 Clone the OAI repository
|
||||
```bash
|
||||
git clone https://gitlab.eurecom.fr/oai/openairinterface5g oai
|
||||
cd oai/
|
||||
```
|
||||
|
||||
### 2.1.2 Build OAI
|
||||
```bash
|
||||
cd cmake_targets/
|
||||
./build_oai -I -w SIMU --gNB --nrUE --build-e2 --ninja
|
||||
```
|
||||
If the flexric folder is empty, try manually the following commands
|
||||
|
||||
```bash
|
||||
git submodule init
|
||||
git submodule update
|
||||
```
|
||||
|
||||
* -I option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed.
|
||||
* -w option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from liboai_device.so to the true device which will be used at run-time (here the USRP one, liboai_usrpdevif.so). The RF simulatorRF simulator is implemented as a specific device replacing RF hardware, it can be specifically built using -w SIMU option, but is also built during any softmodem build.
|
||||
* --gNB is to build the nr-softmodem and nr-cuup executables and all required shared libraries
|
||||
* --nrUE is to build the nr-uesoftmodem executable and all required shared libraries
|
||||
* --ninja is to use the ninja build tool, which speeds up compilation
|
||||
* --build-e2 option is to use the E2 agent, integrated within gNB.
|
||||
|
||||
## 2.2 FlexRIC
|
||||
|
||||
### 2.2.1 Clone the FlexRIC repository
|
||||
```bash
|
||||
git clone https://gitlab.eurecom.fr/mosaic5g/flexric flexric
|
||||
cd flexric/
|
||||
git checkout mir_dev
|
||||
```
|
||||
|
||||
### 2.2.2 Build FlexRIC
|
||||
```bash
|
||||
mkdir build && cd build && cmake .. && make
|
||||
```
|
||||
|
||||
### 2.2.3 Installation of Service Models (SMs)
|
||||
```bash
|
||||
sudo make install
|
||||
```
|
||||
|
||||
By default the service model libraries will be installed in the path /usr/local/lib/flexric while the configuration file in `/usr/local/etc/flexric`.
|
||||
|
||||
* Note: currently, only xApp KPM v03.00 and RC v01.03 (xapp_kpm_rc) is supported to communicate with the integrated E2 agent in OAI. If you are interested in custom SMs (MAC, RLC, PDCP, GTP, TC and SLICE), please follow the instructions at https://gitlab.eurecom.fr/mosaic5g/flexric.
|
||||
|
||||
# 3. Start the process
|
||||
|
||||
* start the gNB
|
||||
```bash
|
||||
cd oai/cmake_targets/ran_build/build
|
||||
sudo ./nr-softmodem RFSIMULATOR=server -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --rfsim --sa
|
||||
```
|
||||
|
||||
* start the nrUE
|
||||
```bash
|
||||
cd oai/cmake_targets/ran_build/build
|
||||
sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --nokrnmod --rfsim --sa --uicc0.imsi 001010000000001
|
||||
```
|
||||
|
||||
* start the nearRT-RIC
|
||||
```bash
|
||||
cd flexric
|
||||
./build/examples/ric/nearRT-RIC
|
||||
```
|
||||
|
||||
* start the KPM+RC xApp
|
||||
```bash
|
||||
cd flexric
|
||||
./build/examples/xApp/c/kpm_rc/xapp_kpm_rc
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 E2_AGENT_ARGS_H
|
||||
#define E2_AGENT_ARGS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Wrapper for OAI
|
||||
typedef struct{
|
||||
const char *ip;
|
||||
const char *sm_dir;
|
||||
} e2_agent_args_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Submodule
+1
Submodule openair2/E2AP/flexric added at ef00d05a3f
@@ -2929,3 +2929,25 @@ void read_config_and_init(void) {
|
||||
RCconfig_RRC(enb_id, RC.rrc[enb_id]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef E2_AGENT
|
||||
|
||||
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);
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -116,6 +116,11 @@ void read_config_and_init(void);
|
||||
int RCconfig_X2(MessageDef *msg_p, uint32_t i);
|
||||
int RCconfig_M2(MessageDef *msg_p, uint32_t i);
|
||||
|
||||
#ifdef E2_AGENT
|
||||
#include "openair2/E2AP/e2_agent_arg.h"
|
||||
e2_agent_args_t RCconfig_E2agent(void);
|
||||
#endif
|
||||
|
||||
void fill_SL_configuration(RrcConfigurationReq *RRCcfg, ccparams_sidelink_t *SLconfig, int cell_idx, int cc_idx, char *config_fname);
|
||||
void fill_eMTC_configuration(RrcConfigurationReq *RRCcfg, ccparams_eMTC_t *eMTCconfig, int cell_idx, int cc_idx, char *config_fname, char *brparamspath);
|
||||
|
||||
|
||||
@@ -1317,6 +1317,35 @@ typedef struct srb1_params_s {
|
||||
#define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n"
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef E2_AGENT
|
||||
|
||||
/* E2 Agent configuration */
|
||||
#define CONFIG_STRING_E2AGENT "e2_agent"
|
||||
|
||||
#define E2AGENT_CONFIG_IP "ip"
|
||||
//#define E2AGENT_CONFIG_PORT "port"
|
||||
#define E2AGENT_CONFIG_SMDIR "sm_dir"
|
||||
|
||||
static const char* const e2agent_config_ip_default = NULL;
|
||||
static const char* const e2agent_config_smdir_default = NULL;
|
||||
//static const uint16_t e2agent_config_port_default = 36421;
|
||||
|
||||
#define E2AGENT_PARAMS_DESC { \
|
||||
{E2AGENT_CONFIG_IP, "RIC IP address", 0, strptr:NULL, defstrval:(char*)e2agent_config_ip_default, TYPE_STRING, 0}, \
|
||||
{E2AGENT_CONFIG_SMDIR, "Directory with SMs to load", 0, strptr:NULL, defstrval:(char*)e2agent_config_smdir_default, TYPE_STRING, 0}, \
|
||||
}
|
||||
/*
|
||||
// {E2AGENT_CONFIG_PORT, "RIC port", 0, u16ptr:NULL, defuintval:e2agent_config_port_default, TYPE_UINT16, 0}, \
|
||||
}
|
||||
*/
|
||||
|
||||
#define E2AGENT_CONFIG_IP_IDX 0
|
||||
#define E2AGENT_CONFIG_SMDIR_IDX 1
|
||||
//#define E2AGENT_CONFIG_PORT_IDX 2
|
||||
|
||||
#endif // E2_AGENT
|
||||
|
||||
|
||||
#include "enb_paramdef_emtc.h"
|
||||
#include "enb_paramdef_sidelink.h"
|
||||
#include "enb_paramdef_mce.h"
|
||||
|
||||
@@ -2259,3 +2259,23 @@ void nr_read_config_and_init(void) {
|
||||
nr_pdcp_layer_init();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef E2_AGENT
|
||||
|
||||
e2_agent_args_t RCconfig_NR_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 from FlexRIC\n", CONFIG_STRING_E2AGENT);
|
||||
return (e2_agent_args_t) { 0 };
|
||||
}
|
||||
e2_agent_args_t dst = {0};
|
||||
if(e2agent_params[E2AGENT_CONFIG_IP_IDX].strptr != NULL)
|
||||
dst.ip = *e2agent_params[E2AGENT_CONFIG_IP_IDX].strptr;
|
||||
if(e2agent_params[E2AGENT_CONFIG_SMDIR_IDX].strptr != NULL)
|
||||
dst.sm_dir = *e2agent_params[E2AGENT_CONFIG_SMDIR_IDX].strptr;
|
||||
return dst;
|
||||
}
|
||||
|
||||
#endif // E2_AGENT
|
||||
|
||||
@@ -110,5 +110,10 @@ void nr_read_config_and_init(void);
|
||||
MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process);
|
||||
ngran_node_t get_node_type(void);
|
||||
|
||||
#ifdef E2_AGENT
|
||||
#include "openair2/E2AP/e2_agent_arg.h"
|
||||
e2_agent_args_t RCconfig_NR_E2agent(void);
|
||||
#endif // E2_AGENT
|
||||
|
||||
#endif /* GNB_CONFIG_H_ */
|
||||
/** @} */
|
||||
|
||||
@@ -266,3 +266,8 @@ log_config :
|
||||
f1ap_log_level ="debug";
|
||||
};
|
||||
|
||||
e2_agent = {
|
||||
address = "127.0.0.1";
|
||||
#sm_dir = "/path/where/the/SMs/are/located/"
|
||||
sm_dir = "/usr/local/lib/flexric/"
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user