Skip to content
Snippets Groups Projects
Commit 70ad480a authored by mir's avatar mir Committed by Robert Schmidt
Browse files

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
parent c81ed57a
No related branches found
No related tags found
No related merge requests found
Showing
with 494 additions and 0 deletions
[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() ...@@ -328,6 +328,18 @@ endif()
# asn1c skeletons need this # asn1c skeletons need this
add_definitions(-DHAVE_NETINET_IN_H) 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 # # ASN.1 grammar C code generation & dependencies #
################################################## ##################################################
...@@ -1567,6 +1579,11 @@ add_library(L2 ...@@ -1567,6 +1579,11 @@ add_library(L2
) )
target_link_libraries(L2 PRIVATE x2ap s1ap lte_rrc m2ap) target_link_libraries(L2 PRIVATE x2ap s1ap lte_rrc m2ap)
target_link_libraries(L2 PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) 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}) add_library(MAC_NR ${MAC_NR_SRC})
target_link_libraries(MAC_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) target_link_libraries(MAC_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
...@@ -1597,6 +1614,11 @@ add_library(e1_pdcp_if ...@@ -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(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) 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 add_library(L2_LTE_NR
${L2_RRC_SRC} ${L2_RRC_SRC}
...@@ -2174,6 +2196,10 @@ target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYP ...@@ -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 ${T_LIB})
target_link_libraries(lte-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) 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 add_executable(oairu
${OPENAIR_DIR}/executables/lte-ru.c ${OPENAIR_DIR}/executables/lte-ru.c
${OPENAIR_DIR}/executables/ru_control.c ${OPENAIR_DIR}/executables/ru_control.c
...@@ -2285,6 +2311,10 @@ endif() ...@@ -2285,6 +2311,10 @@ endif()
# force the generation of ASN.1 so that we don't need to wait during the build # force the generation of ASN.1 so that we don't need to wait during the build
target_link_libraries(nr-softmodem PRIVATE 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) 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 add_executable(nr-cuup
executables/nr-cuup.c executables/nr-cuup.c
......
...@@ -78,6 +78,8 @@ Options: ...@@ -78,6 +78,8 @@ Options:
Pass the supplied option verbatim to cmake. Pass the supplied option verbatim to cmake.
-d | --build-dir -d | --build-dir
Sets build directory (will be <oai-root>/cmake_targets/<build-dir>/build) Sets build directory (will be <oai-root>/cmake_targets/<build-dir>/build)
--build-e2
Enable the the E2 Agent
-I | --install-external-packages -I | --install-external-packages
Installs required packages such as LibXML, asn1.1 compiler, ... Installs required packages such as LibXML, asn1.1 compiler, ...
This option will require root password This option will require root password
...@@ -197,6 +199,10 @@ function main() { ...@@ -197,6 +199,10 @@ function main() {
-d | --build-dir) -d | --build-dir)
BUILD_DIR=$2 BUILD_DIR=$2
shift 2;; shift 2;;
--build-e2 )
CMAKE_CMD="$CMAKE_CMD -DE2_AGENT=ON"
shift
;;
-I | --install-external-packages) -I | --install-external-packages)
INSTALL_EXTERNAL=1 INSTALL_EXTERNAL=1
echo_info "Will install external packages" echo_info "Will install external packages"
......
...@@ -82,6 +82,12 @@ unsigned short config_frames[4] = {2,9,11,13}; ...@@ -82,6 +82,12 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "openair2/E1AP/e1ap_common.h" #include "openair2/E1AP/e1ap_common.h"
#include "openair2/E1AP/e1ap_api.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_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex; pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref 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 ) { ...@@ -683,6 +689,53 @@ int main( int argc, char **argv ) {
config_sync_var=0; 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) { if (NFAPI_MODE==NFAPI_MODE_PNF) {
wait_nfapi_init("main?"); wait_nfapi_init("main?");
} }
......
# 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)
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_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
)
#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");
}
#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
#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");
}
#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
#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;
}
#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
#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");
}
#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
#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;
}
#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
#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;
}
#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
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% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment