NVIDIA Aerial Integration

- Aerial config file
- Changes for ARC1.1. Change config file to max MCS 25. Fixed pdu size errors.
- Remove taskset from Dockerfile.gNB.aerial.ubuntu20 after changing isolated CPUs
- removed the USRP from Docker file

Co-authored-by: Florian Kaltenberger <florian.kaltenberger@eurecom.fr>
Co-authored-by: Fredrik Molander <fmolander@nvidia.com>
Co-authored-by: Reem Bahsoun <reem.bahsoun@openairinterface.org>
This commit is contained in:
Rúben Soares da Silva
2024-03-08 15:53:42 +01:00
committed by Robert Schmidt
co-authored by Florian Kaltenberger Fredrik Molander Reem Bahsoun
parent ed65b52c3c
commit 8150a47ba5
41 changed files with 4237 additions and 179 deletions
+2 -1
View File
@@ -726,7 +726,6 @@ set(SCHED_SRC_NR_UE
add_library(SCHED_NR_UE_LIB ${SCHED_SRC_NR_UE}) add_library(SCHED_NR_UE_LIB ${SCHED_SRC_NR_UE})
target_link_libraries(SCHED_NR_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) target_link_libraries(SCHED_NR_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
# nFAPI # nFAPI
################################# #################################
set(NFAPI_COMMON_SRC set(NFAPI_COMMON_SRC
@@ -2066,6 +2065,8 @@ add_executable(nr-softmodem
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c ${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
) )
include(${OPENAIR_DIR}/nfapi/CMakeLists.txt)
target_link_libraries(nr-softmodem PRIVATE target_link_libraries(nr-softmodem PRIVATE
-Wl,--start-group -Wl,--start-group
UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECURITY UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECURITY
+5 -1
View File
@@ -93,7 +93,7 @@ Options:
--UE-gen-nvram [output path] --UE-gen-nvram [output path]
Specify gen_nvram_path (default \"$gen_nvram_path\") Specify gen_nvram_path (default \"$gen_nvram_path\")
-w | --hardware -w | --hardware
USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, None (Default) USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, AERIAL, None (Default)
Adds this RF board support (in external packages installation and in compilation) Adds this RF board support (in external packages installation and in compilation)
-t | --transport -t | --transport
Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g
@@ -289,6 +289,10 @@ function main() {
TARGET_LIST="$TARGET_LIST aw2sori_transpro" TARGET_LIST="$TARGET_LIST aw2sori_transpro"
CMAKE_CMD="$CMAKE_CMD -DOAI_$2=ON" CMAKE_CMD="$CMAKE_CMD -DOAI_$2=ON"
;; ;;
"AERIAL"|"Aerial"|"aerial")
HW="OAI_AERIAL"
CMAKE_CMD="$CMAKE_CMD -DOAI_AERIAL=ON"
;;
"None") "None")
;; ;;
*) *)
@@ -0,0 +1,76 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 04cfa53..6eef6d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -42,6 +42,8 @@ OPTION(DOCA_GPU_DPDK "Enable DOCA GPUNetIO" ON)
OPTION(NVIPC_DOCA_ENABLE "Build libnvipc.so with DOCA" ON)
OPTION(NVIPC_DOCA_GPUNETIO "Use DOCA gpunetio in DOCA GPU DMA" OFF)
+project(gt_common_libs)
+
find_package(PkgConfig REQUIRED)
# Disable NVIPC_DOCA_ENABLE if DOCA version < 2
diff --git a/nvIPC/CMakeLists.txt b/nvIPC/CMakeLists.txt
index 633bbb7..dad7a7a 100644
--- a/nvIPC/CMakeLists.txt
+++ b/nvIPC/CMakeLists.txt
@@ -19,7 +19,7 @@
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+include(GNUInstallDirs)
# lib: nvipc
set(SOURCES configs/nv_ipc_config.c
configs/nv_ipc_yaml_parser.cpp
@@ -68,6 +68,8 @@ target_include_directories(nvipc PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE
target_include_directories(nvipc PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/cuda>)
target_include_directories(nvipc PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/gpudata>)
+set_target_properties(nvipc PROPERTIES PUBLIC_HEADER $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+
target_compile_options(nvipc PRIVATE ${AERIAL_ARCH_TUNE_FLAGS})
if(NVIPC_DPDK_ENABLE OR NVIPC_DOCA_GPUNETIO)
@@ -120,4 +122,8 @@ else()
target_link_libraries(nvipc PUBLIC rt -pthread nvlog)
endif()
+install(TARGETS nvipc
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/..)
+
add_subdirectory(tests)
diff --git a/nvlog/CMakeLists.txt b/nvlog/CMakeLists.txt
index 7b65242..c0c5080 100644
--- a/nvlog/CMakeLists.txt
+++ b/nvlog/CMakeLists.txt
@@ -20,6 +20,8 @@
# STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+include(GNUInstallDirs)
+
if(NOT CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g")
@@ -42,6 +44,8 @@ target_include_directories(nvlog PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../extern
target_include_directories(nvlog PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../external/fmtlog_flat)
target_link_libraries(nvlog rt -pthread yaml fmtlog-shared fmt::fmt)
+set_target_properties(nvlog PROPERTIES PUBLIC_HEADER $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
+
######## libnvlog_static.a #############
add_library(nvlog_static STATIC ${SOURCES})
set_property(TARGET nvlog_static PROPERTY POSITION_INDEPENDENT_CODE ON)
@@ -68,5 +72,9 @@ target_compile_options(nvlog_static PRIVATE ${AERIAL_ARCH_TUNE_FLAGS})
#add_executable(nvlog_observer ${SOURCES})
#target_link_libraries(nvlog_observer nvlog_static -pthread)
+install(TARGETS nvlog
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/../)
+
######## test directory ################
add_subdirectory(test)
+103
View File
@@ -0,0 +1,103 @@
#/*
# * 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
# */
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface BUILD service
# Valid for Ubuntu 22.04
#
#---------------------------------------------------------------------
FROM ran-base:latest as ran-build
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
wget \
ninja-build \
#unzip is needed for protobuf
unzip \
moreutils \
vim-tiny \
nano \
# To build libnvipc
cmake libpcap-dev libcunit1-dev libnuma-dev pkg-config
RUN rm -Rf /oai-ran
WORKDIR /oai-ran
COPY . .
RUN /bin/sh oaienv && \
tar -xvzf nvipc_src.*.tar.gz && \
cd nvipc_src.* && \
git init && \
git apply ../cmake_targets/tools/install_libraries_to_system.patch --verbose && \
rm -rf build && mkdir build && cd build && \
cmake .. -DNVIPC_DPDK_ENABLE=OFF -DNVIPC_DOCA_ENABLE=OFF -DNVIPC_CUDA_ENABLE=OFF -DENABLE_SLT_RSP=ON && \
make -j && make install
RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
./build_oai -w AERIAL --gNB --ninja
#start from scratch for target executable
FROM ubuntu:focal as oai-gnb-aerial
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
software-properties-common \
procps \
libsctp1 \
tzdata \
libatlas3-base \
libconfig9 \
openssl \
net-tools \
iperf \
iproute2 \
iputils-ping \
gdb \
libusb-1.0-0 && \
rm -rf /var/lib/apt/lists/*
WORKDIR /opt/oai-gnb/bin
COPY --from=ran-build \
/oai-ran/cmake_targets/ran_build/build/nr-softmodem ./
COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh
COPY --from=ran-build /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so /usr/local/lib/
#copy files from nvIPC
COPY --from=ran-build \
/usr/local/lib/libfmtlog-shared.so \
/usr/local/lib/libnvlog.so \
/usr/local/lib/libnvipc.so \
/usr/local/lib/
WORKDIR /opt/oai-gnb
COPY --from=ran-build /tini /tini
ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"]
CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
@@ -0,0 +1,109 @@
#/*
# * 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
# */
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface BUILD service
# Valid for Ubuntu 22.04
#
#---------------------------------------------------------------------
FROM ran-base:latest as ran-build
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
wget \
ninja-build \
#unzip is needed for protobuf
unzip \
moreutils \
vim-tiny \
nano \
# To build libnvipc
cmake libpcap-dev libcunit1-dev libnuma-dev pkg-config
RUN rm -Rf /oai-ran
WORKDIR /oai-ran
COPY . .
RUN /bin/sh oaienv && \
tar -xvzf nvipc_src.*.tar.gz && \
cd nvipc_src.* && \
git init && \
git apply ../cmake_targets/tools/install_libraries_to_system.patch --verbose && \
rm -rf build && mkdir build && cd build && \
cmake .. -DNVIPC_DPDK_ENABLE=OFF -DNVIPC_DOCA_ENABLE=OFF -DNVIPC_CUDA_ENABLE=OFF -DENABLE_SLT_RSP=ON && \
make -j && make install
RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
./build_oai -w AERIAL --gNB --ninja --sanitize-address
#start from scratch for target executable
FROM ubuntu:focal as oai-gnb-aerial
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
software-properties-common \
procps \
libsctp1 \
tzdata \
libatlas3-base \
libconfig9 \
openssl \
net-tools \
iperf \
iproute2 \
iputils-ping \
gdb \
libusb-1.0-0 && \
rm -rf /var/lib/apt/lists/*
WORKDIR /opt/oai-gnb/bin
COPY --from=ran-build \
/oai-ran/cmake_targets/ran_build/build/nr-softmodem ./
COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh
COPY --from=ran-build \
/oai-ran/cmake_targets/ran_build/build/libcoding.so \
/oai-ran/cmake_targets/ran_build/build/librfsimulator.so \
/oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
/oai-ran/cmake_targets/ran_build/build/libdfts.so \
/oai-ran/cmake_targets/ran_build/build/libldpc*.so \
/usr/local/lib/
#copy files from nvIPC
COPY --from=ran-build \
/usr/local/lib/libfmtlog-shared.so \
/usr/local/lib/libnvlog.so \
/usr/local/lib/libnvipc.so \
/usr/local/lib/
WORKDIR /opt/oai-gnb
COPY --from=ran-build /tini /tini
ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"]
CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"]
+1 -1
View File
@@ -394,7 +394,7 @@ void init_gNB_Tpool(int inst) {
// this will be removed when the msgDataTx is not necessary anymore // this will be removed when the msgDataTx is not necessary anymore
gNB->msgDataTx = msgDataTx; gNB->msgDataTx = msgDataTx;
if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT) && (NFAPI_MODE!=NFAPI_MODE_VNF)) if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT) && (NFAPI_MODE!=NFAPI_MODE_VNF) && (NFAPI_MODE != NFAPI_MODE_AERIAL))
threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW); threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW);
} }
+1 -1
View File
@@ -1285,7 +1285,7 @@ void *ru_thread( void *param ) {
while (!oai_exit) { while (!oai_exit) {
if (NFAPI_MODE==NFAPI_MODE_VNF) { if (NFAPI_MODE==NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL ) {
// We should make a VNF main loop with proper tasks calls in case of VNF // We should make a VNF main loop with proper tasks calls in case of VNF
slot_start = timespec_add(slot_start,slot_duration); slot_start = timespec_add(slot_start,slot_duration);
struct timespec curr_time; struct timespec curr_time;
+15 -5
View File
@@ -80,7 +80,9 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "nfapi/oai_integration/vendor_ext.h" #include "nfapi/oai_integration/vendor_ext.h"
#include "gnb_config.h" #include "gnb_config.h"
#include "openair2/E1AP/e1ap_common.h" #include "openair2/E1AP/e1ap_common.h"
#ifdef ENABLE_AERIAL
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
#endif
#ifdef E2_AGENT #ifdef E2_AGENT
#include "openair2/E2AP/flexric/src/agent/e2_agent_api.h" #include "openair2/E2AP/flexric/src/agent/e2_agent_api.h"
#include "openair2/E2AP/RAN_FUNCTION/init_ran_func.h" #include "openair2/E2AP/RAN_FUNCTION/init_ran_func.h"
@@ -286,9 +288,15 @@ static int create_gNB_tasks(ngran_node_t node_type, configmodule_interface_t *cf
itti_wait_ready(1); itti_wait_ready(1);
LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__); LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__);
#ifdef ENABLE_AERIAL
AssertFatal(NFAPI_MODE == NFAPI_MODE_AERIAL,"Can only be run with '--nfapi AERIAL' when compiled with AERIAL support, if you want to run other (n)FAPI modes, please run ./build_oai without -w AERIAL");
#endif
RCconfig_verify(cfg, node_type); RCconfig_verify(cfg, node_type);
if(NFAPI_MODE != NFAPI_MODE_AERIAL){
RCconfig_nr_prs(); RCconfig_nr_prs();
}
if (RC.nb_nr_macrlc_inst > 0) if (RC.nb_nr_macrlc_inst > 0)
RCconfig_nr_macrlc(cfg); RCconfig_nr_macrlc(cfg);
@@ -687,7 +695,7 @@ int main( int argc, char **argv ) {
pthread_mutex_init(&sync_mutex, NULL); pthread_mutex_init(&sync_mutex, NULL);
usleep(1000); usleep(1000);
if (NFAPI_MODE) { if (NFAPI_MODE && NFAPI_MODE != NFAPI_MODE_AERIAL) {
printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
pthread_cond_init(&sync_cond,NULL); pthread_cond_init(&sync_cond,NULL);
pthread_mutex_init(&sync_mutex, NULL); pthread_mutex_init(&sync_mutex, NULL);
@@ -706,7 +714,7 @@ int main( int argc, char **argv ) {
printf("wait_gNBs()\n"); printf("wait_gNBs()\n");
wait_gNBs(); wait_gNBs();
printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
int sl_ahead=6; int sl_ahead = NFAPI_MODE == NFAPI_MODE_AERIAL ? 0 : 6;
if (RC.nb_RU >0) { if (RC.nb_RU >0) {
printf("Initializing RU threads\n"); printf("Initializing RU threads\n");
init_NR_RU(uniqCfg, get_softmodem_params()->rf_config_file); init_NR_RU(uniqCfg, get_softmodem_params()->rf_config_file);
@@ -749,7 +757,9 @@ int main( int argc, char **argv ) {
if (RC.nb_RU > 0) if (RC.nb_RU > 0)
start_NR_RU(); start_NR_RU();
#ifdef ENABLE_AERIAL
nvIPC_Init();
#endif
if (RC.nb_nr_L1_inst > 0) { if (RC.nb_nr_L1_inst > 0) {
printf("wait RUs\n"); printf("wait RUs\n");
wait_RUs(); wait_RUs();
@@ -778,7 +788,7 @@ int main( int argc, char **argv ) {
load_softscope("nrqt", &p); load_softscope("nrqt", &p);
} }
if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) { if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF && NFAPI_MODE != NFAPI_MODE_AERIAL) {
printf("Not NFAPI mode - call init_eNB_afterRU()\n"); printf("Not NFAPI mode - call init_eNB_afterRU()\n");
init_eNB_afterRU(); init_eNB_afterRU();
} else { } else {
+4 -4
View File
@@ -103,7 +103,7 @@ extern "C"
#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" #define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_USRP_THREAD "having extra thead for usrp tx\n" #define CONFIG_HLP_USRP_THREAD "having extra thead for usrp tx\n"
#define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR 'MONOLITHIC', 'PNF', 'VNF','UE_STUB_PNF','UE_STUB_OFFNET','STANDALONE_PNF'\n" #define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR 'MONOLITHIC', 'PNF', 'VNF', 'AERIAL','UE_STUB_PNF','UE_STUB_OFFNET','STANDALONE_PNF'\n"
#define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n" #define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n"
#define CONFIG_HLP_CONTINUOUS_TX "perform continuous transmission, even in TDD mode (to work around USRP issues)\n" #define CONFIG_HLP_CONTINUOUS_TX "perform continuous transmission, even in TDD mode (to work around USRP issues)\n"
#define CONFIG_HLP_STATS_DISABLE "disable globally the stats generation and persistence" #define CONFIG_HLP_STATS_DISABLE "disable globally the stats generation and persistence"
@@ -232,9 +232,9 @@ extern int usrp_tx_thread;
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
{ .s3a = { config_checkstr_assign_integer, \ { .s3a = { config_checkstr_assign_integer, \
{"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \ {"MONOLITHIC", "PNF", "VNF", "AERIAL","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \ {NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF, NFAPI_MODE_AERIAL,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
6 } }, \ 7 } }, \
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
{ .s5 = { NULL } }, \ { .s5 = { NULL } }, \
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/sh
echo "building ctags for openair1 and openair2 ..." echo "building ctags for openair1 and openair2 ..."
ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common nfapi executables radio ctags -e -R --exclude=openair1/DOCS/ --exclude=openair2/DOCS/ --exclude=openair1/SIMULATION/ --exclude=targets/DOCS/ --exclude=targets/PROJECTS/ openair1 openair2 openair3 targets cmake_targets common fapi nfapi executables radio
+1
View File
@@ -0,0 +1 @@
include(${OPENAIR_DIR}/nfapi/oai_integration/aerial/CMakeLists.txt)
@@ -0,0 +1,33 @@
add_boolean_option(OAI_AERIAL OFF "Activate OAI's AERIAL driver" OFF)
if (OAI_AERIAL)
message(STATUS "Building with support for Aerial")
target_sources(
nr-softmodem
PRIVATE
${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_nvIPC.c
${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_vnf_p7.c
${OPENAIR_DIR}/nfapi/oai_integration/aerial/fapi_vnf_p5.c )
find_library(NVIPC_LIB nvipc REQUIRED)
if (NOT NVIPC_LIB)
message(FATAL_ERROR "-- nvipc library not found")
else ()
message(STATUS " nvipc library found in ${NVIPC_LIB}")
#add_library(nvipc STATIC SHARED IMPORTED GLOBAL)
endif ()
find_library(NVLOG_LIB nvlog REQUIRED)
if (NOT NVLOG_LIB)
message(FATAL_ERROR "-- nvlog library not found")
else ()
message(STATUS " nvlog library found in ${NVLOG_LIB}")
endif ()
add_compile_definitions(ENABLE_L2_SLT_RSP)
add_compile_definitions(FAPI_BYTE_ORDERING_BIG_ENDIAN)
add_compile_definitions(ENABLE_AERIAL)
target_link_libraries(nr-softmodem PRIVATE "${NVLOG_LIB}" "${NVIPC_LIB}")
else()
message(STATUS "No Support for Aerial")
endif()
+683
View File
@@ -0,0 +1,683 @@
/*
* 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
*/
/*! \file fapi/oai-integration/fapi_nvIPC.c
* \brief OAI MAC/Aerial L1 interface file using FAPI over shared memory
* \author Ruben S. Silva
* \date 2023
* \version 0.1
* \company OpenAirInterface Software Alliance
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
* \note
* \warning
*/
#ifdef ENABLE_AERIAL
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <termios.h>
#include <stdatomic.h>
#include <sys/queue.h>
#include <sys/epoll.h>
#include "fapi_nvIPC.h"
#include "nfapi_interface.h"
#include "nfapi.h"
#include "nfapi_nr_interface_scf.h"
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
#include "fapi_vnf_p5.h"
#include "fapi_vnf_p7.h"
#define MAX_EVENTS 10
#define RECV_BUF_LEN 8192
char cpu_buf_recv[RECV_BUF_LEN];
uint16_t sfn = 0, slot = 0;
nv_ipc_t *ipc;
nfapi_vnf_config_t *vnf_config = 0;
void set_config(nfapi_vnf_config_t *conf)
{
vnf_config = conf;
}
static uint16_t old_sfn = 0;
static uint16_t old_slot = 0;
////////////////////////////////////////////////////////////////////////
// Handle an RX message
static int ipc_handle_rx_msg(nv_ipc_t *ipc, nv_ipc_msg_t *msg)
{
if (msg == NULL) {
LOG_E(NFAPI_VNF, "%s: ERROR: buffer is empty\n", __func__);
return -1;
}
char *p_cpu_data = NULL;
if (msg->data_buf != NULL) {
int gpu;
if (msg->data_pool == NV_IPC_MEMPOOL_CUDA_DATA) {
gpu = 1;
} else {
gpu = 0;
}
#ifdef NVIPC_CUDA_ENABLE
// Test CUDA: call CUDA functions to change all string to lower case
test_cuda_to_lower_case(test_cuda_device_id, msg->data_buf, TEST_DATA_BUF_LEN, gpu);
#endif
if (gpu) {
p_cpu_data = cpu_buf_recv;
memset(cpu_buf_recv, 0, RECV_BUF_LEN);
ipc->cuda_memcpy_to_host(ipc, p_cpu_data, msg->data_buf, RECV_BUF_LEN);
} else {
p_cpu_data = msg->data_buf;
}
}
int messageBufLen = msg->msg_len;
int dataBufLen = msg->data_len;
uint8_t msgbuf[messageBufLen];
uint8_t databuf[dataBufLen];
memcpy(msgbuf, msg->msg_buf, messageBufLen);
memcpy(databuf, msg->data_buf, dataBufLen);
uint8_t *pReadPackedMessage = msgbuf;
uint8_t *pReadData = databuf;
uint8_t *end = msgbuf + messageBufLen;
uint8_t *data_end = databuf + dataBufLen;
// unpack FAPI messages and handle them
if (vnf_config != 0) {
// first, unpack the header
fapi_phy_api_msg *fapi_msg = calloc(1, sizeof(fapi_phy_api_msg));
if (!(pull8(&pReadPackedMessage, &fapi_msg->num_msg, end) && pull8(&pReadPackedMessage, &fapi_msg->opaque_handle, end)
&& pull16(&pReadPackedMessage, &fapi_msg->message_id, end)
&& pull32(&pReadPackedMessage, &fapi_msg->message_length, end))) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "FAPI message header unpack failed\n");
return -1;
}
switch (fapi_msg->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
if (vnf_config->nr_param_resp) {
nfapi_nr_param_response_scf_t msg_param_resp;
aerial_unpack_nr_param_response(&pReadPackedMessage, end, &msg_param_resp, &vnf_config->codec_config);
(vnf_config->nr_param_resp)(vnf_config, vnf_config->pnf_list->p5_idx, &msg_param_resp);
}
break;
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: {
// unpack message
nfapi_nr_config_response_scf_t msg_config_response;
aerial_unpack_nr_config_response(&pReadPackedMessage, end, &msg_config_response, &vnf_config->codec_config);
// Check the error code
if (msg_config_response.error_code == NFAPI_NR_CONFIG_MSG_OK) {
// Invoke the call back
if (vnf_config->nr_config_resp) {
(vnf_config->nr_config_resp)(vnf_config, vnf_config->pnf_list->p5_idx, &msg_config_response);
}
} else {
// Error code not OK (MSG_INVALID_CONFIG)
/* MSG_INVALID_CONFIG.response structure
* Error code uint8_t
* Number of invalid or unsupported TLVs uint8_t
* Number of invalid TLVs that can only be configured in IDLE state uint8_t
* Number of invalid TLVs that can only be configured in RUNNING state uint8_t
* Number of missing TLVs uint8_t
* List of invalid or unsupported TLVs
* List of invalid TLVs that can only be configured in IDLE state
* List of invalid TLVs that can only be configured in RUNNING state
* List of missing TLVs
* */
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION: {
// TODO : ADD Support for NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION (0x06)
LOG_D(NFAPI_VNF,"Received NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION\n");
break;
}
case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION: {
// TODO: Add Support for NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION (0x07)
LOG_D(NFAPI_VNF,"Received NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION\n");
//for (int i = 0; i < msg->msg_len; i++) {
// printf(" msg->msg_buf[%d] = 0x%02x\n", i, ((uint8_t *) msg->msg_buf)[i]);
//}
LOG_D(NFAPI_VNF,"old sfn %u\n", old_sfn);
LOG_D(NFAPI_VNF,"old slot %u\n", old_slot);
break;
}
// P7 Messages
// P7 Message Handlers -> ((vnf_info *)vnf_config->user_data)->p7_vnfs->config->
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION: {
nfapi_nr_slot_indication_scf_t ind;
aerial_unpack_nr_slot_indication(&pReadPackedMessage,
end,
&ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
// check if the sfn/slot unpacked come wrong at any time, should be old + 1 (slot 0 -- 19, sfn 0 -- 1023)
// add 1 to current sfn number
uint16_t old_slot_plus = ((old_slot + 1) % 20);
uint16_t old_sfn_plus = old_slot_plus == 0 ? ((old_sfn + 1) % 1024) : old_sfn;
if (old_slot_plus != ind.slot || old_sfn_plus != ind.sfn) {
LOG_E(NFAPI_VNF,
"\n============================================================================\n"
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
"============================================================================\n",
old_sfn,
old_slot,
ind.sfn,
ind.slot);
}
old_sfn = ind.sfn;
old_slot = ind.slot;
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_slot_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_slot_indication)(&ind);
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: {
nfapi_nr_rx_data_indication_t ind;
ind.header.message_id = fapi_msg->message_id;
ind.header.message_length = fapi_msg->message_length;
aerial_unpack_nr_rx_data_indication(
&pReadPackedMessage,
end,
&pReadData,
data_end,
&ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RX Indication\n", __FUNCTION__);
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rx_data_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rx_data_indication)(&ind);
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: {
nfapi_nr_crc_indication_t crc_ind;
crc_ind.header.message_id = fapi_msg->message_id;
crc_ind.header.message_length = fapi_msg->message_length;
aerial_unpack_nr_crc_indication(&pReadPackedMessage,
end,
&crc_ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_crc_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_crc_indication)(&crc_ind);
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: {
nfapi_nr_uci_indication_t ind;
aerial_unpack_nr_uci_indication(&pReadPackedMessage,
end,
&ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_uci_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_uci_indication)(&ind);
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: {
nfapi_nr_srs_indication_t ind;
aerial_unpack_nr_srs_indication(&pReadPackedMessage,
end,
&ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_srs_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_srs_indication)(&ind);
}
break;
}
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: {
nfapi_nr_rach_indication_t ind;
aerial_unpack_nr_rach_indication(&pReadPackedMessage,
end,
&ind,
&((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rach_indication) {
(((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_rach_indication)(&ind);
}
break;
}
default: {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, fapi_msg->message_id);
break;
}
}
}
return 0;
}
int8_t buf[1024];
nv_ipc_config_t nv_ipc_config;
int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header)
{
if (ipc == NULL) {
return -1;
}
nv_ipc_msg_t send_msg = {0};
// look for the specific message
switch (header->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
break;
default: {
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
// if(config && config->pack_p4_p5_vendor_extension) {
// result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config);
// } else {
// NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id);
// }
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
}
} break;
}
send_msg.msg_id = header->message_id;
send_msg.cell_id = 0;
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
send_msg.data_len = 0;
send_msg.data_buf = NULL;
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG;
// procedure is allocate->fill->send
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
if (alloc_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
ipc->tx_release(ipc, &send_msg);
return alloc_retval;
}
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
LOG_D(NFAPI_VNF,
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
send_msg.cell_id,
send_msg.msg_id,
send_msg.msg_len,
send_msg.data_len,
send_msg.data_pool);
// Send the message
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
if (send_retval < 0) {
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
ipc->tx_release(ipc, &send_msg);
return send_retval;
}
ipc->notify(ipc, 1); // notify that there's 1 message in queue
return 0;
}
int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header)
{
if (ipc == NULL) {
return -1;
}
nv_ipc_msg_t send_msg;
uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8];
uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8;
uint16_t present_sfn = 0;
uint16_t present_slot = 0;
pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd);
pull16(&pPacketBodyField, &present_slot, pPackMessageEnd);
if (present_sfn != old_sfn || present_slot != old_slot) {
LOG_E(NFAPI_VNF,
"\n============================================================================\n"
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
"============================================================================\n",
present_sfn,
present_slot,
old_sfn,
old_slot);
}
// look for the specific message
switch (header->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
case NFAPI_UE_RELEASE_REQUEST:
case NFAPI_UE_RELEASE_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
case NFAPI_TIMING_INFO:
case 0x8f:
break;
default: {
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
}
} break;
}
send_msg.msg_id = header->message_id;
send_msg.cell_id = 0;
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
send_msg.data_len = 0;
send_msg.data_buf = NULL;
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_MSG;
// procedure is allocate->fill->send
// Allocate buffer for TX message
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
if (alloc_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
ipc->tx_release(ipc, &send_msg);
return alloc_retval;
}
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
LOG_D(NFAPI_VNF,
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
send_msg.cell_id,
send_msg.msg_id,
send_msg.msg_len,
send_msg.data_len,
send_msg.data_pool);
// Send the message
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
if (send_retval < 0) {
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
ipc->tx_release(ipc, &send_msg);
return send_retval;
}
ipc->notify(ipc, 1); // notify that there's 1 message in queue
return 0;
}
int aerial_send_P7_msg_with_data(void *packedBuf,
uint32_t packedMsgLength,
void *dataBuf,
uint32_t dataLength,
nfapi_p7_message_header_t *header)
{
if (ipc == NULL) {
return -1;
}
nv_ipc_msg_t send_msg;
uint8_t *pPacketBodyField = &((uint8_t *)packedBuf)[8];
uint8_t *pPackMessageEnd = packedBuf + packedMsgLength + 8;
uint16_t present_sfn = 0;
uint16_t present_slot = 0;
pull16(&pPacketBodyField, &present_sfn, pPackMessageEnd);
pull16(&pPacketBodyField, &present_slot, pPackMessageEnd);
if (present_sfn != old_sfn || present_slot != old_slot) {
LOG_E(NFAPI_VNF,
"\n============================================================================\n"
"sfn slot doesn't match unpacked one! L2->L1 %d.%d vs L1->L2 %d.%d \n"
"============================================================================\n",
present_sfn,
present_slot,
old_sfn,
old_slot);
}
// look for the specific message
switch (header->message_id) {
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
case NFAPI_UE_RELEASE_REQUEST:
case NFAPI_UE_RELEASE_RESPONSE:
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
case NFAPI_TIMING_INFO:
break;
default: {
if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
} else {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
}
} break;
}
send_msg.msg_id = header->message_id;
send_msg.cell_id = 0;
send_msg.msg_len = packedMsgLength + 8; // adding 8 to account for the size of the FAPI header
send_msg.data_len = dataLength;
send_msg.data_pool = NV_IPC_MEMPOOL_CPU_DATA;
// procedure is allocate->fill->send
// Allocate buffer for TX message
int alloc_retval = ipc->tx_allocate(ipc, &send_msg, 0);
if (alloc_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: allocate TX buffer failed Error: %d\n", __FUNCTION__, alloc_retval);
ipc->tx_release(ipc, &send_msg);
return alloc_retval;
}
memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
memcpy(send_msg.data_buf, dataBuf, send_msg.data_len);
LOG_D(NFAPI_VNF,
"send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
send_msg.cell_id,
send_msg.msg_id,
send_msg.msg_len,
send_msg.data_len,
send_msg.data_pool);
// Send the message
int send_retval = ipc->tx_send_msg(ipc, &send_msg);
if (send_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: send TX message failed Error: %d\n", __FUNCTION__, send_retval);
ipc->tx_release(ipc, &send_msg);
return send_retval;
}
ipc->notify(ipc, 1); // notify that there's 1 message in queue
return 0;
}
// Always allocate message buffer, but allocate data buffer only when data_len > 0
static int aerial_recv_msg(nv_ipc_t *ipc, nv_ipc_msg_t *recv_msg)
{
if (ipc == NULL) {
return -1;
}
recv_msg->msg_buf = NULL;
recv_msg->data_buf = NULL;
// Allocate buffer for TX message
if (ipc->rx_recv_msg(ipc, recv_msg) < 0) {
LOG_D(NFAPI_VNF, "%s: no more message available\n", __func__);
return -1;
}
LOG_D(NFAPI_VNF,
"recv: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
recv_msg->cell_id,
recv_msg->msg_id,
recv_msg->msg_len,
recv_msg->data_len,
recv_msg->data_pool);
ipc_handle_rx_msg(ipc, recv_msg);
// Release buffer of RX message
int release_retval = ipc->rx_release(ipc, recv_msg);
if (release_retval != 0) {
LOG_E(NFAPI_VNF, "%s error: release RX buffer failed Error: %d\n", __FUNCTION__, release_retval);
return release_retval;
}
return 0;
}
bool recv_task_running = false;
int stick_this_thread_to_core(int core_id)
{
int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
if (core_id < 0 || core_id >= num_cores)
return EINVAL;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(core_id, &cpuset);
pthread_t current_thread = pthread_self();
return pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset);
}
void *epoll_recv_task(void *arg)
{
struct epoll_event ev, events[MAX_EVENTS];
stick_this_thread_to_core(10);
LOG_D(NFAPI_VNF,"Aerial recv task start \n");
int epoll_fd = epoll_create1(0);
if (epoll_fd == -1) {
LOG_E(NFAPI_VNF, "%s epoll_create failed\n", __func__);
}
int ipc_rx_event_fd = ipc->get_fd(ipc);
ev.events = EPOLLIN;
ev.data.fd = ipc_rx_event_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, ev.data.fd, &ev) == -1) {
LOG_E(NFAPI_VNF, "%s epoll_ctl failed\n", __func__);
}
while (1) {
if (!recv_task_running) {
recv_task_running = true;
}
LOG_D(NFAPI_VNF, "%s: epoll_wait fd_rx=%d ...\n", __func__, ipc_rx_event_fd);
int nfds;
do {
// epoll_wait() may return EINTR when get unexpected signal SIGSTOP from system
nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
} while (nfds == -1 && errno == EINTR);
if (nfds < 0) {
LOG_E(NFAPI_VNF, "epoll_wait failed: epoll_fd=%d nfds=%d err=%d - %s\n", epoll_fd, nfds, errno, strerror(errno));
}
int n = 0;
for (n = 0; n < nfds; ++n) {
if (events[n].data.fd == ipc_rx_event_fd) {
ipc->get_value(ipc);
nv_ipc_msg_t recv_msg;
while (aerial_recv_msg(ipc, &recv_msg) == 0);
}
}
}
close(epoll_fd);
return NULL;
}
int create_recv_thread(void)
{
pthread_t thread_id;
void *(*recv_task)(void *);
recv_task = epoll_recv_task;
int ret = pthread_create(&thread_id, NULL, recv_task, NULL);
if (ret != 0) {
LOG_E(NFAPI_VNF, "%s failed, ret = %d\n", __func__, ret);
}
return ret;
}
int load_hard_code_config(nv_ipc_config_t *config, int module_type, nv_ipc_transport_t _transport)
{
// Create configuration
config->ipc_transport = _transport;
if (set_nv_ipc_default_config(config, module_type) < 0) {
LOG_E(NFAPI_VNF, "%s: set configuration failed\n", __func__);
return -1;
}
#ifdef NVIPC_CUDA_ENABLE
int test_cuda_device_id = get_cuda_device_id();
#else
int test_cuda_device_id = -1;
#endif
LOG_D(NFAPI_VNF,"CUDA device ID configured : %d \n", test_cuda_device_id);
config->transport_config.shm.cuda_device_id = test_cuda_device_id;
if (test_cuda_device_id >= 0) {
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CUDA_DATA].pool_len = 128;
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CPU_DATA].pool_len = 1024;
config->transport_config.shm.mempool_size[NV_IPC_MEMPOOL_CPU_MSG].pool_len = 4096;
}
return 0;
}
int nvIPC_Init() {
// Want to use transport SHM, type epoll, module secondary (reads the created shm from cuphycontroller)
load_hard_code_config(&nv_ipc_config, NV_IPC_MODULE_SECONDARY, NV_IPC_TRANSPORT_SHM);
// Create nv_ipc_t instance
if ((ipc = create_nv_ipc_interface(&nv_ipc_config)) == NULL) {
LOG_E(NFAPI_VNF, "%s: create IPC interface failed\n", __func__);
return -1;
}
LOG_I(NFAPI_VNF, "%s: create IPC interface successful\n", __func__);
sleep(1);
create_recv_thread();
while(!recv_task_running){usleep(100000);}
aerial_pnf_nr_connection_indication_cb(vnf_config, 1);
return 0;
}
#endif
+61
View File
@@ -0,0 +1,61 @@
/*
* 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
*/
/*! \file fapi/oai-integration/fapi_nvIPC.h
* \brief Header file for fapi_nvIPC.c
* \author Ruben S. Silva
* \date 2023
* \version 0.1
* \company OpenAirInterface Software Alliance
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
* \note
* \warning
*/
#ifdef ENABLE_AERIAL
#ifndef OPENAIRINTERFACE_FAPI_NVIPC_H
#define OPENAIRINTERFACE_FAPI_NVIPC_H
#include "nv_ipc.h"
#include "nv_ipc_utils.h"
#include "nvlog.h"
#include "nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h"
#include "openair1/PHY/defs_gNB.h"
#include "debug.h"
typedef struct {
uint8_t num_msg;
uint8_t opaque_handle;
uint16_t message_id;
uint32_t message_length;
} fapi_phy_api_msg;
int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header);
int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header);
int aerial_send_P7_msg_with_data(void *packedBuf,
uint32_t packedMsgLength,
void *dataBuf,
uint32_t dataLength,
nfapi_p7_message_header_t *header);
void set_config(nfapi_vnf_config_t *conf);
int nvIPC_Init();
#endif // OPENAIRINTERFACE_FAPI_NVIPC_H
#endif
+765
View File
@@ -0,0 +1,765 @@
/*
* 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
*/
/*! \file fapi/oai-integration/fapi_vnf_p5.c
* \brief OAI FAPI VNF P5 message handler procedures
* \author Ruben S. Silva
* \date 2023
* \version 0.1
* \company OpenAirInterface Software Alliance
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
* \note
* \warning
*/
#ifdef ENABLE_AERIAL
#include "fapi_vnf_p5.h"
#include "fapi_vnf_p7.h"
#include "nfapi/open-nFAPI/nfapi/src/nfapi_p5.c"
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
extern RAN_CONTEXT_t RC;
extern UL_RCC_IND_t UL_RCC_INFO;
extern int single_thread_flag;
extern uint16_t sf_ahead;
extern uint16_t slot_ahead;
static pthread_t vnf_aerial_p7_start_pthread;
void *aerial_vnf_nr_aerial_p7_start_thread(void *ptr)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
pthread_setname_np(pthread_self(), "VNF_P7_AERIAL");
nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr;
aerial_nfapi_nr_vnf_p7_start(config);
return config;
}
void *aerial_vnf_nr_p7_thread_start(void *ptr)
{
// set_thread_priority(79);
int s;
cpu_set_t cpuset;
CPU_SET(8, &cpuset);
s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
if (s != 0)
printf("failed to set afinity\n");
set_priority(79);
pthread_attr_t ptAttr;
if (pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) {
printf("Failed to set pthread sched policy SCHED_RR\n");
}
pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED);
struct sched_param thread_params;
thread_params.sched_priority = 20;
if (pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) {
printf("failed to set sched param\n");
}
init_queue(&gnb_rach_ind_queue);
init_queue(&gnb_rx_ind_queue);
init_queue(&gnb_crc_ind_queue);
init_queue(&gnb_uci_ind_queue);
init_queue(&gnb_slot_ind_queue);
vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr;
p7_vnf->config->port = p7_vnf->local_port;
p7_vnf->config->sync_indication = &aerial_phy_sync_indication;
p7_vnf->config->slot_indication = &aerial_phy_slot_indication;
p7_vnf->config->harq_indication = &aerial_phy_harq_indication;
p7_vnf->config->nr_crc_indication = &aerial_phy_nr_crc_indication;
p7_vnf->config->nr_rx_data_indication = &aerial_phy_nr_rx_data_indication;
p7_vnf->config->nr_rach_indication = &aerial_phy_nr_rach_indication;
p7_vnf->config->nr_uci_indication = &aerial_phy_nr_uci_indication;
p7_vnf->config->srs_indication = &aerial_phy_srs_indication;
p7_vnf->config->sr_indication = &aerial_phy_sr_indication;
p7_vnf->config->cqi_indication = &aerial_phy_cqi_indication;
p7_vnf->config->lbt_dl_indication = &aerial_phy_lbt_dl_indication;
p7_vnf->config->nb_harq_indication = &aerial_phy_nb_harq_indication;
p7_vnf->config->nrach_indication = &aerial_phy_nrach_indication;
p7_vnf->config->nr_slot_indication = &aerial_phy_nr_slot_indication;
p7_vnf->config->nr_srs_indication = &aerial_phy_nr_srs_indication;
p7_vnf->config->malloc = &aerial_vnf_allocate;
p7_vnf->config->free = &aerial_vnf_deallocate;
p7_vnf->config->vendor_ext = &aerial_phy_vendor_ext;
p7_vnf->config->user_data = p7_vnf;
p7_vnf->mac->user_data = p7_vnf;
p7_vnf->config->codec_config.unpack_p7_vendor_extension = &aerial_phy_unpack_p7_vendor_extension;
p7_vnf->config->codec_config.pack_p7_vendor_extension = &aerial_phy_pack_p7_vendor_extension;
p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &aerial_phy_unpack_vendor_extension_tlv;
p7_vnf->config->codec_config.pack_vendor_extension_tlv = &aerial_phy_pack_vendor_extension_tlv;
p7_vnf->config->codec_config.allocate = &aerial_vnf_allocate;
p7_vnf->config->codec_config.deallocate = &aerial_vnf_deallocate;
p7_vnf->config->allocate_p7_vendor_ext = &aerial_phy_allocate_p7_vendor_ext;
p7_vnf->config->deallocate_p7_vendor_ext = &aerial_phy_deallocate_p7_vendor_ext;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__);
pthread_create(&vnf_aerial_p7_start_pthread, NULL, &aerial_vnf_nr_aerial_p7_start_thread, p7_vnf->config);
return 0;
}
int aerial_pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx)
{
printf("[VNF] pnf connection indication idx:%d\n", p5_idx);
// in aerial, send first CONFIG.request, not PARAM.request
nfapi_nr_config_request_scf_t conf_req;
memset(&conf_req, 0, sizeof(conf_req));
conf_req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
printf("Try to send first CONFIG.request\n");
aerial_nr_send_config_request(config, p5_idx);
return 0;
}
int aerial_pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf disconnection indication idx:%d\n", p5_idx);
vnf_info *vnf = (vnf_info *)(config->user_data);
pnf_info *pnf = vnf->pnfs;
phy_info *phy = pnf->phys;
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
nfapi_vnf_p7_del_pnf((p7_vnf->config), phy->id);
return 0;
}
int aerial_pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_param_response_t *resp)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code);
vnf_info *vnf = (vnf_info *)(config->user_data);
pnf_info *pnf = vnf->pnfs;
for (int i = 0; i < resp->pnf_phy.number_of_phys; ++i) {
phy_info phy;
memset(&phy, 0, sizeof(phy));
phy.index = resp->pnf_phy.phy[i].phy_config_index;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index);
nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id));
for (int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index);
phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index;
}
pnf->phys[0] = phy;
}
nfapi_nr_pnf_config_request_t req;
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_PNF_CONFIG_REQUEST;
req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG;
req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size();
NFAPI_TRACE(NFAPI_TRACE_INFO, "DJP:Hard coded num phy rf to 2\n");
for (unsigned i = 0; i < 2; ++i) {
req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id;
req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index;
req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0];
}
nfapi_nr_vnf_pnf_config_req(config, p5_idx, &req);
return 0;
}
int aerial_pnf_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_config_response_t *resp)
{
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n",
p5_idx,
resp->header.phy_id,
resp->header.message_id,
resp->header.message_length);
if (1) {
nfapi_nr_pnf_start_request_t req;
memset(&req, 0, sizeof(req));
req.header.phy_id = resp->header.phy_id;
req.header.message_id = NFAPI_PNF_START_REQUEST;
nfapi_nr_vnf_pnf_start_req(config, p5_idx, &req);
} else {
// Rather than send the pnf_start_request we will demonstrate
// sending a vendor extention message. The start request will be
// send when the vendor extension response is received
// vnf_info* vnf = (vnf_info*)(config->user_data);
vendor_ext_p5_req req;
memset(&req, 0, sizeof(req));
req.header.message_id = P5_VENDOR_EXT_REQ;
req.dummy1 = 45;
req.dummy2 = 1977;
nfapi_vnf_vendor_extension(config, p5_idx, &req.header);
}
return 0;
}
int aerial_pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_start_response_t *resp)
{
vnf_info *vnf = (vnf_info *)(config->user_data);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
pnf_info *pnf = vnf->pnfs;
nfapi_nr_param_request_scf_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n",
p5_idx,
config,
config->user_data,
vnf->p7_vnfs[0].config,
vnf->p7_vnfs[0].thread_started);
if (p7_vnf->thread_started == 0) {
pthread_t vnf_p7_thread;
pthread_create(&vnf_p7_thread, NULL, &aerial_vnf_nr_p7_thread_start, p7_vnf);
p7_vnf->thread_started = 1;
} else {
// P7 thread already running.
}
// start all the phys in the pnf.
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id);
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST;
req.header.phy_id = pnf->phys[0].id;
nfapi_nr_vnf_param_req(config, p5_idx, &req);
return 0;
}
int aerial_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_param_response_scf_t *resp)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
vnf_info *vnf = (vnf_info *)(config->user_data);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
pnf_info *pnf = vnf->pnfs;
phy_info *phy = pnf->phys;
struct sockaddr_in pnf_p7_sockaddr;
nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; // check
phy->remote_port = resp->nfapi_config.p7_pnf_port.value;
// phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value;
memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4);
phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr);
// for now just 1
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n",
p5_idx,
phy->id,
phy->remote_addr,
phy->remote_port,
p7_vnf->timing_window,
p7_vnf->periodic_timing_period,
p7_vnf->aperiodic_timing_enabled,
p7_vnf->periodic_timing_period);
req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
req->header.phy_id = phy->id;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n");
// NFAPI_TRACE(NFAPI_TRACE_INFO, "\n NR bandP =%d\n",req->nfapi_config.rf_bands.rf_band[0]);
req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NR_NFAPI_P7_VNF_PORT_TAG;
req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port;
req->num_tlv++;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_port:%d\n", ntohs(p7_vnf->local_port));
req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG;
struct sockaddr_in vnf_p7_sockaddr;
vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr);
memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4);
req->num_tlv++;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_addr:%s\n", p7_vnf->local_addr);
req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG;
req->nfapi_config.timing_window.value = p7_vnf->timing_window;
NFAPI_TRACE(NFAPI_TRACE_INFO,
"\n[VNF]Timing window tag : %d Timing window:%u\n",
NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,
p7_vnf->timing_window);
req->num_tlv++;
if (p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) {
req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG;
req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled);
req->num_tlv++;
if (p7_vnf->periodic_timing_enabled) {
req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period;
req->num_tlv++;
}
}
// TODO: Assign tag and value for P7 message offsets
req->nfapi_config.dl_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET;
req->nfapi_config.ul_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET;
req->nfapi_config.ul_dci_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET;
req->nfapi_config.tx_data_timing_offset.tl.tag = NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET;
vendor_ext_tlv_2 ve2;
memset(&ve2, 0, sizeof(ve2));
ve2.tl.tag = VENDOR_EXT_TLV_2_TAG;
ve2.dummy = 2016;
req->vendor_extension = &ve2.tl;
nfapi_nr_vnf_config_req(config, p5_idx, req);
printf("[VNF] Sent NFAPI_VNF_CONFIG_REQ num_tlv:%u\n", req->num_tlv);
return 0;
}
int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx)
{
vnf_info *vnf = (vnf_info *)(config->user_data);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
pnf_info *pnf = vnf->pnfs;
phy_info *phy = pnf->phys;
nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; //&RC.gNB[0]->gNB_config; // check
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n",
p5_idx,
phy->id,
phy->remote_addr,
phy->remote_port,
p7_vnf->timing_window,
p7_vnf->periodic_timing_period,
p7_vnf->aperiodic_timing_enabled,
p7_vnf->periodic_timing_period);
req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST;
req->header.phy_id = phy->id;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n");
vnf_t *_this = (vnf_t *)(config);
nfapi_vnf_phy_info_t *vnf_phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id);
if (vnf_phy == NULL) {
printf("%s failed to find phy information phy_id:%d\n", __FUNCTION__, req->header.phy_id);
return -1;
}
nfapi_p4_p5_message_header_t *msg = &req->header;
uint16_t msg_len = sizeof(nfapi_nr_config_request_scf_t);
nfapi_p4_p5_message_header_t *msgFAPI = calloc(1, msg_len);
memcpy(msgFAPI, &req->header, msg_len);
uint8_t tx_messagebufferFAPI[sizeof(_this->tx_message_buffer)];
int packedMessageLengthFAPI = -1;
packedMessageLengthFAPI =
fapi_nr_p5_message_pack(msgFAPI, msg_len, tx_messagebufferFAPI, sizeof(tx_messagebufferFAPI), &_this->_public.codec_config);
aerial_send_P5_msg(tx_messagebufferFAPI, packedMessageLengthFAPI, msg);
return 0;
}
int aerial_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_config_response_scf_t *resp)
{
nfapi_nr_start_request_scf_t req;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
LOG_I(NFAPI_VNF, "Received CONFIG.response, gNB is ready! \n");
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_REQUEST;
req.header.phy_id = resp->header.phy_id;
nfapi_nr_vnf_start_req(config, p5_idx, &req);
return 0;
}
int aerial_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_response_scf_t *resp)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
vnf_info *vnf = (vnf_info *)(config->user_data);
pnf_info *pnf = vnf->pnfs;
phy_info *phy = pnf->phys;
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id);
return 0;
}
int aerial_vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s\n", __FUNCTION__);
switch (msg->message_id) {
case P5_VENDOR_EXT_RSP: {
vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)msg;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code);
// send the start request
nfapi_pnf_start_request_t req;
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_PNF_START_REQUEST;
nfapi_vnf_pnf_start_req(config, p5_idx, &req);
} break;
}
return 0;
}
int aerial_vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
uint8_t **ppReadPackedMessage,
uint8_t *end,
void **ve,
nfapi_p4_p5_codec_config_t *codec)
{
return -1;
}
int aerial_vnf_pack_vendor_extension_tlv(void *vext, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec)
{
nfapi_tl_t *tlv = (nfapi_tl_t *)vext;
switch (tlv->tag) {
case VENDOR_EXT_TLV_2_TAG: {
vendor_ext_tlv_2 *ve = (vendor_ext_tlv_2 *)tlv;
if (!push32(ve->dummy, ppWritePackedMsg, end))
return 0;
return 1;
} break;
}
return -1;
}
int aerial_vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
uint8_t **ppReadPackedMessage,
uint8_t *end,
nfapi_p4_p5_codec_config_t *codec)
{
if (header->message_id == P5_VENDOR_EXT_RSP) {
vendor_ext_p5_rsp *req = (vendor_ext_p5_rsp *)(header);
return (!pull16(ppReadPackedMessage, &req->error_code, end));
}
return 0;
}
int aerial_vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
uint8_t **ppWritePackedMsg,
uint8_t *end,
nfapi_p4_p5_codec_config_t *codec)
{
if (header->message_id == P5_VENDOR_EXT_REQ) {
vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header);
return (!(push16(req->dummy1, ppWritePackedMsg, end) && push16(req->dummy2, ppWritePackedMsg, end)));
}
return 0;
}
nfapi_p4_p5_message_header_t *aerial_vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size)
{
if (message_id == P5_VENDOR_EXT_RSP) {
*msg_size = sizeof(vendor_ext_p5_rsp);
return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_rsp));
}
return 0;
}
void aerial_vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header)
{
free(header);
}
void *aerial_vnf_p5_allocate(size_t size)
{
// return (void*)memory_pool::allocate(size);
return (void *)malloc(size);
}
void aerial_vnf_p5_deallocate(void *ptr)
{
// memory_pool::deallocate((uint8_t*)ptr);
free(ptr);
}
static vnf_info aerial_vnf;
void aerial_configure_nr_fapi_vnf()
{
// TODO: Implement for FAPI
// nfapi_setmode(NFAPI_MODE_VNF);
memset(&aerial_vnf, 0, sizeof(aerial_vnf));
memset(aerial_vnf.p7_vnfs, 0, sizeof(aerial_vnf.p7_vnfs));
aerial_vnf.p7_vnfs[0].timing_window = 30;
aerial_vnf.p7_vnfs[0].periodic_timing_enabled = 0;
aerial_vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
aerial_vnf.p7_vnfs[0].periodic_timing_period = 10;
aerial_vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
aerial_vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t));
nfapi_vnf_config_t *config = nfapi_vnf_config_create();
config->malloc = malloc;
config->free = free;
config->vnf_ipv4 = 1;
config->vnf_ipv6 = 0;
config->pnf_list = 0;
config->phy_list = 0;
config->pnf_nr_connection_indication = &aerial_pnf_nr_connection_indication_cb;
config->pnf_disconnect_indication = &aerial_pnf_disconnection_indication_cb;
config->pnf_nr_param_resp = &aerial_pnf_nr_param_resp_cb;
config->pnf_nr_config_resp = &aerial_pnf_nr_config_resp_cb;
config->pnf_nr_start_resp = &aerial_pnf_nr_start_resp_cb;
config->nr_param_resp = &aerial_nr_param_resp_cb;
config->nr_config_resp = &aerial_nr_config_resp_cb;
config->nr_start_resp = &aerial_nr_start_resp_cb;
config->vendor_ext = &aerial_vendor_ext_cb;
config->user_data = &aerial_vnf;
// To allow custom vendor extentions to be added to nfapi
config->codec_config.unpack_vendor_extension_tlv = &aerial_vnf_unpack_vendor_extension_tlv;
config->codec_config.pack_vendor_extension_tlv = &aerial_vnf_pack_vendor_extension_tlv;
config->codec_config.unpack_p4_p5_vendor_extension = &aerial_vnf_unpack_p4_p5_vendor_extension;
config->codec_config.pack_p4_p5_vendor_extension = &aerial_vnf_pack_p4_p5_vendor_extension;
config->allocate_p4_p5_vendor_ext = &aerial_vnf_allocate_p4_p5_vendor_ext;
config->deallocate_p4_p5_vendor_ext = &aerial_vnf_deallocate_p4_p5_vendor_ext;
config->codec_config.allocate = &aerial_vnf_allocate;
config->codec_config.deallocate = &aerial_vnf_deallocate;
memset(&UL_RCC_INFO, 0, sizeof(UL_RCC_IND_t));
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
set_config(config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__);
nfapi_vnf_pnf_info_t *pnf = (nfapi_vnf_pnf_info_t *)malloc(sizeof(nfapi_vnf_pnf_info_t));
NFAPI_TRACE(NFAPI_TRACE_INFO, "MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:%p\n", pnf);
memset(pnf, 0, sizeof(nfapi_vnf_pnf_info_t));
pnf->p5_idx = 1;
pnf->connected = 1;
// Add needed parameters
vnf_info *vnf = (vnf_info *)(config->user_data);
pnf_info *pnf_info = vnf->pnfs;
for (int i = 0; i < 1; ++i) {
phy_info phy;
memset(&phy, 0, sizeof(phy));
phy.index = 0;
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, 0);
nfapi_vnf_allocate_phy(config, 1, &(phy.id));
for (int j = 0; j < 1; ++j) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, 0);
phy.rfs[0] = 0;
}
pnf_info->phys[0] = phy;
}
nfapi_vnf_pnf_list_add(config, pnf);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
NFAPI_TRACE(NFAPI_TRACE_INFO,
"[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n",
1,
config,
config->user_data,
vnf->p7_vnfs[0].config,
vnf->p7_vnfs[0].thread_started);
if (p7_vnf->thread_started == 0) {
pthread_t vnf_p7_thread;
pthread_create(&vnf_p7_thread, NULL, &aerial_vnf_nr_p7_thread_start, p7_vnf);
p7_vnf->thread_started = 1;
} else {
// P7 thread already running.
}
}
uint8_t aerial_unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config)
{
return unpack_nr_param_response(ppReadPackedMsg, end, msg, config);
}
uint8_t aerial_unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config)
{
return unpack_nr_config_response(ppReadPackedMsg, end, msg, config);
}
// monitor the p7 endpoints and the timing loop and
// send indications to mac
int aerial_nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t *config)
{
if (config == 0)
return -1;
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
vnf_p7_t *vnf_p7 = (vnf_p7_t *)config;
// Create p7 receive udp port
// todo : this needs updating for Ipv6
NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port);
struct timespec ref_time;
clock_gettime(CLOCK_MONOTONIC, &ref_time);
uint8_t setup_done = 0;
while (vnf_p7->terminate == 0) {
if (setup_done == 0) {
struct timespec curr_time;
clock_gettime(CLOCK_MONOTONIC, &curr_time);
uint8_t setup_time = curr_time.tv_sec - ref_time.tv_sec;
if (setup_time > 3) {
setup_done = 1;
}
}
}
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
close(vnf_p7->socket);
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__);
return 0;
}
int fapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t *config){
nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
uint8_t *pWritePackedMessage = pPackedBuf;
uint32_t packedMsgLen;
//uint16_t packedMsgLen16;
if (pMessageBuf == NULL || pPackedBuf == NULL) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n");
return -1;
}
uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
uint8_t *pPackedLengthField = &pWritePackedMessage[4];
uint8_t *pPacketBodyField = &pWritePackedMessage[8];
uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8];
pack_nr_p5_message_body(pMessageHeader, &pPacketBodyField, pPackMessageEnd, config);
// PHY API message header
push8(1, &pWritePackedMessage, pPackMessageEnd); // Number of messages
push8(0, &pWritePackedMessage, pPackMessageEnd); // Opaque handle
// PHY API Message structure
push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd); // Message type ID
if(1==1) {
// check for a valid message length
packedMsgLen = get_packed_msg_len((uintptr_t)pPacketBodyFieldStart, (uintptr_t)pPacketBodyField);
packedMsgLen-=1;
if(pMessageHeader->message_id == NFAPI_NR_PHY_MSG_TYPE_START_REQUEST){
//START.request doesn't have a body, length is 0
packedMsgLen = 0;
}else if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message 0x%02x length error %d, buffer supplied %d\n",pMessageHeader->message_id, packedMsgLen, packedBufLen);
return -1;
} else {
}
// Update the message length in the header
if(!push32(packedMsgLen, &pPackedLengthField, pPackMessageEnd))
return -1;
// return the packed length
return (packedMsgLen);
} else {
// Failed to pack the meassage
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n");
return -1;
}
}
int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req)
{
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
ul_tti_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ul_tti_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST;
// int retval = nfapi_vnf_p7_ul_tti_req(p7_config, ul_tti_req);
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &ul_tti_req->header);
if (retval != 0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
// Reset number of PDUs so that it is not resent
ul_tti_req->n_pdus = 0;
ul_tti_req->n_group = 0;
ul_tti_req->n_ulcch = 0;
ul_tti_req->n_ulsch = 0;
}
return retval;
}
int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req)
{
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
ul_dci_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
ul_dci_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST;
// int retval = nfapi_vnf_p7_ul_dci_req(p7_config, ul_dci_req);
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &ul_dci_req->header);
if (retval != 0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
ul_dci_req->numPdus = 0;
}
return retval;
}
int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req)
{
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
tx_data_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
tx_data_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST;
// LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_data_req->SFN),
// tx_data_req->Number_of_PDUs); int retval = nfapi_vnf_p7_tx_data_req(p7_config, tx_data_req);
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &tx_data_req->header);
if (retval != 0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
} else {
tx_data_req->Number_of_PDUs = 0;
}
return retval;
}
int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
{
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
dl_config_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &dl_config_req->header);
dl_config_req->dl_tti_request_body.nPDUs = 0;
dl_config_req->dl_tti_request_body.nGroup = 0;
if (retval != 0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
}
return retval;
}
int oai_fapi_send_end_request(int cell, uint32_t frame, uint32_t slot){
nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config;
nfapi_nr_slot_indication_scf_t *nr_slot_resp = CALLOC(1, sizeof(*nr_slot_resp));
nr_slot_resp->header.message_id = 0x8F;
nr_slot_resp->sfn = frame;
nr_slot_resp->slot = slot;
int retval = fapi_nr_pack_and_send_p7_message((vnf_p7_t *)p7_config, &nr_slot_resp->header);
if (retval != 0) {
LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
}
return retval;
}
#endif
@@ -0,0 +1,75 @@
/*
* 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
*/
/*! \file fapi/oai-integration/fapi_vnf_p5.h
* \brief Header file for fapi_vnf_p5.c
* \author Ruben S. Silva
* \date 2023
* \version 0.1
* \company OpenAirInterface Software Alliance
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
* \note
* \warning
*/
#ifdef ENABLE_AERIAL
#ifndef OPENAIRINTERFACE_FAPI_VNF_P5_H
#define OPENAIRINTERFACE_FAPI_VNF_P5_H
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "nfapi_nr_interface_scf.h"
#include "nfapi_vnf_interface.h"
#include "nfapi_vnf.h"
#include "nfapi.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "fapi_nvIPC.h"
#include "PHY/defs_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "common/ran_context.h"
#include "openair2/PHY_INTERFACE/queue_t.h"
#include "gnb_ind_vars.h"
#include "nfapi/open-nFAPI/vnf/inc/vnf.h"
void aerial_configure_nr_fapi_vnf();
int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx);
int oai_fapi_send_end_request(int cell_id, uint32_t frame, uint32_t slot);
uint8_t aerial_unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
uint8_t aerial_unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
int aerial_pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx);
int aerial_nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t *config);
int fapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config);
int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req);
int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req);
int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req);
int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
#endif //OPENAIRINTERFACE_FAPI_VNF_P5_H
#endif
File diff suppressed because it is too large Load Diff
+243
View File
@@ -0,0 +1,243 @@
/*
* 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
*/
/*! \file fapi/oai-integration/fapi_vnf_p7.h
* \brief Header file for fapi_vnf_p7.c
* \author Ruben S. Silva
* \date 2023
* \version 0.1
* \company OpenAirInterface Software Alliance
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
* \note
* \warning
*/
#ifdef ENABLE_AERIAL
#ifndef OPENAIRINTERFACE_FAPI_VNF_P7_H
#define OPENAIRINTERFACE_FAPI_VNF_P7_H
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "nfapi_nr_interface_scf.h"
#include "nfapi_vnf_interface.h"
#include "nfapi_vnf.h"
#include "nfapi.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "fapi_nvIPC.h"
#include "PHY/defs_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "lte-softmodem.h"
#include "common/ran_context.h"
#include "openair2/PHY_INTERFACE/queue_t.h"
#include "gnb_ind_vars.h"
#include "nfapi/open-nFAPI/vnf/inc/vnf.h"
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
typedef struct {
uint8_t enabled;
uint32_t rx_port;
uint32_t tx_port;
char tx_addr[80];
} udp_data;
typedef struct {
uint16_t index;
uint16_t id;
uint8_t rfs[2];
uint8_t excluded_rfs[2];
udp_data udp;
char local_addr[80];
int local_port;
char *remote_addr;
int remote_port;
uint8_t duplex_mode;
uint16_t dl_channel_bw_support;
uint16_t ul_channel_bw_support;
uint8_t num_dl_layers_supported;
uint8_t num_ul_layers_supported;
uint16_t release_supported;
uint8_t nmm_modes_supported;
uint8_t dl_ues_per_subframe;
uint8_t ul_ues_per_subframe;
uint8_t first_subframe_ind;
// timing information recevied from the vnf
uint8_t timing_window;
uint8_t timing_info_mode;
uint8_t timing_info_period;
} phy_info;
typedef struct {
uint16_t index;
uint16_t band;
int16_t max_transmit_power;
int16_t min_transmit_power;
uint8_t num_antennas_supported;
uint32_t min_downlink_frequency;
uint32_t max_downlink_frequency;
uint32_t max_uplink_frequency;
uint32_t min_uplink_frequency;
} rf_info;
typedef struct {
int release;
phy_info phys[2];
rf_info rfs[2];
uint8_t sync_mode;
uint8_t location_mode;
uint8_t location_coordinates[6];
uint32_t dl_config_timing;
uint32_t ul_config_timing;
uint32_t tx_timing;
uint32_t hi_dci0_timing;
uint16_t max_phys;
uint16_t max_total_bw;
uint16_t max_total_dl_layers;
uint16_t max_total_ul_layers;
uint8_t shared_bands;
uint8_t shared_pa;
int16_t max_total_power;
uint8_t oui;
uint8_t wireshark_test_mode;
} pnf_info;
typedef struct mac mac_t;
typedef struct mac {
void *user_data;
void (*dl_config_req)(mac_t *mac, nfapi_dl_config_request_t *req);
void (*ul_config_req)(mac_t *mac, nfapi_ul_config_request_t *req);
void (*hi_dci0_req)(mac_t *mac, nfapi_hi_dci0_request_t *req);
void (*tx_req)(mac_t *mac, nfapi_tx_request_t *req);
} mac_t;
typedef struct {
int local_port;
char local_addr[80];
unsigned timing_window;
unsigned periodic_timing_enabled;
unsigned aperiodic_timing_enabled;
unsigned periodic_timing_period;
// This is not really the right place if we have multiple PHY,
// should be part of the phy struct
udp_data udp;
uint8_t thread_started;
nfapi_vnf_p7_config_t *config;
mac_t *mac;
} vnf_p7_info;
typedef struct {
uint8_t wireshark_test_mode;
pnf_info pnfs[2];
vnf_p7_info p7_vnfs[2];
} vnf_info;
int aerial_wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot);
int aerial_wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf);
int aerial_phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync);
int aerial_phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
int aerial_phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind);
int aerial_phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind);
int aerial_phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind);
int aerial_phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind);
int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind);
int aerial_phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind);
int aerial_phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind);
int aerial_phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind);
int aerial_phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind);
int aerial_phy_nb_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_nb_harq_indication_t *ind);
int aerial_phy_nrach_indication(struct nfapi_vnf_p7_config *config, nfapi_nrach_indication_t *ind);
int aerial_phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
int aerial_phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
void *aerial_vnf_allocate(size_t size);
void aerial_vnf_deallocate(void *ptr);
int aerial_phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg);
int aerial_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header,
uint8_t **ppReadPackedMessage,
uint8_t *end,
nfapi_p7_codec_config_t *config);
int aerial_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header,
uint8_t **ppWritePackedMsg,
uint8_t *end,
nfapi_p7_codec_config_t *config);
int aerial_phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
uint8_t **ppReadPackedMessage,
uint8_t *end,
void **ve,
nfapi_p7_codec_config_t *codec);
int aerial_phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec);
nfapi_p7_message_header_t *aerial_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size);
void aerial_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header);
uint8_t aerial_unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_nr_slot_indication_scf_t *msg,
nfapi_p7_codec_config_t *config);
uint8_t aerial_unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg,
uint8_t *end,
uint8_t **pDataMsg,
uint8_t *data_end,
nfapi_nr_rx_data_indication_t *msg,
nfapi_p7_codec_config_t *config);
uint8_t aerial_unpack_nr_crc_indication(uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_nr_crc_indication_t *msg,
nfapi_p7_codec_config_t *config);
uint8_t aerial_unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
uint8_t aerial_unpack_nr_rach_indication(uint8_t **ppReadPackedMsg,
uint8_t *end,
nfapi_nr_rach_indication_t *msg,
nfapi_p7_codec_config_t *config);
// int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_p7_message_header_t *header);
#endif // OPENAIRINTERFACE_FAPI_VNF_P7_H
#endif
+2 -1
View File
@@ -27,6 +27,7 @@ static const char *const nfapi_str_mode[] = {
"MONOLITHIC", "MONOLITHIC",
"PNF", "PNF",
"VNF", "VNF",
"AERIAL",
"UE_STUB_PNF", "UE_STUB_PNF",
"UE_STUB_OFFNET", "UE_STUB_OFFNET",
"STANDALONE_PNF", "STANDALONE_PNF",
@@ -64,7 +65,7 @@ const char *nfapi_get_strmode(void) {
} }
void nfapi_logmode() { void nfapi_logmode() {
LOG_I(ENB_APP,"nfapi running mode: %s\n",nfapi_get_strmode()); LOG_I(ENB_APP,"nfapi (%d) running mode: %s\n",nfapi_params.nfapi_mode,nfapi_get_strmode());
} }
nfapi_mode_t nfapi_getmode(void) { nfapi_mode_t nfapi_getmode(void) {
+1
View File
@@ -68,6 +68,7 @@ typedef enum {
NFAPI_MONOLITHIC=0, NFAPI_MONOLITHIC=0,
NFAPI_MODE_PNF, NFAPI_MODE_PNF,
NFAPI_MODE_VNF, NFAPI_MODE_VNF,
NFAPI_MODE_AERIAL,
NFAPI_UE_STUB_PNF, NFAPI_UE_STUB_PNF,
NFAPI_UE_STUB_OFFNET, NFAPI_UE_STUB_OFFNET,
NFAPI_MODE_STANDALONE_PNF, NFAPI_MODE_STANDALONE_PNF,
@@ -328,6 +328,7 @@ typedef struct
#define NFAPI_NR_CONFIG_SLOT_CONFIG_TAG 0x1027 #define NFAPI_NR_CONFIG_SLOT_CONFIG_TAG 0x1027
#define NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG 0x1028 #define NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG 0x1028
#define NFAPI_NR_CONFIG_TDD_TABLE 0x1035
//table 3-21 //table 3-21
typedef struct typedef struct
@@ -1467,11 +1468,9 @@ typedef enum {
//table 3-58 //table 3-58
#define NFAPI_NR_MAX_TX_REQUEST_TLV 2 #define NFAPI_NR_MAX_TX_REQUEST_TLV 2
typedef struct { typedef struct
uint16_t PDU_length; // SCF 222.10.02 The total length (in bytes) of the PDU description and PDU data, without the padding bytes. {
// (2 bytes PDU_Length + 2 bytes PDU_Index + 4 bytes num_TLV + TLV size ( 2 bytes tag + 2 bytes length + uint32_t PDU_length;
// value size without padding))
// TBS + 12
uint16_t PDU_index; uint16_t PDU_index;
uint32_t num_TLV; uint32_t num_TLV;
nfapi_nr_tx_data_request_tlv_t TLVs[NFAPI_NR_MAX_TX_REQUEST_TLV]; nfapi_nr_tx_data_request_tlv_t TLVs[NFAPI_NR_MAX_TX_REQUEST_TLV];
@@ -1505,7 +1504,7 @@ typedef struct
uint32_t handle; uint32_t handle;
uint16_t rnti; uint16_t rnti;
uint8_t harq_id; uint8_t harq_id;
uint16_t pdu_length; uint32_t pdu_length;// For Aerial, RX_DATA.indication PDULength is changed to 32 bit field
uint8_t ul_cqi; uint8_t ul_cqi;
uint16_t timing_advance;//Timing advance 𝑇𝐴 measured for the UE [TS 38.213, Section 4.2] NTA_new = NTA_old + (TA − 31) ⋅ 16 ⋅ 64⁄2μ Value: 0 → 63 0xffff should be set if this field is invalid uint16_t timing_advance;//Timing advance 𝑇𝐴 measured for the UE [TS 38.213, Section 4.2] NTA_new = NTA_old + (TA − 31) ⋅ 16 ⋅ 64⁄2μ Value: 0 → 63 0xffff should be set if this field is invalid
uint16_t rssi; uint16_t rssi;
+40 -1
View File
@@ -102,8 +102,13 @@ uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end) {
uint8_t *pOut = *out; uint8_t *pOut = *out;
if((end - pOut) >= 2) { if((end - pOut) >= 2) {
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
pOut[1] = (in & 0xFF00) >> 8;
pOut[0] = (in & 0xFF);
#else
pOut[0] = (in & 0xFF00) >> 8; pOut[0] = (in & 0xFF00) >> 8;
pOut[1] = (in & 0xFF); pOut[1] = (in & 0xFF);
#endif
(*out)+=2; (*out)+=2;
return 2; return 2;
} else { } else {
@@ -117,8 +122,13 @@ uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end) {
uint8_t *pOut = *out; uint8_t *pOut = *out;
if((end - pOut) >= 2) { if((end - pOut) >= 2) {
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
pOut[1] = (in & 0xFF00) >> 8;
pOut[0] = (in & 0xFF);
#else
pOut[0] = (in & 0xFF00) >> 8; pOut[0] = (in & 0xFF00) >> 8;
pOut[1] = (in & 0xFF); pOut[1] = (in & 0xFF);
#endif
(*out)+=2; (*out)+=2;
return 2; return 2;
} else { } else {
@@ -132,10 +142,17 @@ uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end) {
uint8_t *pOut = *out; uint8_t *pOut = *out;
if((end - pOut) >= 4) { if((end - pOut) >= 4) {
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
pOut[3] = (in & 0xFF000000) >> 24;
pOut[2] = (in & 0xFF0000) >> 16;
pOut[1] = (in & 0xFF00) >> 8;
pOut[0] = (in & 0xFF);
#else
pOut[0] = (in & 0xFF000000) >> 24; pOut[0] = (in & 0xFF000000) >> 24;
pOut[1] = (in & 0xFF0000) >> 16; pOut[1] = (in & 0xFF0000) >> 16;
pOut[2] = (in & 0xFF00) >> 8; pOut[2] = (in & 0xFF00) >> 8;
pOut[3] = (in & 0xFF); pOut[3] = (in & 0xFF);
#endif
(*out)+=4; (*out)+=4;
return 4; return 4;
} else { } else {
@@ -149,10 +166,17 @@ uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end) {
uint8_t *pOut = *out; uint8_t *pOut = *out;
if((end - pOut) >= 4) { if((end - pOut) >= 4) {
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
pOut[3] = (in & 0xFF000000) >> 24;
pOut[2] = (in & 0xFF0000) >> 16;
pOut[1] = (in & 0xFF00) >> 8;
pOut[0] = (in & 0xFF);
#else
pOut[0] = (in & 0xFF000000) >> 24; pOut[0] = (in & 0xFF000000) >> 24;
pOut[1] = (in & 0xFF0000) >> 16; pOut[1] = (in & 0xFF0000) >> 16;
pOut[2] = (in & 0xFF00) >> 8; pOut[2] = (in & 0xFF00) >> 8;
pOut[3] = (in & 0xFF); pOut[3] = (in & 0xFF);
#endif
(*out)+=4; (*out)+=4;
return 4; return 4;
} else { } else {
@@ -194,7 +218,11 @@ uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end) {
uint8_t *pIn = *in; uint8_t *pIn = *in;
if((end - pIn) >=2 ) { if((end - pIn) >=2 ) {
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
*out = ((pIn[1]) << 8) | pIn[0];
#else
*out = ((pIn[0]) << 8) | pIn[1]; *out = ((pIn[0]) << 8) | pIn[1];
#endif
(*in)+=2; (*in)+=2;
return 2; return 2;
} else { } else {
@@ -208,7 +236,11 @@ uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end) {
uint8_t *pIn = *in; uint8_t *pIn = *in;
if((end - pIn) >=2 ) { if((end - pIn) >=2 ) {
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
*out = ((pIn[1]) << 8) | pIn[0];
#else
*out = ((pIn[0]) << 8) | pIn[1]; *out = ((pIn[0]) << 8) | pIn[1];
#endif
(*in)+=2; (*in)+=2;
return 2; return 2;
} else { } else {
@@ -222,7 +254,11 @@ uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end) {
uint8_t *pIn = *in; uint8_t *pIn = *in;
if((end - pIn) >= 4) { if((end - pIn) >= 4) {
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
*out = ((uint32_t)pIn[3] << 24) | (pIn[2] << 16) | (pIn[1] << 8) | pIn[0];
#else
*out = ((uint32_t)pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3]; *out = ((uint32_t)pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
#endif
(*in) += 4; (*in) += 4;
return 4; return 4;
} else { } else {
@@ -236,7 +272,11 @@ uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end) {
uint8_t *pIn = *in; uint8_t *pIn = *in;
if((end - pIn) >=4 ) { if((end - pIn) >=4 ) {
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
*out = (pIn[3] << 24) | (pIn[2] << 16) | (pIn[1] << 8) | pIn[0];
#else
*out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3]; *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3];
#endif
(*in)+=4; (*in)+=4;
return 4; return 4;
} else { } else {
@@ -839,7 +879,6 @@ int unpack_nr_tlv_list(unpack_tlv_t unpack_fns[],
} }
} }
} }
return 1; return 1;
} }
+69 -10
View File
@@ -35,6 +35,7 @@
#include <nfapi.h> #include <nfapi.h>
#include "nfapi_nr_interface.h" #include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h" #include "nfapi_nr_interface_scf.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include <debug.h> #include <debug.h>
@@ -1670,6 +1671,16 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
end, end,
&pack_uint16_tlv_value); &pack_uint16_tlv_value);
numTLVs++; numTLVs++;
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
// TLV not supported by Aerial L1
pack_nr_tlv(NFAPI_NR_CONFIG_FREQUENCY_SHIFT_7P5KHZ_TAG,
&(pNfapiMsg->carrier_config.frequency_shift_7p5khz),
ppWritePackedMsg,
end,
&pack_uint8_tlv_value);
numTLVs++;
}
// END Carrier Configuration // END Carrier Configuration
// START Cell Configuration // START Cell Configuration
@@ -1695,13 +1706,15 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
end, end,
&pack_uint32_tlv_value); &pack_uint32_tlv_value);
numTLVs++; numTLVs++;
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
// TLV not supported by Aerial L1
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG, retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG,
&(pNfapiMsg->ssb_config.bch_payload), &(pNfapiMsg->ssb_config.bch_payload),
ppWritePackedMsg, ppWritePackedMsg,
end, end,
&pack_uint8_tlv_value); &pack_uint8_tlv_value);
numTLVs++; numTLVs++;
}
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SCS_COMMON_TAG, retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SCS_COMMON_TAG,
&(pNfapiMsg->ssb_config.scs_common), &(pNfapiMsg->ssb_config.scs_common),
@@ -1780,6 +1793,16 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
end, end,
&pack_uint16_tlv_value); &pack_uint16_tlv_value);
numTLVs++; numTLVs++;
for (int k = 0; k < prach_fd_occasion.num_unused_root_sequences.value; k++) {
prach_fd_occasion.unused_root_sequences_list[k].tl.tag = NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG;
prach_fd_occasion.unused_root_sequences_list[k].value = 0;
pack_nr_tlv(NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG,
&(prach_fd_occasion.unused_root_sequences_list[k]),
ppWritePackedMsg,
end,
&pack_uint16_tlv_value);
numTLVs++;
}
} }
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PER_RACH_TAG, retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PER_RACH_TAG,
@@ -1788,15 +1811,25 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
end, end,
&pack_uint8_tlv_value); &pack_uint8_tlv_value);
numTLVs++; numTLVs++;
pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band.tl.tag = NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG;
pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band.value = 0;
pack_nr_tlv(NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG,
&(pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band),
ppWritePackedMsg,
end,
&pack_uint8_tlv_value);
numTLVs++;
// END PRACH Configuration // END PRACH Configuration
// START SSB Table // START SSB Table
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
// TLV not supported by Aerial L1
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG,
&(pNfapiMsg->ssb_table.ssb_offset_point_a), &(pNfapiMsg->ssb_table.ssb_offset_point_a),
ppWritePackedMsg, ppWritePackedMsg,
end, end,
&pack_uint16_tlv_value); &pack_uint16_tlv_value);
numTLVs++; numTLVs++;
}
retval &= retval &=
pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), ppWritePackedMsg, end, &pack_uint8_tlv_value); pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), ppWritePackedMsg, end, &pack_uint8_tlv_value);
numTLVs++; numTLVs++;
@@ -1807,7 +1840,10 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
end, end,
&pack_uint8_tlv_value); &pack_uint8_tlv_value);
numTLVs++; numTLVs++;
/* was unused */
pNfapiMsg->ssb_table.MIB.tl.tag = NFAPI_NR_CONFIG_MIB_TAG;
pack_nr_tlv(NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), ppWritePackedMsg, end, &pack_uint32_tlv_value);
numTLVs++;
// SCF222.10.02 Table 3-25 : If included there must be two instances of this TLV // SCF222.10.02 Table 3-25 : If included there must be two instances of this TLV
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG, retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG,
&(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask), &(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask),
@@ -1822,7 +1858,8 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
end, end,
&pack_uint32_tlv_value); &pack_uint32_tlv_value);
numTLVs++; numTLVs++;
if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
// TLV not supported by Aerial L1
for (int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
// SCF222.10.02 Table 3-25 : If included there must be 64 instances of this TLV // SCF222.10.02 Table 3-25 : If included there must be 64 instances of this TLV
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BEAM_ID_TAG, retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BEAM_ID_TAG,
@@ -1835,13 +1872,34 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
// END SSB Table // END SSB Table
// START TDD Table // START TDD Table
retval &= retval &= pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG,
pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value); &(pNfapiMsg->tdd_table.tdd_period),
ppWritePackedMsg,
end,
&pack_uint8_tlv_value);
numTLVs++; numTLVs++;
// END TDD Table // END TDD Table
for (int i = 0; i < 40; i++) {
for (int k = 0; k < 14; k++) {
pack_nr_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,
&(pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config),
ppWritePackedMsg,
end,
&pack_uint8_tlv_value);
numTLVs++;
}
}
}
// START Measurement Config // START Measurement Config
// SCF222.10.02 Table 3-27 : Contains only one TLV and is currently unused // SCF222.10.02 Table 3-27 : Contains only one TLV and is currently unused
pNfapiMsg->measurement_config.rssi_measurement.tl.tag = NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG;
pNfapiMsg->measurement_config.rssi_measurement.value = 1;
pack_nr_tlv(NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG,
&(pNfapiMsg->measurement_config.rssi_measurement),
ppWritePackedMsg,
end,
&pack_uint8_tlv_value);
numTLVs++;
// END Measurement Config // END Measurement Config
// START Digital Beam Table (DBT) PDU // START Digital Beam Table (DBT) PDU
@@ -1851,7 +1909,7 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
// START Precoding Matrix (PM) PDU // START Precoding Matrix (PM) PDU
// Struct in nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h nfapi_nr_pm_pdu_t, currently unused, tag to use for AERIAL // Struct in nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h nfapi_nr_pm_pdu_t, currently unused, tag to use for AERIAL
// is 0xA011 END Precoding Matrix (PM) PDU // is 0xA011 END Precoding Matrix (PM) PDU
if(NFAPI_MODE != NFAPI_MODE_AERIAL){
// START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states // START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG,
&(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4),
@@ -1901,7 +1959,7 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing CONFIG.request vendor_extension_tlv %d\n", pNfapiMsg->vendor_extension->tag); NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing CONFIG.request vendor_extension_tlv %d\n", pNfapiMsg->vendor_extension->tag);
numTLVs++; numTLVs++;
} }
}
pNfapiMsg->num_tlv = numTLVs; pNfapiMsg->num_tlv = numTLVs;
retval &= push8(pNfapiMsg->num_tlv, &pNumTLVFields, end); retval &= push8(pNfapiMsg->num_tlv, &pNumTLVFields, end);
return retval; return retval;
@@ -2170,7 +2228,7 @@ static uint8_t pack_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_
static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) { static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) {
if (msgEnd < msgHead) { if (msgEnd < msgHead) {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %lu, %lu\n", msgHead, msgEnd); NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %p, %p\n", &msgHead, &msgEnd);
return 0; return 0;
} }
@@ -2178,6 +2236,7 @@ static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) {
} }
// Main pack function - public // Main pack function - public
int nfapi_nr_p5_message_pack(void *pMessageBuf, int nfapi_nr_p5_message_pack(void *pMessageBuf,
uint32_t messageBufLen, uint32_t messageBufLen,
void *pPackedBuf, void *pPackedBuf,
+25 -15
View File
@@ -328,8 +328,8 @@ static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePac
} }
// TODO Add TX power info // TODO Add TX power info
// Hardcoded values that represent 0db // Hardcoded values that represent 0db
if (!(push8(8, ppWritePackedMsg, end) && // powerControlOffset if (!(push8(0, ppWritePackedMsg, end) && // powerControlOffset
push8(1, ppWritePackedMsg, end))) { // powerControlOffsetSS push8(0, ppWritePackedMsg, end))) { // powerControlOffsetSS
return 0; return 0;
} }
// TODO Add CBG Fields // TODO Add CBG Fields
@@ -346,9 +346,8 @@ static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePacke
&& push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && push8(value->bchPayloadFlag, ppWritePackedMsg, end) && push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && push8(value->bchPayloadFlag, ppWritePackedMsg, end)
&& push8((value->bchPayload >> 16) & 0xff, ppWritePackedMsg, end) && push8((value->bchPayload >> 16) & 0xff, ppWritePackedMsg, end)
&& push8((value->bchPayload >> 8) & 0xff, ppWritePackedMsg, end) && push8(value->bchPayload & 0xff, ppWritePackedMsg, end) && push8((value->bchPayload >> 8) & 0xff, ppWritePackedMsg, end) && push8(value->bchPayload & 0xff, ppWritePackedMsg, end)
&& push8(0, ppWritePackedMsg, end) && && push8(0, ppWritePackedMsg, end)
// TODO add Tx Power Info // TODO add Tx Power Info
push8(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end)
&& push16(value->precoding_and_beamforming.num_prgs, ppWritePackedMsg, end) && push16(value->precoding_and_beamforming.num_prgs, ppWritePackedMsg, end)
&& push16(value->precoding_and_beamforming.prg_size, ppWritePackedMsg, end) && push16(value->precoding_and_beamforming.prg_size, ppWritePackedMsg, end)
&& push8(value->precoding_and_beamforming.dig_bf_interfaces, ppWritePackedMsg, end))) { && push8(value->precoding_and_beamforming.dig_bf_interfaces, ppWritePackedMsg, end))) {
@@ -1092,7 +1091,7 @@ static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, ui
} }
static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) { static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
return( if(!(
push16(srs_pdu->rnti, ppWritePackedMsg, end) && push16(srs_pdu->rnti, ppWritePackedMsg, end) &&
push32(srs_pdu->handle, ppWritePackedMsg, end) && push32(srs_pdu->handle, ppWritePackedMsg, end) &&
push16(srs_pdu->bwp_size, ppWritePackedMsg, end) && push16(srs_pdu->bwp_size, ppWritePackedMsg, end) &&
@@ -1117,7 +1116,23 @@ static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t
push16(srs_pdu->t_srs, ppWritePackedMsg, end) && push16(srs_pdu->t_srs, ppWritePackedMsg, end) &&
push16(srs_pdu->t_offset, ppWritePackedMsg, end) push16(srs_pdu->t_offset, ppWritePackedMsg, end)
// TODO: ignoring beamforming tlv for now // TODO: ignoring beamforming tlv for now
); )){
return 0;
}
// Rx Beamforming PDU
if(!(push16(srs_pdu->beamforming.num_prgs,ppWritePackedMsg,end) &&
push16(srs_pdu->beamforming.prg_size,ppWritePackedMsg,end) &&
push8(srs_pdu->beamforming.dig_bf_interface,ppWritePackedMsg,end))){
return 0;
}
for(int prg = 0; prg < srs_pdu->beamforming.num_prgs; prg ++){
for(int digInt = 0; digInt < srs_pdu->beamforming.dig_bf_interface; digInt++){
if(!push16(srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx,ppWritePackedMsg,end)){
return 0;
}
}
}
return 1;
} }
static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu *ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) { static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu *ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
@@ -2002,6 +2017,7 @@ static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8
static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{ {
nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)tlv; nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)tlv;
AssertFatal(value->PDU_length <= 0xFFFF,"TX_DATA.request PDU_Length should be within 16 bit, according to SCF222.10.02");
if (!(push16(value->PDU_length, ppWritePackedMsg, end) && push16(value->PDU_index, ppWritePackedMsg, end) if (!(push16(value->PDU_length, ppWritePackedMsg, end) && push16(value->PDU_index, ppWritePackedMsg, end)
&& push32(value->num_TLV, ppWritePackedMsg, end))) && push32(value->num_TLV, ppWritePackedMsg, end)))
return 0; return 0;
@@ -3153,6 +3169,7 @@ return 1;
static uint8_t pack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end) static uint8_t pack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
{ {
AssertFatal(value->pdu_length <= 0xFFFF,"RX_DATA.indication PDU_Length should be within 16 bit, according to SCF222.10.02");
if(!(push32(value->handle, ppWritePackedMsg, end) && if(!(push32(value->handle, ppWritePackedMsg, end) &&
push16(value->rnti, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end) &&
push8(value->harq_id, ppWritePackedMsg, end) && push8(value->harq_id, ppWritePackedMsg, end) &&
@@ -5886,7 +5903,7 @@ static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, v
static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) { static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
nfapi_nr_pdu_t *pNfapiMsg = (nfapi_nr_pdu_t *)msg; nfapi_nr_pdu_t *pNfapiMsg = (nfapi_nr_pdu_t *)msg;
if(!(pull16(ppReadPackedMsg, &pNfapiMsg->PDU_length, end) && if(!(pull16(ppReadPackedMsg, (uint16_t *)&pNfapiMsg->PDU_length, end) &&
pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end) && pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end) &&
pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end) pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end)
)) ))
@@ -5939,13 +5956,6 @@ static uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, v
for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) { for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i])) { if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i])) {
printf("%s():%d. Error packing TX_DATA.request PDU #%d, PDU length = %d PDU IDX = %d\n",
__FUNCTION__,
__LINE__,
i,
pNfapiMsg->pdu_list[i].PDU_length,
pNfapiMsg->pdu_list[i].PDU_index);
return 0; return 0;
} }
} }
@@ -6065,7 +6075,7 @@ static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value,
nfapi_p7_codec_config_t *config) nfapi_p7_codec_config_t *config)
{ {
if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end) if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
&& pull8(ppReadPackedMsg, &value->harq_id, end) && pull16(ppReadPackedMsg, &value->pdu_length, end) && pull8(ppReadPackedMsg, &value->harq_id, end) && pull16(ppReadPackedMsg, (uint16_t *)&value->pdu_length, end)
&& pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end) && pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
&& pull16(ppReadPackedMsg, &value->rssi, end))) && pull16(ppReadPackedMsg, &value->rssi, end)))
return 0; return 0;
+4 -2
View File
@@ -2040,8 +2040,10 @@ int pnf_read_dispatch_message(pnf_t* pnf)
{ {
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n"); NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n");
return 0; return 0;
}else{
NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Unpack p5 message header success\n");
} }
message_size = header.message_length; message_size = header.message_length+header_buffer_size;
// now have the size of the mesage // now have the size of the mesage
} }
@@ -2206,7 +2208,7 @@ int pnf_nr_read_dispatch_message(pnf_t* pnf)
// print the received message // print the received message
printf("\n MESSAGE RECEIVED: \n"); printf("\n MESSAGE RECEIVED: \n");
for(int i=0; i<message_size; i++){ for(int i=0; i<message_size; i++){
printf("%d", read_buffer[i]); printf("read_buffer[%d] = 0x%02x\n",i, read_buffer[i]);
} }
printf("\n"); printf("\n");
#endif #endif
+35 -6
View File
@@ -27,7 +27,11 @@
#include "vnf.h" #include "vnf.h"
#include "nfapi_nr_interface.h" #include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h" #include "nfapi_nr_interface_scf.h"
#ifdef ENABLE_AERIAL
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h"
#endif
#include "nfapi/oai_integration/vendor_ext.h"
void* vnf_malloc(nfapi_vnf_config_t* config, size_t size) void* vnf_malloc(nfapi_vnf_config_t* config, size_t size)
{ {
@@ -1520,20 +1524,45 @@ int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_mes
if(pnf) if(pnf)
{ {
// pack the message for transmission // pack the message for transmission
int packedMessageLength = nfapi_nr_p5_message_pack(msg, msg_len, vnf->tx_message_buffer, sizeof(vnf->tx_message_buffer), &vnf->_public.codec_config); int packedMessageLength = 0;
if (NFAPI_MODE == NFAPI_MODE_AERIAL) {
#ifdef ENABLE_AERIAL
// In case it is a FAPI message, create 2 messages, one with nFAPI header for OAI PNF and one with no nFAPI header for Aerial
// L1
nfapi_p4_p5_message_header_t *msgFAPI = calloc(1, msg_len);
memcpy(msgFAPI, msg, msg_len);
// create FAPI tx_buffer
uint8_t tx_messagebufferFAPI[sizeof(vnf->tx_message_buffer)];
int packedMessageLengthFAPI = -1;
packedMessageLengthFAPI =
fapi_nr_p5_message_pack(msgFAPI, msg_len, tx_messagebufferFAPI, sizeof(tx_messagebufferFAPI), &vnf->_public.codec_config);
return aerial_send_P5_msg(tx_messagebufferFAPI, packedMessageLengthFAPI, msg);
#else
return 0;
#endif
} else {
packedMessageLength = nfapi_nr_p5_message_pack(msg,
msg_len,
vnf->tx_message_buffer,
sizeof(vnf->tx_message_buffer),
&vnf->_public.codec_config);
if (packedMessageLength < 0) if (packedMessageLength < 0) {
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength); NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength);
return -1; return -1;
} }
// printf("msg id = 0x%02x, entire message length: %d\n", msg->message_id, packedMessageLength);
// for (int i = 0; i < packedMessageLength; i++) {
// printf(" msg->msg_buf[%d] = 0x%02x\n", i, ((uint8_t *) vnf->tx_message_buffer)[i]);
// }
return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0); return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0);
} }
else } else {
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx); NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx);
return -1; return -1;
} }
} }
+3 -1
View File
@@ -25,7 +25,9 @@
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#ifdef ENABLE_AERIAL
#include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
#endif
#include "vnf_p7.h" #include "vnf_p7.h"
#ifdef NDEBUG #ifdef NDEBUG
+33 -7
View File
@@ -29,6 +29,9 @@
* \note * \note
* \warning * \warning
*/ */
#ifdef ENABLE_AERIAL
#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h"
#endif
#include "fapi_nr_l1.h" #include "fapi_nr_l1.h"
#include "common/ran_context.h" #include "common/ran_context.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h"
@@ -37,7 +40,6 @@
#include "nfapi/oai_integration/vendor_ext.h" #include "nfapi/oai_integration/vendor_ext.h"
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h" #include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
extern int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req); extern int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
extern int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req); extern int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req);
extern int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req); extern int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req);
@@ -237,19 +239,43 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
} }
} }
if (NFAPI_MODE == NFAPI_MODE_VNF) { //If VNF, oai_nfapi functions send respective p7 msgs to PNF for which nPDUs is greater than 0 if (NFAPI_MODE == NFAPI_MODE_VNF) { // If VNF, oai_nfapi functions send respective p7 msgs to PNF for which nPDUs > 0
if(number_ul_tti_pdu>0) if (number_ul_tti_pdu > 0)
oai_nfapi_ul_tti_req(UL_tti_req); oai_nfapi_ul_tti_req(UL_tti_req);
if (number_ul_dci_pdu>0) if (number_ul_dci_pdu > 0)
oai_nfapi_ul_dci_req(UL_dci_req); oai_nfapi_ul_dci_req(UL_dci_req);
if (number_tx_data_pdu>0) if (number_dl_pdu > 0)
oai_nfapi_dl_tti_req(DL_req);
if (number_tx_data_pdu > 0)
oai_nfapi_tx_data_req(TX_req); oai_nfapi_tx_data_req(TX_req);
if (number_dl_pdu>0) } else if (NFAPI_MODE == NFAPI_MODE_AERIAL) {
oai_nfapi_dl_tti_req(DL_req); #ifdef ENABLE_AERIAL
bool send_slt_resp = false;
if (number_dl_pdu > 0) {
oai_fapi_dl_tti_req(DL_req);
send_slt_resp = true;
}
if (number_ul_tti_pdu > 0) {
oai_fapi_ul_tti_req(UL_tti_req);
send_slt_resp = true;
}
if (number_tx_data_pdu > 0) {
oai_fapi_tx_data_req(TX_req);
send_slt_resp = true;
}
if (number_ul_dci_pdu > 0) {
oai_fapi_ul_dci_req(UL_dci_req);
send_slt_resp = true;
}
if (send_slt_resp) {
oai_fapi_send_end_request(0,frame,slot);
}
#endif
} }
/* this thread is done with the sched_info, decrease the reference counter */ /* this thread is done with the sched_info, decrease the reference counter */
+8
View File
@@ -91,6 +91,9 @@
#include "RRC/NR/nr_rrc_extern.h" #include "RRC/NR/nr_rrc_extern.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
#include "nfapi/oai_integration/vendor_ext.h" #include "nfapi/oai_integration/vendor_ext.h"
#ifdef ENABLE_AERIAL
#include "nfapi/oai_integration/aerial/fapi_vnf_p5.h"
#endif
extern uint16_t sf_ahead; extern uint16_t sf_ahead;
@@ -1303,6 +1306,11 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
configure_nr_nfapi_vnf( configure_nr_nfapi_vnf(
RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc, RC.nrmac[j]->eth_params_s.remote_addr, RC.nrmac[j]->eth_params_s.remote_portd, RC.nrmac[j]->eth_params_s.my_portd); RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc, RC.nrmac[j]->eth_params_s.remote_addr, RC.nrmac[j]->eth_params_s.remote_portd, RC.nrmac[j]->eth_params_s.my_portd);
printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc); printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc);
} else if(strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "aerial") == 0){
#ifdef ENABLE_AERIAL
printf("Configuring VNF for Aerial connection\n");
aerial_configure_nr_fapi_vnf();
#endif
} else { // other midhaul } else { // other midhaul
AssertFatal(1 == 0, "MACRLC %d: %s unknown southbound midhaul\n", j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); AssertFatal(1 == 0, "MACRLC %d: %s unknown southbound midhaul\n", j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
} }
+8 -5
View File
@@ -708,6 +708,12 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG; cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
cfg->num_tlv++; cfg->num_tlv++;
uint8_t *mib_payload = nrmac->common_channels[0].MIB_pdu;
uint32_t mib = (mib_payload[2] << 16) | (mib_payload[1] << 8) | mib_payload[0];
cfg->ssb_table.MIB.tl.tag = NFAPI_NR_CONFIG_MIB_TAG;
cfg->ssb_table.MIB.value = mib;
cfg->num_tlv++;
nrmac->ssb_SubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; nrmac->ssb_SubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value;
nrmac->ssb_OffsetPointA = cfg->ssb_table.ssb_offset_point_a.value; nrmac->ssb_OffsetPointA = cfg->ssb_table.ssb_offset_point_a.value;
LOG_I(NR_MAC, LOG_I(NR_MAC,
@@ -837,11 +843,8 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
config_common(nrmac, config->pdsch_AntennaPorts, config->pusch_AntennaPorts, scc); config_common(nrmac, config->pdsch_AntennaPorts, config->pusch_AntennaPorts, scc);
if (NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) { if (NFAPI_MODE == NFAPI_MONOLITHIC) {
// fake that the gNB is configured in nFAPI mode, which would normally be // nothing to be sent in the other cases
// done in a NR_PHY_config_req, but in this mode, there is no PHY
RC.gNB[0]->configured = 1;
} else {
NR_PHY_Config_t phycfg = {.Mod_id = 0, .CC_id = 0, .cfg = &nrmac->config[0]}; NR_PHY_Config_t phycfg = {.Mod_id = 0, .CC_id = 0, .cfg = &nrmac->config[0]};
DevAssert(nrmac->if_inst->NR_PHY_config_req); DevAssert(nrmac->if_inst->NR_PHY_config_req);
nrmac->if_inst->NR_PHY_config_req(&phycfg); nrmac->if_inst->NR_PHY_config_req(&phycfg);
@@ -91,6 +91,53 @@ void clear_nr_nfapi_information(gNB_MAC_INST *gNB,
future_ul_tti_req->SFN = (prev_slot / num_slots) % 1024; future_ul_tti_req->SFN = (prev_slot / num_slots) % 1024;
LOG_D(NR_MAC, "%d.%d UL_tti_req_ahead SFN.slot = %d.%d for index %d \n", frameP, slotP, future_ul_tti_req->SFN, future_ul_tti_req->Slot, prev_slot % size); LOG_D(NR_MAC, "%d.%d UL_tti_req_ahead SFN.slot = %d.%d for index %d \n", frameP, slotP, future_ul_tti_req->SFN, future_ul_tti_req->Slot, prev_slot % size);
/* future_ul_tti_req->Slot is fixed! */ /* future_ul_tti_req->Slot is fixed! */
for (int i = 0; i < future_ul_tti_req->n_pdus; i++) {
switch(future_ul_tti_req->pdus_list[i].pdu_type){
case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
if(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list){
for (int j = 0; j < future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.num_prgs; ++j) {
if(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list[j].dig_bf_interface_list){
free(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list[j].dig_bf_interface_list);
}
}
free(future_ul_tti_req->pdus_list[i].prach_pdu.beamforming.prgs_list);
}
break;
case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
if(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list){
for (int j = 0; j < future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.num_prgs; ++j) {
if(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list[j].dig_bf_interface_list){
free(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list[j].dig_bf_interface_list);
}
}
free(future_ul_tti_req->pdus_list[i].pusch_pdu.beamforming.prgs_list);
}
break;
case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
if(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list){
for (int j = 0; j < future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.num_prgs; ++j) {
if(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list[j].dig_bf_interface_list){
free(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list[j].dig_bf_interface_list);
}
}
free(future_ul_tti_req->pdus_list[i].pucch_pdu.beamforming.prgs_list);
}
break;
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
if(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list){
for (int j = 0; j < future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.num_prgs; ++j) {
if(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list[j].dig_bf_interface_list){
free(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list[j].dig_bf_interface_list);
}
}
free(future_ul_tti_req->pdus_list[i].srs_pdu.beamforming.prgs_list);
}
default:
break;
}
future_ul_tti_req->pdus_list[i].pdu_type = 0;
future_ul_tti_req->pdus_list[i].pdu_size = 0;
}
future_ul_tti_req->n_pdus = 0; future_ul_tti_req->n_pdus = 0;
future_ul_tti_req->n_ulsch = 0; future_ul_tti_req->n_ulsch = 0;
future_ul_tti_req->n_ulcch = 0; future_ul_tti_req->n_ulcch = 0;
+31 -1
View File
@@ -317,6 +317,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
UL_tti_req->SFN = frameP; UL_tti_req->SFN = frameP;
UL_tti_req->Slot = slotP; UL_tti_req->Slot = slotP;
UL_tti_req->rach_present = 1;
for (int fdm_index=0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion for (int fdm_index=0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion
for (int td_index=0; td_index<N_t_slot; td_index++) { for (int td_index=0; td_index<N_t_slot; td_index++) {
@@ -498,7 +499,11 @@ static void nr_schedule_msg2(uint16_t rach_frame,
while ((eff_slot-rach_slot)<=sl_ahead) { while ((eff_slot-rach_slot)<=sl_ahead) {
eff_slot += tdd_period_slot; eff_slot += tdd_period_slot;
} }
#ifdef ENABLE_AERIAL
if (nfapi_mode > 0) { // Aerial needs slot_ahead = 0, requiring addition of another TDD period
eff_slot += tdd_period_slot;
}
#endif
int FR = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257 ? nr_FR2 : nr_FR1; int FR = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257 ? nr_FR2 : nr_FR1;
if (FR==nr_FR2) { if (FR==nr_FR2) {
int num_tdd_period = (eff_slot%nr_slots_per_frame[mu])/tdd_period_slot; int num_tdd_period = (eff_slot%nr_slots_per_frame[mu])/tdd_period_slot;
@@ -1052,10 +1057,12 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
LOG_D(NR_MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d, ul_dmrs_symb_pos:%x\n", start_symbol_index, nr_of_symbols, mappingtype, pusch_pdu->ul_dmrs_symb_pos); LOG_D(NR_MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d, ul_dmrs_symb_pos:%x\n", start_symbol_index, nr_of_symbols, mappingtype, pusch_pdu->ul_dmrs_symb_pos);
pusch_pdu->dmrs_config_type = 0; pusch_pdu->dmrs_config_type = 0;
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
pusch_pdu->pusch_identity = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0. pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used
pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214 pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214
pusch_pdu->resource_alloc = 1; //type 1 pusch_pdu->resource_alloc = 1; //type 1
memset(pusch_pdu->rb_bitmap, 0, sizeof(pusch_pdu->rb_bitmap));
pusch_pdu->rb_start = msg3_first_rb; pusch_pdu->rb_start = msg3_first_rb;
if (msg3_nb_rb > pusch_pdu->bwp_size) if (msg3_nb_rb > pusch_pdu->bwp_size)
AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n"); AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n");
@@ -1077,6 +1084,23 @@ static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
pusch_pdu->pusch_data.harq_process_id = 0; pusch_pdu->pusch_data.harq_process_id = 0;
pusch_pdu->pusch_data.new_data_indicator = (round == 0) ? 1 : 0;; pusch_pdu->pusch_data.new_data_indicator = (round == 0) ? 1 : 0;;
pusch_pdu->pusch_data.num_cb = 0; pusch_pdu->pusch_data.num_cb = 0;
// Beamforming
pusch_pdu->beamforming.num_prgs = 0;
pusch_pdu->beamforming.prg_size = 0; // bwp_size;
pusch_pdu->beamforming.dig_bf_interface = 0;
if (pusch_pdu->beamforming.num_prgs > 0) {
if (pusch_pdu->beamforming.prgs_list == NULL) {
pusch_pdu->beamforming.prgs_list = calloc(pusch_pdu->beamforming.num_prgs, sizeof(*pusch_pdu->beamforming.prgs_list));
}
if (pusch_pdu->beamforming.dig_bf_interface > 0) {
if (pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list == NULL) {
pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list =
calloc(pusch_pdu->beamforming.dig_bf_interface, sizeof(*pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list));
}
}
pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
}
int num_dmrs_symb = 0; int num_dmrs_symb = 0;
for(int i = start_symbol_index; i < start_symbol_index+nr_of_symbols; i++) for(int i = start_symbol_index; i < start_symbol_index+nr_of_symbols; i++)
num_dmrs_symb += (pusch_pdu->ul_dmrs_symb_pos >> i) & 1; num_dmrs_symb += (pusch_pdu->ul_dmrs_symb_pos >> i) & 1;
@@ -1279,6 +1303,12 @@ static void nr_generate_Msg2(module_id_t module_idP,
dl_req->nPDUs+=1; dl_req->nPDUs+=1;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
pdsch_pdu_rel15->precodingAndBeamforming.num_prgs = 0;
pdsch_pdu_rel15->precodingAndBeamforming.prg_size = 0;
pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces = 0;
pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0;
pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
LOG_A(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n", LOG_A(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n",
module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state,pdcch_pdu_rel15->CoreSetType); module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state,pdcch_pdu_rel15->CoreSetType);
@@ -426,6 +426,12 @@ static void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
dl_req->nPDUs += 1; dl_req->nPDUs += 1;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=0;
pdsch_pdu_rel15->precodingAndBeamforming.prg_size=0;
pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces=0;
pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0;
pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
pdcch_pdu_rel15->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; pdcch_pdu_rel15->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
pdsch_pdu_rel15->pduBitmap = 0; pdsch_pdu_rel15->pduBitmap = 0;
@@ -1066,6 +1066,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
pdsch_pdu->qamModOrder[0] = Qm; pdsch_pdu->qamModOrder[0] = Qm;
pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs; pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs;
pdsch_pdu->mcsTable[0] = current_BWP->mcsTableIdx; pdsch_pdu->mcsTable[0] = current_BWP->mcsTableIdx;
// NVIDIA: Workaround for MCSTableIdx mismatch error
if (nr_get_code_rate_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx) != R) {
pdsch_pdu->mcsTable[0] = 0;
}
AssertFatal(harq!=NULL,"harq is null\n"); AssertFatal(harq!=NULL,"harq is null\n");
AssertFatal(harq->round<gNB_mac->dl_bler.harq_round_max,"%d",harq->round); AssertFatal(harq->round<gNB_mac->dl_bler.harq_round_max,"%d",harq->round);
pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round%4]; pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round%4];
@@ -1090,8 +1094,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
pdsch_pdu->StartSymbolIndex = tda_info->startSymbolIndex; pdsch_pdu->StartSymbolIndex = tda_info->startSymbolIndex;
pdsch_pdu->NrOfSymbols = tda_info->nrOfSymbols; pdsch_pdu->NrOfSymbols = tda_info->nrOfSymbols;
// Precoding // Precoding
pdsch_pdu->precodingAndBeamforming.num_prgs = 0;
pdsch_pdu->precodingAndBeamforming.prg_size = pdsch_pdu->rbSize; pdsch_pdu->precodingAndBeamforming.prg_size = pdsch_pdu->rbSize;
pdsch_pdu->precodingAndBeamforming.dig_bf_interfaces = 0;
pdsch_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = sched_pdsch->pm_index; pdsch_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = sched_pdsch->pm_index;
pdsch_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
// TBS_LBRM according to section 5.4.2.1 of 38.212 // TBS_LBRM according to section 5.4.2.1 of 38.212
// TODO: verify the case where maxMIMO_Layers is NULL, in which case // TODO: verify the case where maxMIMO_Layers is NULL, in which case
// in principle maxMIMO_layers should be given by the maximum number of layers // in principle maxMIMO_layers should be given by the maximum number of layers
@@ -1146,6 +1153,13 @@ void nr_schedule_ue_spec(module_id_t module_id,
dci_pdu->CceIndex = sched_ctrl->cce_index; dci_pdu->CceIndex = sched_ctrl->cce_index;
dci_pdu->beta_PDCCH_1_0 = 0; dci_pdu->beta_PDCCH_1_0 = 0;
dci_pdu->powerControlOffsetSS = 1; dci_pdu->powerControlOffsetSS = 1;
dci_pdu->precodingAndBeamforming.num_prgs = 0;
dci_pdu->precodingAndBeamforming.prg_size = 0;
dci_pdu->precodingAndBeamforming.dig_bf_interfaces = 0;
dci_pdu->precodingAndBeamforming.prgs_list[0].pm_idx = 0;
dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
/* DCI payload */ /* DCI payload */
dci_pdu_rel15_t dci_payload; dci_pdu_rel15_t dci_payload;
memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t)); memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t));
@@ -57,6 +57,7 @@
#define DEBUG_gNB_SCHEDULER 1 #define DEBUG_gNB_SCHEDULER 1
#include "common/ran_context.h" #include "common/ran_context.h"
#include "nfapi/oai_integration/vendor_ext.h"
//#define DEBUG_DCI //#define DEBUG_DCI
@@ -227,13 +228,23 @@ NR_pdsch_dmrs_t get_dl_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
switch (Layers) { switch (Layers) {
case 1: case 1:
#ifdef ENABLE_AERIAL
dmrs.dmrs_ports_id = 3;
dmrs.numDmrsCdmGrpsNoData = 2;
#else
dmrs.dmrs_ports_id = 0; dmrs.dmrs_ports_id = 0;
dmrs.numDmrsCdmGrpsNoData = 1; dmrs.numDmrsCdmGrpsNoData = 1;
#endif
frontloaded_symb = 1; frontloaded_symb = 1;
break; break;
case 2: case 2:
#ifdef ENABLE_AERIAL
dmrs.dmrs_ports_id = 7;
dmrs.numDmrsCdmGrpsNoData = 2;
#else
dmrs.dmrs_ports_id = 2; dmrs.dmrs_ports_id = 2;
dmrs.numDmrsCdmGrpsNoData = 1; dmrs.numDmrsCdmGrpsNoData = 1;
#endif
frontloaded_symb = 1; frontloaded_symb = 1;
break; break;
case 3: case 3:
@@ -606,10 +617,14 @@ NR_pusch_dmrs_t get_ul_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
NR_pusch_dmrs_t dmrs = {0}; NR_pusch_dmrs_t dmrs = {0};
// TODO setting of cdm groups with no data to be redone for MIMO // TODO setting of cdm groups with no data to be redone for MIMO
if(NFAPI_MODE == NFAPI_MODE_AERIAL) {
dmrs.num_dmrs_cdm_grps_no_data = 2;
} else {
if (ul_bwp->transform_precoding && Layers < 3) if (ul_bwp->transform_precoding && Layers < 3)
dmrs.num_dmrs_cdm_grps_no_data = ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_1 || tda_info->nrOfSymbols == 2 ? 1 : 2; dmrs.num_dmrs_cdm_grps_no_data = ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_1 || tda_info->nrOfSymbols == 2 ? 1 : 2;
else else
dmrs.num_dmrs_cdm_grps_no_data = 2; dmrs.num_dmrs_cdm_grps_no_data = 2;
}
NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = ul_bwp->pusch_Config ? NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = ul_bwp->pusch_Config ?
(tda_info->mapping_type == typeA ? (tda_info->mapping_type == typeA ?
@@ -738,7 +753,8 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info,
// antenna_ports.val = 0 for transform precoder is disabled, dmrs-Type=1, maxLength=1, Rank=1/2/3/4 // antenna_ports.val = 0 for transform precoder is disabled, dmrs-Type=1, maxLength=1, Rank=1/2/3/4
// Antenna Ports // Antenna Ports
dci_pdu_rel15->antenna_ports.val = 0;
dci_pdu_rel15->antenna_ports.val = NFAPI_MODE == NFAPI_MODE_AERIAL ? 2 : 0;
// DMRS sequence initialization // DMRS sequence initialization
dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid; dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid;
@@ -1031,6 +1047,22 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t *pucch_pdu,
pucch_pdu->sr_flag = O_sr; pucch_pdu->sr_flag = O_sr;
pucch_pdu->prb_size=1; pucch_pdu->prb_size=1;
} }
// Beamforming
pucch_pdu->beamforming.num_prgs = 0;
pucch_pdu->beamforming.prg_size = 0; // pucch_pdu->prb_size;
pucch_pdu->beamforming.dig_bf_interface = 0;
if (pucch_pdu->beamforming.num_prgs > 0) {
if (pucch_pdu->beamforming.prgs_list == NULL) {
pucch_pdu->beamforming.prgs_list = calloc(pucch_pdu->beamforming.num_prgs, sizeof(*pucch_pdu->beamforming.prgs_list));
}
if (pucch_pdu->beamforming.dig_bf_interface > 0) {
if (pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list == NULL) {
pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list =
calloc(pucch_pdu->beamforming.dig_bf_interface, sizeof(*pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list));
}
}
pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
}
} }
void set_r_pucch_parms(int rsetindex, void set_r_pucch_parms(int rsetindex,
@@ -2580,9 +2612,9 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator); delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator);
} }
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) { uint8_t nr_get_tpc(int target, int snrx10, int incr)
// al values passed to this function are x10 {
int snrx10 = (cqi*5) - 640; // all values passed to this function are in dB x10
if (snrx10 > target + incr) return 0; // decrease 1dB if (snrx10 > target + incr) return 0; // decrease 1dB
if (snrx10 < target - (3*incr)) return 3; // increase 3dB if (snrx10 < target - (3*incr)) return 3; // increase 3dB
if (snrx10 < target - incr) return 2; // increase 1dB if (snrx10 < target - incr) return 2; // increase 1dB
@@ -1042,11 +1042,11 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
} }
// tpc (power control) only if we received AckNack // tpc (power control) only if we received AckNack
if (uci_01->harq.harq_confidence_level==0) if (uci_01->harq.harq_confidence_level == 0 && uci_01->ul_cqi != 0xff) {
sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, uci_01->ul_cqi, 30);
else
sched_ctrl->tpc1 = 3;
sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640; sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, sched_ctrl->pucch_snrx10, 30);
} else
sched_ctrl->tpc1 = 1;
} }
// check scheduling request result, confidence_level == 0 is good // check scheduling request result, confidence_level == 0 is good
@@ -1085,10 +1085,10 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
// tpc (power control) // tpc (power control)
// TODO PUCCH2 SNR computation is not correct -> ignore the following // TODO PUCCH2 SNR computation is not correct -> ignore the following
//sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, if (uci_234->ul_cqi != 0xff) {
// uci_234->ul_cqi, sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640;
// 30); sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, sched_ctrl->pucch_snrx10, 30);
//sched_ctrl->pucch_snrx10 = uci_234->ul_cqi * 5 - 640; }
// TODO: handle SR // TODO: handle SR
if (uci_234->pduBitmap & 0x1) { if (uci_234->pduBitmap & 0x1) {
@@ -625,11 +625,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
// if not missed detection (10dB threshold for now) // if not missed detection (10dB threshold for now)
if (rssi>0) { if (rssi>0) {
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30); if (ul_cqi != 0xff) {
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, UE_scheduling_control->pusch_snrx10, 30);
}
if (timing_advance != 0xffff) if (timing_advance != 0xffff)
UE_scheduling_control->ta_update = timing_advance; UE_scheduling_control->ta_update = timing_advance;
UE_scheduling_control->raw_rssi = rssi; UE_scheduling_control->raw_rssi = rssi;
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update); LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
} }
@@ -670,7 +672,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
if (UE_scheduling_control->sched_ul_bytes < 0) if (UE_scheduling_control->sched_ul_bytes < 0)
UE_scheduling_control->sched_ul_bytes = 0; UE_scheduling_control->sched_ul_bytes = 0;
} }
if (ul_cqi <= 128) { if (ul_cqi == 0xff || ul_cqi <= 128) {
UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt++; UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt++;
UE->mac_stats.ulsch_DTX++; UE->mac_stats.ulsch_DTX++;
} }
@@ -756,7 +758,10 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_msg3_stage->UE_sched_ctrl; NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_msg3_stage->UE_sched_ctrl;
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, ul_cqi, 30); if (ul_cqi != 0xff) {
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10, UE_scheduling_control->pusch_snrx10, 30);
}
if (timing_advance != 0xffff) if (timing_advance != 0xffff)
UE_scheduling_control->ta_update = timing_advance; UE_scheduling_control->ta_update = timing_advance;
UE_scheduling_control->raw_rssi = rssi; UE_scheduling_control->raw_rssi = rssi;
@@ -2245,11 +2250,15 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n
pusch_pdu->num_dmrs_cdm_grps_no_data = sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data; pusch_pdu->num_dmrs_cdm_grps_no_data = sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data;
/* FAPI: DMRS */ /* FAPI: DMRS */
pusch_pdu->num_dmrs_cdm_grps_no_data = sched_pusch->dmrs_info.num_dmrs_cdm_grps_no_data;
pusch_pdu->dmrs_ports = ((1<<sched_pusch->nrOfLayers) - 1);
pusch_pdu->ul_dmrs_symb_pos = sched_pusch->dmrs_info.ul_dmrs_symb_pos; pusch_pdu->ul_dmrs_symb_pos = sched_pusch->dmrs_info.ul_dmrs_symb_pos;
pusch_pdu->dmrs_config_type = sched_pusch->dmrs_info.dmrs_config_type; pusch_pdu->dmrs_config_type = sched_pusch->dmrs_info.dmrs_config_type;
pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]
const NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = get_DMRS_UplinkConfig(current_BWP->pusch_Config, &sched_pusch->tda_info); const NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = get_DMRS_UplinkConfig(current_BWP->pusch_Config, &sched_pusch->tda_info);
if (pusch_pdu->transform_precoding) { // transform precoding disabled if (pusch_pdu->transform_precoding) { // transform precoding disabled
long *scramblingid=NULL; long *scramblingid=NULL;
pusch_pdu->pusch_identity = *scc->physCellId;
if (NR_DMRS_UplinkConfig && pusch_pdu->scid == 0) if (NR_DMRS_UplinkConfig && pusch_pdu->scid == 0)
scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0; scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0;
else if (NR_DMRS_UplinkConfig) else if (NR_DMRS_UplinkConfig)
@@ -2356,7 +2365,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus]; nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus];
memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t)); memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t));
ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); ul_dci_request_pdu->PDUSize = (uint8_t)(4+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
ul_dci_req->numPdus += 1; ul_dci_req->numPdus += 1;
nr_configure_pdcch(pdcch_pdu, coreset, &sched_ctrl->sched_pdcch); nr_configure_pdcch(pdcch_pdu, coreset, &sched_ctrl->sched_pdcch);
+1 -1
View File
@@ -272,7 +272,7 @@ NR_pusch_dmrs_t get_ul_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
const NR_tda_info_t *tda_info, const NR_tda_info_t *tda_info,
const int Layers); const int Layers);
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr); uint8_t nr_get_tpc(int target, int snrx10, int incr);
int get_spf(nfapi_nr_config_request_scf_t *cfg); int get_spf(nfapi_nr_config_request_scf_t *cfg);
+6 -6
View File
@@ -202,12 +202,12 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info)
UL_info->CC_id, UL_info->CC_id,
UL_info->rx_ind.sfn, UL_info->rx_ind.sfn,
UL_info->rx_ind.slot, UL_info->rx_ind.slot,
rx->rnti, crc->rnti,
crc->tb_crc_status ? NULL : rx->pdu, crc->tb_crc_status ? NULL : rx->pdu,
rx->pdu_length, rx->pdu_length,
rx->timing_advance, crc->timing_advance,
rx->ul_cqi, crc->ul_cqi,
rx->rssi); crc->rssi);
handle_nr_ul_harq(UL_info->CC_id, UL_info->module_id, UL_info->frame, UL_info->slot, crc); handle_nr_ul_harq(UL_info->CC_id, UL_info->module_id, UL_info->frame, UL_info->slot, crc);
} }
} }
@@ -440,7 +440,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
nfapi_nr_uci_indication_t *uci_ind = NULL; nfapi_nr_uci_indication_t *uci_ind = NULL;
nfapi_nr_rx_data_indication_t *rx_ind = NULL; nfapi_nr_rx_data_indication_t *rx_ind = NULL;
nfapi_nr_crc_indication_t *crc_ind = NULL; nfapi_nr_crc_indication_t *crc_ind = NULL;
if (get_softmodem_params()->emulate_l1) if (get_softmodem_params()->emulate_l1 || NFAPI_MODE == NFAPI_MODE_AERIAL)
{ {
if (gnb_rach_ind_queue.num_items > 0) { if (gnb_rach_ind_queue.num_items > 0) {
LOG_D(NR_MAC, "gnb_rach_ind_queue size = %zu\n", gnb_rach_ind_queue.num_items); LOG_D(NR_MAC, "gnb_rach_ind_queue size = %zu\n", gnb_rach_ind_queue.num_items);
@@ -483,7 +483,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
handle_nr_ulsch(UL_info); handle_nr_ulsch(UL_info);
handle_nr_srs(UL_info); handle_nr_srs(UL_info);
if (get_softmodem_params()->emulate_l1) { if (get_softmodem_params()->emulate_l1 || NFAPI_MODE == NFAPI_MODE_AERIAL) {
free_unqueued_nfapi_indications(rach_ind, uci_ind, rx_ind, crc_ind); free_unqueued_nfapi_indications(rach_ind, uci_ind, rx_ind, crc_ind);
} }
} }
+5 -5
View File
@@ -26,7 +26,7 @@ void handle_rach(UL_IND_t *UL_info) {
int i; int i;
int j = UL_info->subframe; int j = UL_info->subframe;
AssertFatal(j < sizeof(UL_RCC_INFO.rach_ind) / sizeof(UL_RCC_INFO.rach_ind[0]), "j index out of range of index of rach_ind\n"); AssertFatal(j < sizeof(UL_RCC_INFO.rach_ind) / sizeof(UL_RCC_INFO.rach_ind[0]), "j index out of range of index of rach_ind\n");
if (NFAPI_MODE == NFAPI_MODE_VNF) if (NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL)
{ {
if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles > 0) if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles > 0)
{ {
@@ -97,7 +97,7 @@ void handle_sr(UL_IND_t *UL_info) {
if (UL_info->sr_ind.sr_indication_body.number_of_srs>0) { if (UL_info->sr_ind.sr_indication_body.number_of_srs>0) {
oai_nfapi_sr_indication(&UL_info->sr_ind); oai_nfapi_sr_indication(&UL_info->sr_ind);
} }
} else if(NFAPI_MODE == NFAPI_MODE_VNF) { } else if(NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) {
for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) { for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) {
if(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs > 0) { if(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs > 0) {
assert(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU); assert(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU);
@@ -140,7 +140,7 @@ void handle_cqi(UL_IND_t *UL_info) {
oai_nfapi_cqi_indication(&UL_info->cqi_ind); oai_nfapi_cqi_indication(&UL_info->cqi_ind);
UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0; UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0;
} }
} else if (NFAPI_MODE == NFAPI_MODE_VNF) { } else if (NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) {
for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) { for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) {
if(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis > 0) { if(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis > 0) {
assert(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); assert(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU);
@@ -187,7 +187,7 @@ void handle_harq(UL_IND_t *UL_info) {
} }
UL_info->harq_ind.harq_indication_body.number_of_harqs = 0; UL_info->harq_ind.harq_indication_body.number_of_harqs = 0;
} else if(NFAPI_MODE == NFAPI_MODE_VNF) { } else if(NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) {
for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) { for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) {
if(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs > 0) { if(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs > 0) {
assert(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); assert(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU);
@@ -232,7 +232,7 @@ void handle_ulsch(UL_IND_t *UL_info) {
oai_nfapi_rx_ind(&UL_info->rx_ind); oai_nfapi_rx_ind(&UL_info->rx_ind);
UL_info->rx_ind.rx_indication_body.number_of_pdus = 0; UL_info->rx_ind.rx_indication_body.number_of_pdus = 0;
} }
} else if(NFAPI_MODE == NFAPI_MODE_VNF) { } else if(NFAPI_MODE == NFAPI_MODE_VNF || NFAPI_MODE == NFAPI_MODE_AERIAL) {
for(uint8_t k = 0; k < NUM_NFAPI_SUBFRAME; k++) { for(uint8_t k = 0; k < NUM_NFAPI_SUBFRAME; k++) {
if((UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus>0) && (UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs>0)) { if((UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus>0) && (UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs>0)) {
assert(UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU); assert(UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU);
@@ -0,0 +1,262 @@
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
sa = 1;
nfapi = "AERIAL";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({
mcc = 001;
mnc = 01;
mnc_length = 2;
snssaiList = (
{
sst = 1;
}
);
});
nr_cellid = 12345678L;
////////// Physical parameters:
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;
do_CSIRS = 1;
do_SRS = 0;
min_rxtxtime = 2;
pdcch_ConfigSIB1 = (
{
controlResourceSetZero = 12;
searchSpaceZero = 0;
}
);
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3300.24 + 134*12*30e3 = 3348.48 MHz (5G NR GSCN: 7741)
absoluteFrequencySSB = 649920;
#652860; #should be 649920
#647520;
#647540;
#649920;
#650208;
#647540;
dl_frequencyBand = 78;
# this is 3300.24 MHz
dl_absoluteFrequencyPointA = 646724;
#649104;
#646724;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 273;
#initialDownlinkBWP
#genericParameters
# this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart))
initialDLBWPlocationAndBandwidth = 1099;
#
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 273;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 1099;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 159;# testMAC 158; OAI gNB 98
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 12;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant = -90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 5; #6;
nrofDownlinkSlots = 3; #7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 1; #2;
nrofUplinkSymbols = 0;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "192.168.70.132";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129";
GNB_INTERFACE_NAME_FOR_NGU = "demo-oai";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
local_s_if_name = "lo:";
remote_s_address = "127.0.0.1"; // pnf addr [!]
local_s_address = "127.0.0.2"; // vnf addr
local_s_portc = 50001; // vnf p5 port
remote_s_portc = 50000; // pnf p5 port [!]
local_s_portd = 50011; // vnf p7 port [!]
remote_s_portd = 50010; // pnf p7 port [!]
tr_s_preference = "aerial";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200; #150;
pucch_TargetSNRx10 = 200; #200;
ulsch_max_frame_inactivity = 10;
dl_max_mcs = 28;
ul_max_mcs = 28;
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
ngap_log_level ="debug";
f1ap_log_level ="debug";
};