mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Compare commits
17 Commits
pre-commit
...
new_jpn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf67061721 | ||
|
|
7e9a7d902f | ||
|
|
dd124b72d0 | ||
|
|
1327efeeba | ||
|
|
09c3eb9ba1 | ||
|
|
af66e9f4f3 | ||
|
|
fe63f1b164 | ||
|
|
3b6d9f8a5e | ||
|
|
a0dfe34260 | ||
|
|
ad665b707e | ||
|
|
10aa33f7b6 | ||
|
|
18e03f093a | ||
|
|
1bed096f37 | ||
|
|
ce510f14c5 | ||
|
|
315e5db0c6 | ||
|
|
bc09aeb2ef | ||
|
|
f625cdd20c |
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@@ -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 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)
|
||||
@@ -1583,6 +1600,8 @@ add_library(L2_NR
|
||||
${GNB_APP_SRC}
|
||||
)
|
||||
|
||||
target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap)
|
||||
|
||||
add_library(e1_if
|
||||
${NR_RRC_DIR}/cucp_cuup_direct.c
|
||||
${NR_RRC_DIR}/cucp_cuup_e1ap.c
|
||||
@@ -1597,6 +1616,10 @@ 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 +2197,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
|
||||
@@ -2262,6 +2289,10 @@ add_executable(nr-softmodem
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
#L2_NR
|
||||
${L2_NR_SRC}
|
||||
${MAC_NR_SRC}
|
||||
${GNB_APP_SRC}
|
||||
)
|
||||
|
||||
target_link_libraries(nr-softmodem PRIVATE
|
||||
@@ -2270,7 +2301,7 @@ target_link_libraries(nr-softmodem PRIVATE
|
||||
ITTI ${NAS_UE_LIB} lte_rrc nr_rrc
|
||||
ngap s1ap L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU SIMU_ETH
|
||||
x2ap f1ap m2ap m3ap e1ap
|
||||
-Wl,--end-group z dl)
|
||||
-Wl,--end-group z dl f1ap x2ap s1ap ngap nr_rrc )
|
||||
|
||||
target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${ATLAS_LIBRARIES})
|
||||
target_link_libraries(nr-softmodem PRIVATE ${T_LIB})
|
||||
@@ -2285,6 +2316,14 @@ 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()
|
||||
|
||||
|
||||
|
||||
target_compile_definitions(nr-softmodem PRIVATE MIR_FLAG)
|
||||
|
||||
|
||||
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"
|
||||
|
||||
@@ -59,8 +59,13 @@ add_library(telnetsrv_ci MODULE telnetsrv_ci.c)
|
||||
target_link_libraries(telnetsrv_ci PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
add_dependencies(telnetsrv telnetsrv_ci)
|
||||
|
||||
message(STATUS "Add bearer specific telnet functions in libtelnetsrv_bearer.so")
|
||||
add_library(telnetsrv_bearer MODULE telnetsrv_bearer.c)
|
||||
target_link_libraries(telnetsrv_bearer PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
add_dependencies(telnetsrv telnetsrv_bearer)
|
||||
|
||||
# all libraries should be written to root build dir
|
||||
set_target_properties(telnetsrv telnetsrv_enb telnetsrv_5Gue telnetsrv_ci
|
||||
set_target_properties(telnetsrv telnetsrv_enb telnetsrv_5Gue telnetsrv_ci telnetsrv_bearer
|
||||
PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../../..
|
||||
)
|
||||
|
||||
|
||||
96
common/utils/telnetsrv/telnetsrv_bearer.c
Normal file
96
common/utils/telnetsrv/telnetsrv_bearer.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
|
||||
|
||||
#define TELNETSERVERCODE
|
||||
#include "telnetsrv.h"
|
||||
|
||||
#define ERROR_MSG_RET(mSG, aRGS...) do { prnt(mSG, ##aRGS); return 1; } while (0)
|
||||
|
||||
static int get_single_ue_rnti(void)
|
||||
{
|
||||
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[0]->rrc_ue_head)) {
|
||||
return ue_context_p->ue_context.rnti;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_single_rnti(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (buf)
|
||||
ERROR_MSG_RET("no parameter allowed\n");
|
||||
|
||||
int rnti = get_single_ue_rnti();
|
||||
if (rnti < 1)
|
||||
ERROR_MSG_RET("different number of UEs\n");
|
||||
|
||||
prnt("single UE RNTI %04x\n", rnti);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rrc_gNB_trigger_new_bearer(int rnti);
|
||||
int add_bearer(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
int rnti = -1;
|
||||
if (!buf) {
|
||||
rnti = get_single_ue_rnti();
|
||||
if (rnti < 1)
|
||||
ERROR_MSG_RET("no UE found\n");
|
||||
} else {
|
||||
rnti = strtol(buf, NULL, 16);
|
||||
if (rnti < 1 || rnti >= 0xfffe)
|
||||
ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n");
|
||||
}
|
||||
|
||||
// verify it exists in RRC as well
|
||||
rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti);
|
||||
if (!rrcue)
|
||||
ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti);
|
||||
|
||||
rrc_gNB_trigger_new_bearer(rnti);
|
||||
prnt("called rrc_gNB_trigger_new_bearer(%04x)\n", rnti);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static telnetshell_cmddef_t bearercmds[] = {
|
||||
{"get_single_rnti", "", get_single_rnti},
|
||||
{"add_bearer", "[rnti(hex,opt)]", add_bearer},
|
||||
{"", "", NULL},
|
||||
};
|
||||
|
||||
static telnetshell_vardef_t bearervars[] = {
|
||||
|
||||
{"", 0, 0, NULL}
|
||||
};
|
||||
|
||||
void add_bearer_cmds(void) {
|
||||
add_telnetcmd("bearer", bearervars, bearercmds);
|
||||
}
|
||||
@@ -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?");
|
||||
}
|
||||
|
||||
98
openair2/E2AP/CMakeLists.txt
Normal file
98
openair2/E2AP/CMakeLists.txt
Normal file
@@ -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)
|
||||
|
||||
12
openair2/E2AP/RAN_FUNCTION/CMakeLists.txt
Normal file
12
openair2/E2AP/RAN_FUNCTION/CMakeLists.txt
Normal file
@@ -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
|
||||
)
|
||||
17
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/CMakeLists.txt
Normal file
17
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/CMakeLists.txt
Normal file
@@ -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
|
||||
)
|
||||
|
||||
24
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.c
Normal file
24
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.c
Normal file
@@ -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");
|
||||
}
|
||||
|
||||
13
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.h
Normal file
13
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_gtp.h
Normal file
@@ -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
|
||||
|
||||
24
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_mac.c
Normal file
24
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_mac.c
Normal file
@@ -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");
|
||||
}
|
||||
|
||||
12
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_mac.h
Normal file
12
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_mac.h
Normal file
@@ -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
|
||||
31
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_pdcp.c
Normal file
31
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_pdcp.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
13
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_pdcp.h
Normal file
13
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_pdcp.h
Normal file
@@ -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
|
||||
|
||||
25
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_rlc.c
Normal file
25
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_rlc.c
Normal file
@@ -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");
|
||||
}
|
||||
|
||||
13
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_rlc.h
Normal file
13
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_rlc.h
Normal file
@@ -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
|
||||
|
||||
47
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_slice.c
Normal file
47
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_slice.c
Normal file
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
13
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_slice.h
Normal file
13
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_slice.h
Normal file
@@ -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
|
||||
|
||||
39
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_tc.c
Normal file
39
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_tc.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
13
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_tc.h
Normal file
13
openair2/E2AP/RAN_FUNCTION/CUSTOMIZED/ran_func_tc.h
Normal file
@@ -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
|
||||
|
||||
7
openair2/E2AP/RAN_FUNCTION/O-RAN/CMakeLists.txt
Normal file
7
openair2/E2AP/RAN_FUNCTION/O-RAN/CMakeLists.txt
Normal file
@@ -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
|
||||
)
|
||||
3
openair2/E2AP/RAN_FUNCTION/O-RAN/README.md
Normal file
3
openair2/E2AP/RAN_FUNCTION/O-RAN/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
RAN Functions as defined by O-RAN
|
||||
|
||||
|
||||
209
openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c
Normal file
209
openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.c
Normal file
@@ -0,0 +1,209 @@
|
||||
#include "ran_func_kpm.h"
|
||||
#include "../../flexric/test/rnd/fill_rnd_data_kpm.h"
|
||||
#include "../../flexric/src/util/time_now_us.h"
|
||||
#include "../../../LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
//#include "../../../LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
//#include "../../../RRC/NR/nr_rrc_defs.h"
|
||||
//#include "../../../RRC/NR/rrc_gNB_UE_context.h"
|
||||
//#include "../../../../common/ran_context.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;
|
||||
}
|
||||
|
||||
// Forward declaration
|
||||
int get_single_ue_rnti(void);
|
||||
|
||||
static
|
||||
kpm_ind_msg_format_1_t fill_kpm_ind_msg_frm_1(void)
|
||||
{
|
||||
kpm_ind_msg_format_1_t msg_frm_1 = {0};
|
||||
|
||||
int const rnti = get_single_ue_rnti();
|
||||
|
||||
int const srb_flag = 0;
|
||||
int const rb_id = 4;
|
||||
nr_rlc_statistics_t out[2] = {0};
|
||||
|
||||
bool rc = nr_rlc_get_statistics(rnti, srb_flag, rb_id, &out[0]);
|
||||
assert(rc == true);
|
||||
|
||||
rc = nr_rlc_get_statistics(rnti, srb_flag, rb_id + 1, &out[1]);
|
||||
assert(rc == false && "At least for one bearer");
|
||||
|
||||
// Measurement Data
|
||||
uint32_t num_drbs = 1 + rc;
|
||||
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 = num_drbs; // (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 = out[0].txsdu_avg_time_to_tx;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 const 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
13
openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.h
Normal file
13
openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_kpm.h
Normal file
@@ -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
|
||||
|
||||
108
openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c
Normal file
108
openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
15
openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.h
Normal file
15
openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc.h
Normal file
@@ -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
|
||||
|
||||
73
openair2/E2AP/RAN_FUNCTION/init_ran_func.c
Normal file
73
openair2/E2AP/RAN_FUNCTION/init_ran_func.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
32
openair2/E2AP/RAN_FUNCTION/init_ran_func.h
Normal file
32
openair2/E2AP/RAN_FUNCTION/init_ran_func.h
Normal 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 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
|
||||
|
||||
155
openair2/E2AP/README.md
Normal file
155
openair2/E2AP/README.md
Normal file
@@ -0,0 +1,155 @@
|
||||
<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
|
||||
```
|
||||
|
||||
|
||||
35
openair2/E2AP/e2_agent_arg.h
Normal file
35
openair2/E2AP/e2_agent_arg.h
Normal file
@@ -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
|
||||
|
||||
|
||||
1
openair2/E2AP/flexric
Submodule
1
openair2/E2AP/flexric
Submodule
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"
|
||||
|
||||
@@ -1188,7 +1188,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
|
||||
rrc->nr_cellid = (uint64_t)*(GNBParamList.paramarray[i][GNB_NRCELLID_IDX].u64ptr);
|
||||
|
||||
rrc->um_on_default_drb = *(GNBParamList.paramarray[i][GNB_UMONDEFAULTDRB_IDX].uptr);
|
||||
rrc->um_on_default_drb = 1; // *(GNBParamList.paramarray[i][GNB_UMONDEFAULTDRB_IDX].uptr);
|
||||
if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) {
|
||||
|
||||
} else if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "cudu") == 0) {
|
||||
@@ -2259,3 +2259,26 @@ 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_ */
|
||||
/** @} */
|
||||
|
||||
@@ -62,10 +62,12 @@ static void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddMo
|
||||
if (rlc_bearer2release_list) {
|
||||
for (int i = 0; i < rlc_bearer2release_list->list.count; i++) {
|
||||
for (int idx = 0; idx < sched_ctrl->dl_lc_num; idx++) {
|
||||
if (sched_ctrl->dl_lc_ids[idx] == *rlc_bearer2release_list->list.array[i]) {
|
||||
const int lcid = *rlc_bearer2release_list->list.array[i];
|
||||
if (sched_ctrl->dl_lc_ids[idx] == lcid) {
|
||||
const int remaining_lcs = sched_ctrl->dl_lc_num - idx - 1;
|
||||
memmove(&sched_ctrl->dl_lc_ids[idx], &sched_ctrl->dl_lc_ids[idx + 1], sizeof(sched_ctrl->dl_lc_ids[idx]) * remaining_lcs);
|
||||
sched_ctrl->dl_lc_num--;
|
||||
LOG_I(NR_MAC, "remove LCID %d (%s %d)\n", lcid, lcid < 4 ? "SRB" : "DRB", lcid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -75,7 +77,7 @@ static void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddMo
|
||||
if (rlc_bearer2add_list) {
|
||||
// keep lcids
|
||||
for (int i = 0; i < rlc_bearer2add_list->list.count; i++) {
|
||||
const int lcid = rlc_bearer2add_list->list.array[i]->logicalChannelIdentity;
|
||||
const uint8_t lcid = rlc_bearer2add_list->list.array[i]->logicalChannelIdentity;
|
||||
bool found = false;
|
||||
for (int idx = 0; idx < sched_ctrl->dl_lc_num; idx++) {
|
||||
if (sched_ctrl->dl_lc_ids[idx] == lcid) {
|
||||
@@ -85,9 +87,21 @@ static void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddMo
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
/* we assume that the first two are SRB bearers, and we add before
|
||||
* other DRB */
|
||||
uint8_t i = 0;
|
||||
/* go beyond all SRBs */
|
||||
while (i < sched_ctrl->dl_lc_num && sched_ctrl->dl_lc_ids[i] < 4)
|
||||
i++;
|
||||
uint8_t remaining_lcs = sched_ctrl->dl_lc_num - i;
|
||||
memmove(&sched_ctrl->dl_lc_ids[i + 1], &sched_ctrl->dl_lc_ids[i], sizeof(sched_ctrl->dl_lc_ids[i]) * remaining_lcs);
|
||||
sched_ctrl->dl_lc_ids[i] = lcid;
|
||||
|
||||
sched_ctrl->dl_lc_num++;
|
||||
sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num - 1] = lcid;
|
||||
LOG_D(NR_MAC, "Adding LCID %d (%s %d)\n", lcid, lcid < 4 ? "SRB" : "DRB", lcid);
|
||||
|
||||
LOG_I(NR_MAC, "Adding LCID %d (%s %d)\n", lcid, lcid < 4 ? "SRB" : "DRB", lcid);
|
||||
for (i = 0; i < sched_ctrl->dl_lc_num; ++i)
|
||||
LOG_E(NR_MAC, "bearer %d LCID %s %d\n", i, lcid < 4 ? "SRB" : "DRB", sched_ctrl->dl_lc_ids[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
/* rlc */
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include "openair2/RRC/NR/nr_rrc_defs.h"
|
||||
|
||||
#include <executables/softmodem-common.h>
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
@@ -329,7 +329,7 @@ static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_fram
|
||||
const int lcid = sched_ctrl->dl_lc_ids[i];
|
||||
const uint16_t rnti = UE->rnti;
|
||||
LOG_D(NR_MAC, "In %s: UE %x: LCID %d\n", __FUNCTION__, rnti, lcid);
|
||||
if (lcid == DL_SCH_LCID_DTCH && sched_ctrl->rrc_processing_timer > 0) {
|
||||
if (lcid >= DL_SCH_LCID_DTCH && sched_ctrl->rrc_processing_timer > 0) {
|
||||
continue;
|
||||
}
|
||||
start_meas(&RC.nrmac[module_id]->rlc_status_ind);
|
||||
@@ -626,7 +626,11 @@ static void pf_dl(module_id_t module_id,
|
||||
/* Calculate coeff */
|
||||
const NR_bler_options_t *bo = &mac->dl_bler;
|
||||
const int max_mcs_table = current_BWP->mcsTableIdx == 1 ? 27 : 28;
|
||||
const int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table);
|
||||
int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table);
|
||||
|
||||
if(max_mcs > 10)
|
||||
max_mcs = 10;
|
||||
|
||||
if (bo->harq_round_max == 1)
|
||||
sched_pdsch->mcs = max_mcs;
|
||||
else
|
||||
|
||||
@@ -32,6 +32,14 @@
|
||||
#include "openair2/RRC/NR/nr_rrc_proto.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
|
||||
|
||||
|
||||
/* from OAI */
|
||||
#include "oai_asn1.h"
|
||||
#include "nr_pdcp_oai_api.h"
|
||||
@@ -932,6 +940,8 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
|
||||
{
|
||||
if (drb2add_list != NULL) {
|
||||
for (int i = 0; i < drb2add_list->list.count; i++) {
|
||||
// assert(drb2add_list->list.count == rlc_bearer2add_list->list.count );
|
||||
|
||||
add_drb(enb_flag, rntiMaybeUEid, reestablish_ue_id, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, kUPint);
|
||||
}
|
||||
} else
|
||||
|
||||
@@ -37,11 +37,11 @@ static void nr_rlc_entity_get_stats(
|
||||
{
|
||||
// printf("Stats from the RLC entity asked\n");
|
||||
*out = entity->stats;
|
||||
if (entity->avg_time_is_on)
|
||||
// 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());
|
||||
else
|
||||
out->txsdu_avg_time_to_tx = 0;
|
||||
// else
|
||||
// out->txsdu_avg_time_to_tx = 0;
|
||||
}
|
||||
|
||||
nr_rlc_entity_t *new_nr_rlc_entity_am(
|
||||
|
||||
@@ -23,81 +23,13 @@
|
||||
#define _NR_RLC_ENTITY_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "openair2/RRC/NR/rrc_gNB_radio_bearers.h"
|
||||
#include "../../../openair2/RRC/NR/rrc_gNB_radio_bearers.h"
|
||||
#include "../../../openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
|
||||
#include "common/utils/time_stat.h"
|
||||
|
||||
#define NR_SDU_MAX 16000 /* max NR PDCP SDU size is 9000, let's take more */
|
||||
|
||||
typedef enum {
|
||||
NR_RLC_AM,
|
||||
NR_RLC_UM,
|
||||
NR_RLC_TM,
|
||||
} nr_rlc_mode_t;
|
||||
|
||||
typedef struct {
|
||||
nr_rlc_mode_t mode; /* AM, UM, or TM */
|
||||
|
||||
/* PDU stats */
|
||||
/* 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_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) */
|
||||
uint32_t txpdu_retx_bytes; /* aggregated amount of bytes to be re-transmitted (only applicable to RLC AM) */
|
||||
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) */
|
||||
/* txbuf_wd_ms: the time window for which the txbuf occupancy value is obtained - NOT IMPLEMENTED */
|
||||
|
||||
/* RX */
|
||||
uint32_t rxpdu_pkts; /* aggregated number of received RLC PDUs */
|
||||
uint32_t rxpdu_bytes; /* amount of bytes received by the RLC */
|
||||
uint32_t rxpdu_dup_pkts; /* aggregated number of duplicate packets */
|
||||
uint32_t rxpdu_dup_bytes; /* aggregated amount of duplicated bytes */
|
||||
uint32_t rxpdu_dd_pkts; /* aggregated number of rx packets dropped or discarded by RLC */
|
||||
uint32_t rxpdu_dd_bytes; /* aggregated amount of rx bytes dropped or discarded by RLC */
|
||||
uint32_t rxpdu_ow_pkts; /* aggregated number of out of window received RLC pdu */
|
||||
uint32_t rxpdu_ow_bytes; /* aggregated number of out of window bytes received RLC pdu */
|
||||
uint32_t rxpdu_status_pkts; /* aggregated number of rx status pdus/pkts (only applicable to RLC AM) */
|
||||
uint32_t rxpdu_status_bytes; /* aggregated amount of rx status bytes (only applicable to RLC AM) */
|
||||
/* 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) */
|
||||
|
||||
/* SDU stats */
|
||||
/* TX */
|
||||
uint32_t txsdu_pkts; /* number of SDUs delivered */
|
||||
uint32_t txsdu_bytes; /* number of bytes of SDUs delivered */
|
||||
|
||||
/* RX */
|
||||
uint32_t rxsdu_pkts; /* number of SDUs received */
|
||||
uint32_t rxsdu_bytes; /* number of bytes of SDUs received */
|
||||
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 {
|
||||
int status_size;
|
||||
int tx_size;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "nr_rlc_pdu.h"
|
||||
|
||||
@@ -480,6 +481,12 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size)
|
||||
if (pdu_header_size + 1 > size)
|
||||
return 0;
|
||||
|
||||
// mir Save BW when using TCP Cubic
|
||||
if(pdu_header_size + sdu->size > size ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
entity->tx_list = entity->tx_list->next;
|
||||
if (entity->tx_list == NULL)
|
||||
entity->tx_end = NULL;
|
||||
@@ -496,8 +503,11 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size)
|
||||
if (pdu_size > size) {
|
||||
nr_rlc_sdu_segment_t *next_sdu;
|
||||
next_sdu = resegment(sdu, entity, size);
|
||||
if (next_sdu == NULL)
|
||||
printf("resegmenting \n");
|
||||
if (next_sdu == NULL){
|
||||
printf("next_sdu == NULL \n");
|
||||
return 0;
|
||||
}
|
||||
/* put the second SDU back at the head of the TX list */
|
||||
next_sdu->next = entity->tx_list;
|
||||
entity->tx_list = next_sdu;
|
||||
@@ -511,11 +521,20 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size)
|
||||
}
|
||||
|
||||
/* update tx_next if the SDU is an SDU segment and is the last */
|
||||
if (!sdu->is_first && sdu->is_last)
|
||||
if (!sdu->is_first && sdu->is_last){
|
||||
printf("Updating the SN \n");
|
||||
entity->tx_next = (entity->tx_next + 1) % entity->sn_modulus;
|
||||
}
|
||||
|
||||
ret = serialize_sdu(entity, sdu, buffer, size);
|
||||
|
||||
//uint8_t* a = (uint8_t*) buffer;
|
||||
//uint8_t* b = (uint8_t*)(buffer+1);
|
||||
//uint8_t* c = (uint8_t*)(buffer+2);
|
||||
//uint8_t* d = (uint8_t*)(buffer+3);
|
||||
|
||||
//printf("a %u b %u c %u d %u \n",*a, *b, *c, *d);
|
||||
|
||||
entity->tx_size -= sdu->size;
|
||||
|
||||
entity->common.stats.txpdu_pkts++;
|
||||
@@ -525,8 +544,11 @@ static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size)
|
||||
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;
|
||||
// sdu->sdu->time_of_arrival = 0;
|
||||
time_average_add(entity->common.txsdu_avg_time_to_tx, time_now, waited_time);
|
||||
|
||||
// double av = time_average_get_average(entity->common.txsdu_avg_time_to_tx, time_average_now() );
|
||||
// printf("Average time in the RLC SDU %lf us \n", av);
|
||||
}
|
||||
|
||||
nr_rlc_free_sdu_segment(sdu);
|
||||
@@ -555,6 +577,14 @@ int nr_rlc_entity_um_generate_pdu(nr_rlc_entity_t *_entity,
|
||||
return generate_tx_pdu(entity, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
double nr_rlc_entity_um_sojourn_time(nr_rlc_entity_um_t const *entity)
|
||||
{
|
||||
double const av = time_average_get_average(entity->common.txsdu_avg_time_to_tx, time_average_now() );
|
||||
return av;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* SDU RX functions */
|
||||
/*************************************************************************/
|
||||
@@ -595,8 +625,8 @@ void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity,
|
||||
entity->common.bstatus.tx_size += compute_pdu_header_size(entity, sdu)
|
||||
+ sdu->size;
|
||||
|
||||
if (entity->common.avg_time_is_on)
|
||||
sdu->sdu->time_of_arrival = time_average_now();
|
||||
// if (entity->common.avg_time_is_on)
|
||||
sdu->sdu->time_of_arrival = time_average_now();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
@@ -77,4 +77,6 @@ void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity);
|
||||
void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity);
|
||||
int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *entity);
|
||||
|
||||
double nr_rlc_entity_um_sojourn_time(nr_rlc_entity_um_t const *entity);
|
||||
|
||||
#endif /* _NR_RLC_ENTITY_UM_H_ */
|
||||
|
||||
@@ -1048,7 +1048,7 @@ void nr_rlc_activate_avg_time_to_tx(
|
||||
}
|
||||
|
||||
/* returns false in case of error, true if everything ok */
|
||||
const bool nr_rlc_get_statistics(
|
||||
bool nr_rlc_get_statistics(
|
||||
int rnti,
|
||||
int srb_flag,
|
||||
int rb_id,
|
||||
|
||||
@@ -29,15 +29,100 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "NR_RLC-BearerConfig.h"
|
||||
#include "NR_RLC-Config.h"
|
||||
#include "NR_LogicalChannelIdentity.h"
|
||||
#include "NR_RadioBearerConfig.h"
|
||||
#include "NR_CellGroupConfig.h"
|
||||
#include "openair2/RRC/NR/nr_rrc_proto.h"
|
||||
#ifndef NR_RLC_OAI_API_H_MIR
|
||||
#define NR_RLC_OAI_API_H_MIR
|
||||
|
||||
struct NR_RLC_Config;
|
||||
struct NR_LogicalChannelConfig;
|
||||
//#include "../../../openair2/RRC/NR/nr_rrc_proto.h"
|
||||
|
||||
//#include "openair2/../cmake_targets/ran_build/build/openair2/RRC/NR/MESSAGES/NR_RLC-BearerConfig.h"
|
||||
//#include "NR_RLC-Config.h"
|
||||
//#include "NR_LogicalChannelIdentity.h"
|
||||
//#include "NR_RadioBearerConfig.h"
|
||||
//#include "NR_CellGroupConfig.h"
|
||||
|
||||
|
||||
//#include "openair2/LAYER2/nr_rlc/nr_rlc_entity.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
|
||||
typedef int32_t sdu_size_t;
|
||||
typedef unsigned int logical_chan_id_t;
|
||||
typedef uint16_t rnti_t;
|
||||
|
||||
typedef enum {
|
||||
NR_RLC_AM,
|
||||
NR_RLC_UM,
|
||||
NR_RLC_TM,
|
||||
} nr_rlc_mode_t;
|
||||
|
||||
typedef struct {
|
||||
nr_rlc_mode_t mode; /* AM, UM, or TM */
|
||||
|
||||
/* PDU stats */
|
||||
/* 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_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) */
|
||||
uint32_t txpdu_retx_bytes; /* aggregated amount of bytes to be re-transmitted (only applicable to RLC AM) */
|
||||
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) */
|
||||
/* txbuf_wd_ms: the time window for which the txbuf occupancy value is obtained - NOT IMPLEMENTED */
|
||||
|
||||
/* RX */
|
||||
uint32_t rxpdu_pkts; /* aggregated number of received RLC PDUs */
|
||||
uint32_t rxpdu_bytes; /* amount of bytes received by the RLC */
|
||||
uint32_t rxpdu_dup_pkts; /* aggregated number of duplicate packets */
|
||||
uint32_t rxpdu_dup_bytes; /* aggregated amount of duplicated bytes */
|
||||
uint32_t rxpdu_dd_pkts; /* aggregated number of rx packets dropped or discarded by RLC */
|
||||
uint32_t rxpdu_dd_bytes; /* aggregated amount of rx bytes dropped or discarded by RLC */
|
||||
uint32_t rxpdu_ow_pkts; /* aggregated number of out of window received RLC pdu */
|
||||
uint32_t rxpdu_ow_bytes; /* aggregated number of out of window bytes received RLC pdu */
|
||||
uint32_t rxpdu_status_pkts; /* aggregated number of rx status pdus/pkts (only applicable to RLC AM) */
|
||||
uint32_t rxpdu_status_bytes; /* aggregated amount of rx status bytes (only applicable to RLC AM) */
|
||||
/* 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) */
|
||||
|
||||
/* SDU stats */
|
||||
/* TX */
|
||||
uint32_t txsdu_pkts; /* number of SDUs delivered */
|
||||
uint32_t txsdu_bytes; /* number of bytes of SDUs delivered */
|
||||
|
||||
/* RX */
|
||||
uint32_t rxsdu_pkts; /* number of SDUs received */
|
||||
uint32_t rxsdu_bytes; /* number of bytes of SDUs received */
|
||||
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;
|
||||
|
||||
//struct NR_RLC_Config;
|
||||
//struct NR_LogicalChannelConfig;
|
||||
typedef struct NR_RLC_BearerConfig NR_RLC_BearerConfig_t;
|
||||
|
||||
void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
|
||||
void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig);
|
||||
@@ -63,3 +148,10 @@ 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));
|
||||
bool nr_rlc_get_statistics(
|
||||
int rnti,
|
||||
int srb_flag,
|
||||
int rb_id,
|
||||
nr_rlc_statistics_t *out);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -803,7 +803,7 @@ int16_t do_RRCReconfiguration(
|
||||
|
||||
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie;
|
||||
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
if (true) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,8 +100,9 @@ void CU_update_UP_DL_tunnel(e1ap_bearer_setup_req_t *const req, instance_t insta
|
||||
}
|
||||
}
|
||||
|
||||
static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
|
||||
rrc_gNB_ue_context_t *ue_context_p,
|
||||
static
|
||||
int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
|
||||
rrc_gNB_ue_context_t *ue_context_p,
|
||||
e1ap_bearer_setup_req_t *const req,
|
||||
NR_DRB_ToAddModList_t *DRB_configList,
|
||||
instance_t instance)
|
||||
@@ -110,6 +111,7 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
|
||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
LOG_W(NR_RRC, "recreate existing tunnels, while adding new ones\n");
|
||||
printf("UE->nb_of_pdusessions %d\n ", UE->nb_of_pdusessions );
|
||||
for (int i = 0; i < UE->nb_of_pdusessions; i++) {
|
||||
rrc_pdu_session_param_t *pdu = UE->pduSession + i;
|
||||
create_tunnel_req.pdusession_id[i] = pdu->param.pdusession_id;
|
||||
@@ -122,14 +124,14 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
|
||||
create_tunnel_req.num_tunnels = UE->nb_of_pdusessions;
|
||||
create_tunnel_req.ue_id = UE->rnti;
|
||||
int ret = gtpv1u_create_ngu_tunnel(getCxtE1(instance)->gtpInstN3,
|
||||
&create_tunnel_req,
|
||||
&create_tunnel_resp,
|
||||
nr_pdcp_data_req_drb,
|
||||
sdap_data_req);
|
||||
&create_tunnel_req,
|
||||
&create_tunnel_resp,
|
||||
nr_pdcp_data_req_drb,
|
||||
sdap_data_req);
|
||||
|
||||
if (ret != 0) {
|
||||
LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE rnti %ld\n",
|
||||
create_tunnel_req.ue_id);
|
||||
create_tunnel_req.ue_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -152,38 +154,81 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p,
|
||||
|
||||
LOG_D(NR_RRC, "Configuring PDCP DRBs for UE %x\n", UE->rnti);
|
||||
nr_pdcp_add_drbs(ctxt_p->enb_flag,
|
||||
ctxt_p->rntiMaybeUEid,
|
||||
0,
|
||||
DRB_configList,
|
||||
(UE->integrity_algorithm << 4) | UE->ciphering_algorithm,
|
||||
kUPenc,
|
||||
kUPint,
|
||||
get_softmodem_params()->sa ? UE->masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
ctxt_p->rntiMaybeUEid,
|
||||
0,
|
||||
DRB_configList,
|
||||
(UE->integrity_algorithm << 4) | UE->ciphering_algorithm,
|
||||
kUPenc,
|
||||
kUPint,
|
||||
get_softmodem_params()->sa ? UE->masterCellGroup->rlc_BearerToAddModList : NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid)
|
||||
/*
|
||||
static NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, NR_SRB_ToAddModList_t *SRB_configList, uint8_t xid)
|
||||
{
|
||||
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
|
||||
|
||||
SRB_configList2 = &ue->SRB_configList2[xid];
|
||||
if (*SRB_configList2 == NULL) {
|
||||
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
|
||||
NR_SRB_ToAddMod_t *SRB2_config = CALLOC(1, sizeof(*SRB2_config));
|
||||
SRB2_config->srb_Identity = 2;
|
||||
asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
|
||||
asn1cSeqAdd(&SRB_configList->list, SRB2_config);
|
||||
}
|
||||
|
||||
return SRB_configList2;
|
||||
}
|
||||
*/
|
||||
|
||||
static
|
||||
void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid)
|
||||
{
|
||||
/*
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti);
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
|
||||
|
||||
fill_DRB_configList(&ctxt, ue_context_p, xid);
|
||||
e1ap_bearer_setup_resp_t resp = {0};
|
||||
resp.numPDUSessions = req->numPDUSessions;
|
||||
for (int i = 0; i < resp.numPDUSessions; ++i) {
|
||||
resp.pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup;
|
||||
for (int j = 0; j < req->pduSession[i].numDRB2Setup; j++) {
|
||||
DRB_nGRAN_to_setup_t *req_drb = req->pduSession[i].DRBnGRanList + j;
|
||||
DRB_nGRAN_setup_t *resp_drb = resp.pduSession[i].DRBnGRanList + j;
|
||||
resp_drb->id = req_drb->id;
|
||||
resp_drb->numQosFlowSetup = req_drb->numQosFlow2Setup;
|
||||
for (int k = 0; k < resp_drb->numQosFlowSetup; k++)
|
||||
resp_drb->qosFlows[k].id = req_drb->qosFlows[k].id;
|
||||
}
|
||||
// mir
|
||||
if(UE->DRB_configList != NULL && get_softmodem_params()->sa){
|
||||
assert(UE->DRB_configList->list.count == UE->masterCellGroup->rlc_BearerToAddModList->list.count);
|
||||
}
|
||||
|
||||
fill_DRB_configList(&ctxt, ue_context_p, xid);
|
||||
|
||||
// mir
|
||||
if(UE->DRB_configList != NULL && get_softmodem_params()->sa){
|
||||
assert(UE->DRB_configList->list.count == UE->masterCellGroup->rlc_BearerToAddModList->list.count);
|
||||
}
|
||||
|
||||
*/
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti);
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
protocol_ctxt_t ctxt = {0};
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
|
||||
|
||||
fill_DRB_configList(&ctxt, ue_context_p, xid);
|
||||
e1ap_bearer_setup_resp_t resp = {0};
|
||||
resp.numPDUSessions = req->numPDUSessions;
|
||||
for (int i = 0; i < resp.numPDUSessions; ++i) {
|
||||
resp.pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup;
|
||||
for (int j = 0; j < req->pduSession[i].numDRB2Setup; j++) {
|
||||
DRB_nGRAN_to_setup_t *req_drb = req->pduSession[i].DRBnGRanList + j;
|
||||
DRB_nGRAN_setup_t *resp_drb = resp.pduSession[i].DRBnGRanList + j;
|
||||
resp_drb->id = req_drb->id;
|
||||
resp_drb->numQosFlowSetup = req_drb->numQosFlow2Setup;
|
||||
for (int k = 0; k < resp_drb->numQosFlowSetup; k++)
|
||||
resp_drb->qosFlows[k].id = req_drb->qosFlows[k].id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||
// GTP tunnel for UL
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "COMMON/mac_rrc_primitives.h"
|
||||
#include "RRC/NR/MESSAGES/asn1_msg.h"
|
||||
#include "openair2/E1AP/e1ap_asnc.h"
|
||||
|
||||
#include "NR_BCCH-BCH-Message.h"
|
||||
#include "NR_UL-DCCH-Message.h"
|
||||
@@ -1036,20 +1037,21 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co
|
||||
/* Refresh SRBs/DRBs */
|
||||
LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_p->rnti);
|
||||
ue_id_t reestablish_ue_id = 0;
|
||||
if (DRB_configList && DRB_configList->list.array[0]->reestablishPDCP && *DRB_configList->list.array[0]->reestablishPDCP == NR_DRB_ToAddMod__reestablishPDCP_true) {
|
||||
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
|
||||
nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[i];
|
||||
if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) {
|
||||
ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++;
|
||||
reestablish_ue_id = nr_reestablish_rnti_map[i].c_rnti;
|
||||
LOG_D(NR_RRC, "Removing reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti);
|
||||
// clear current C-RNTI from map
|
||||
nr_reestablish_rnti_map->ue_id = 0;
|
||||
nr_reestablish_rnti_map->c_rnti = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// we don't consider Reestablishment right now, uncomment to prevent segfault
|
||||
//if (DRB_configList && DRB_configList->list.array[0]->reestablishPDCP && *DRB_configList->list.array[0]->reestablishPDCP == NR_DRB_ToAddMod__reestablishPDCP_true) {
|
||||
// for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
|
||||
// nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[i];
|
||||
// if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) {
|
||||
// ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++;
|
||||
// reestablish_ue_id = nr_reestablish_rnti_map[i].c_rnti;
|
||||
// LOG_D(NR_RRC, "Removing reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti);
|
||||
// // clear current C-RNTI from map
|
||||
// nr_reestablish_rnti_map->ue_id = 0;
|
||||
// nr_reestablish_rnti_map->c_rnti = 0;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false);
|
||||
|
||||
nr_pdcp_add_srbs(ctxt_pP->enb_flag,
|
||||
@@ -2979,6 +2981,93 @@ rrc_gNB_generate_RRCRelease(
|
||||
/* UE will be freed after UE context release complete */
|
||||
}
|
||||
|
||||
void rrc_gNB_trigger_new_bearer(int rnti)
|
||||
{
|
||||
/* get RRC and UE */
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, rnti);
|
||||
if (ue_context_p == NULL) {
|
||||
LOG_E(RRC, "unknown UE RNTI %04x\n", rnti);
|
||||
return;
|
||||
}
|
||||
gNB_RRC_UE_t *ue = &ue_context_p->ue_context;
|
||||
|
||||
/* get the existing PDU sessoin */
|
||||
if (ue->nb_of_pdusessions < 1) {
|
||||
LOG_E(RRC, "no PDU session set up yet, cannot create additional bearer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ue->established_drbs[0].status != DRB_INACTIVE
|
||||
&& ue->established_drbs[1].status != DRB_INACTIVE) {
|
||||
LOG_E(RRC, "already have two established bearers, aborting\n");
|
||||
return;
|
||||
}
|
||||
|
||||
e1ap_bearer_setup_req_t bearer_req = {0};
|
||||
bearer_req.gNB_cu_cp_ue_id = ue->gNB_ue_ngap_id;
|
||||
bearer_req.rnti = ue->rnti;
|
||||
bearer_req.cipheringAlgorithm = ue->ciphering_algorithm;
|
||||
memcpy(bearer_req.encryptionKey, ue->kgnb, sizeof(ue->kgnb));
|
||||
bearer_req.integrityProtectionAlgorithm = ue->integrity_algorithm;
|
||||
memcpy(bearer_req.integrityProtectionKey, ue->kgnb, sizeof(ue->kgnb));
|
||||
bearer_req.ueDlAggMaxBitRate = 10000; /* probably does not matter */
|
||||
|
||||
pdu_session_to_setup_t *pdu = &bearer_req.pduSession[0];
|
||||
//bearer_req.numPDUSessions++;
|
||||
bearer_req.numPDUSessions = 1;
|
||||
//pdu->sessionId = session->pdusession_id;
|
||||
//pdu->sst = msg->allowed_nssai[i].sST;
|
||||
//pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed;
|
||||
|
||||
//pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed;
|
||||
//pdu->teId = session->gtp_teid;
|
||||
pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding
|
||||
DRB_nGRAN_to_setup_t *drb = &pdu->DRBnGRanList[0];
|
||||
int drb_id = 2;
|
||||
drb->id = drb_id;
|
||||
|
||||
drb->defaultDRB = E1AP_DefaultDRB_false;
|
||||
drb->sDAP_Header_UL = !(rrc->configuration.enable_sdap);
|
||||
drb->sDAP_Header_DL = !(rrc->configuration.enable_sdap);
|
||||
|
||||
drb->pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_18;
|
||||
drb->pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_18;
|
||||
|
||||
drb->discardTimer = E1AP_DiscardTimer_infinity;
|
||||
drb->reorderingTimer = E1AP_T_Reordering_ms0;
|
||||
|
||||
drb->rLC_Mode = E1AP_RLC_Mode_rlc_am;
|
||||
|
||||
drb->numCellGroups = 1; // assume one cell group associated with a DRB
|
||||
|
||||
for (int k=0; k < drb->numCellGroups; k++) {
|
||||
cell_group_t *cellGroup = drb->cellGroupList + k;
|
||||
cellGroup->id = 0; // MCG
|
||||
}
|
||||
|
||||
int xid = rrc_gNB_get_next_transaction_identifier(0);
|
||||
/* GIGANTIC HACK: DRBs would be added internally in fill_DRB_configList(),
|
||||
* but it checks and will skip our request because the PDU session is up.
|
||||
* Below, simply add the new bearer to DRB_configList so the reconfiguration
|
||||
* will have all bearers */
|
||||
generateDRB(ue,
|
||||
drb_id,
|
||||
&ue->pduSession[0],
|
||||
rrc->configuration.enable_sdap,
|
||||
rrc->security.do_drb_integrity,
|
||||
rrc->security.do_drb_ciphering);
|
||||
NR_DRB_ToAddMod_t *DRB_config = generateDRB_ASN1(&ue->established_drbs[drb_id - 1]);
|
||||
asn1cSeqAdd(&ue->DRB_configList->list, DRB_config);
|
||||
//asn1cSeqAdd(&ue->DRB_configList2[xid]->list, DRB_config);
|
||||
|
||||
/* associate the new bearer to it */
|
||||
ue->xids[xid] = RRC_PDUSESSION_MODIFY;
|
||||
ue->pduSession[0].xid = xid; // hack: fake xid for ongoing PDU session
|
||||
LOG_W(RRC, "trigger new bearer %ld for UE %04x xid %d\n", drb->id, ue->rnti, xid);
|
||||
rrc->cucp_cuup.bearer_context_setup(&bearer_req, 0, xid);
|
||||
}
|
||||
|
||||
int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id){
|
||||
const unsigned int Ttab[4] = {32,64,128,256};
|
||||
uint8_t Tc;
|
||||
|
||||
@@ -731,7 +731,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
|
||||
{
|
||||
protocol_ctxt_t ctxt={0};
|
||||
|
||||
ngap_pdusession_setup_req_t* msg=&NGAP_PDUSESSION_SETUP_REQ(msg_p);
|
||||
ngap_pdusession_setup_req_t* msg = &NGAP_PDUSESSION_SETUP_REQ(msg_p);
|
||||
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], msg->gNB_ue_ngap_id);
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
|
||||
@@ -777,7 +777,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
|
||||
pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed;
|
||||
pdu->teId = session->gtp_teid;
|
||||
memcpy(&pdu->tlAddress, session->upf_addr.buffer, 4); // Fixme: dirty IPv4 target
|
||||
pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding
|
||||
pdu->numDRB2Setup = 2; // One DRB per PDU Session. TODO: Remove hardcoding
|
||||
for (int j=0; j < pdu->numDRB2Setup; j++) {
|
||||
DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j;
|
||||
|
||||
|
||||
@@ -25,6 +25,16 @@
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h"
|
||||
|
||||
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
@@ -56,6 +66,57 @@ void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_s
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MIR_FLAG
|
||||
|
||||
int get_single_ue_rnti(void)
|
||||
{
|
||||
NR_UE_info_t *ue = NULL;
|
||||
UE_iterator(RC.nrmac[0]->UE_info.list, it) {
|
||||
if (it && ue)
|
||||
return -1;
|
||||
if (it)
|
||||
ue = it;
|
||||
}
|
||||
if (!ue)
|
||||
return -1;
|
||||
|
||||
// verify it exists in RRC as well
|
||||
rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], ue->rnti);
|
||||
if (!rrcue)
|
||||
return -1;
|
||||
|
||||
return ue->rnti;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//static_assert(0!=0, "Compiled");
|
||||
|
||||
static
|
||||
pthread_once_t once_bearer = PTHREAD_ONCE_INIT;
|
||||
// Forward declaration. Forget my sins.
|
||||
void rrc_gNB_trigger_new_bearer(int rnti);
|
||||
|
||||
static
|
||||
uint64_t cnt = 0;
|
||||
|
||||
static
|
||||
void create_bearer(void)
|
||||
{
|
||||
int const rnti = get_single_ue_rnti();
|
||||
assert(rnti > 0 && "Error finding the rnti");
|
||||
// verify it exists in RRC as well
|
||||
rrc_gNB_ue_context_t *rrcue = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], rnti);
|
||||
if(!rrcue)
|
||||
printf("Could not find the UE in RRC \n");
|
||||
// assert(!rrcue && "Could not find UE");
|
||||
|
||||
rrc_gNB_trigger_new_bearer(rnti);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
|
||||
protocol_ctxt_t *ctxt_p,
|
||||
const srb_flag_t srb_flag,
|
||||
@@ -92,7 +153,25 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity,
|
||||
|
||||
if(!pdcp_ent_has_sdap){
|
||||
LOG_D(SDAP, "TX - DRB ID: %ld does not have SDAP\n", entity->qfi2drb_table[qfi].drb_id);
|
||||
ret = nr_pdcp_data_req_drb(ctxt_p,
|
||||
|
||||
#ifdef MIR_FLAG
|
||||
// mir
|
||||
// Naive L4/L3 packet classifier
|
||||
struct iphdr* hdr = (struct iphdr*)sdu_buffer;
|
||||
|
||||
if(hdr->protocol == IPPROTO_TCP){
|
||||
printf("TCP packet detected \n");
|
||||
} else if(hdr->protocol == IPPROTO_UDP){
|
||||
printf("UDP packet detected \n");
|
||||
} else if(hdr->protocol == IPPROTO_ICMP){
|
||||
printf("Ping packet detected \n");
|
||||
pthread_once(&once_bearer, create_bearer);
|
||||
sdap_drb_id += 1; //cnt%2;
|
||||
//cnt++;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = nr_pdcp_data_req_drb(ctxt_p,
|
||||
srb_flag,
|
||||
sdap_drb_id,
|
||||
mui,
|
||||
|
||||
@@ -170,4 +170,8 @@ nr_sdap_entity_t *nr_sdap_get_entity(ue_id_t ue_id, int pdusession_id);
|
||||
/* Entity Handling Related Functions */
|
||||
void delete_nr_sdap_entity(ue_id_t ue_id);
|
||||
|
||||
|
||||
// mir hack
|
||||
int get_single_ue_rnti(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,7 @@ gNBs =
|
||||
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) });
|
||||
|
||||
nr_cellid = 12345678L;
|
||||
min_rxtxtime=6;
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
@@ -266,3 +267,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