Commit 9965acda authored by Hongzhi Wang's avatar Hongzhi Wang Committed by Robert Schmidt

Add O-RAN 7.2 FHI library and documentation

- Add the O-RAN 7.2 FHI library, interfacing with OSC xRAN library
- Add documentation and patches necessary to make it run
- Add some sample config files

This is a squashed commit. It was made with the contributions of:
- Manish Kumar Singh <manish1.kumar@amd.com>
- thamizhselvan.k <thamizhselvan.k@vvdntech.in>
- rajeshwari.p <rajeshwari.p@vvdntech.in>
- Raymond Knopp <raymond.knopp@eurecom.fr>
- Sagar Arora <sagar.arora@openairinterface.org>
- Sofia Pison <Sofia.Pison@eurecom.fr>
- Ting-An Lin <lingwanjae@gmail.com>
parent 96ab8b99
......@@ -64,6 +64,21 @@ check_option(${ASN1C_EXEC} -no-gen-JER ASN1C_EXEC)
check_option(${ASN1C_EXEC} -no-gen-BER ASN1C_EXEC)
check_option(${ASN1C_EXEC} -no-gen-OER ASN1C_EXEC)
add_list2_option(TP_PROTO "None" "Ethernet" "benetel4g" "benetel5g" "oran_fhlib_5g")
if (${TP_PROTO} STREQUAL "oran_fhlib_5g")
if(DEFINED ENV{RTE_SDK})
message("RTE_SDK $ENV{RTE_SDK}")
else()
message(FATAL_ERROR "RTE_SDK Not defined")
endif()
if(DEFINED ENV{RTE_TARGET})
message("RTE_TARGET $ENV{RTE_TARGET}")
else()
message(FATAL_ERROR "RTE_TARGET is NOT defined")
endif()
endif()
#uhd 4.0 and iris installs by default in /usr/local
include_directories("/usr/local/include/")
#use native cmake method as this package is not in pkg-config
......@@ -149,7 +164,20 @@ set (OPENAIR3_DIR ${OPENAIR_DIR}/openair3)
set (OPENAIR3_DIR ${OPENAIR_DIR}/openair3)
set (OPENAIR_CMAKE ${OPENAIR_DIR}/cmake_targets)
set (OPENAIR_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY})
set (INTEL_LIB /usr/local/intel64)
set (DPDK_DIR $ENV{RTE_SDK}/$ENV{RTE_TARGET}/include)
if(DEFINED ENV{XRAN_LIB_DIR})
set (XRAN_LIB_DIR $ENV{XRAN_LIB_DIR})
else()
set (XRAN_LIB_DIR /usr/local/xran)
endif()
set (XRAN_DIR $ENV{XRAN_LIB_DIR}/../src)
set (XRAN_COMMON_DIR $ENV{XRAN_LIB_DIR}/../../test/common)
set (XRAN_LIB_API_DIR $ENV{XRAN_LIB_DIR}/../api)
Message("XRAN_LIB_DIR: ${XRAN_LIB_DIR}, DPDK_DIR: ${DPDK_DIR}")
project (OpenAirInterface)
####################################################
......@@ -602,6 +630,30 @@ SET(DPDK_LIBS "-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive
target_link_libraries(benetel_5g PRIVATE ${DPDK_LIBS})
target_link_libraries(benetel_5g PRIVATE pthread dl rt m numa)
# ORAN 5G library
######################################################################
set(ORAN_FHLIB_5G_SOURCE
${OPENAIR_DIR}/radio/ETHERNET/oran/5g/oran.cpp
${OPENAIR_DIR}/radio/ETHERNET/oran/5g/xran_lib_wrap.cpp
${OPENAIR_DIR}/radio/ETHERNET/oran/5g/oran_isolate.c
)
add_library(oran_fhlib_5g MODULE ${ORAN_FHLIB_5G_SOURCE})
target_include_directories(oran_fhlib_5g PRIVATE ${XRAN_DIR})
target_include_directories(oran_fhlib_5g PRIVATE ${DPDK_DIR})
target_include_directories(oran_fhlib_5g PRIVATE ${INTEL_LIB})
target_include_directories(oran_fhlib_5g PRIVATE ${XRAN_COMMON_DIR})
target_include_directories(oran_fhlib_5g PRIVATE ${XRAN_LIB_API_DIR})
set_target_properties(oran_fhlib_5g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native -I$ENV{RTE_SDK}/$ENV{RTE_TARGET}/include")
SET(DPDK_LIBS "-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive -L$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -ldpdk -Wl,--no-whole-archive")
TARGET_LINK_LIBRARIES(oran_fhlib_5g PRIVATE ${DPDK_LIBS})
TARGET_LINK_LIBRARIES(oran_fhlib_5g PRIVATE -L${XRAN_LIB_DIR} -lxran)
TARGET_LINK_LIBRARIES(oran_fhlib_5g PRIVATE pthread dl rt m numa)
target_link_libraries(oran_fhlib_5g PRIVATE asn1_nr_rrc asn1_lte_rrc)
##########################################################
# LDPC offload library
......
......@@ -109,7 +109,7 @@ Options:
USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, None (Default)
Adds this RF board support (in external packages installation and in compilation)
-t | --transport
Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g
Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g
-P | --phy_simulators
Makes the unitary tests Layer 1 simulators
-S | --core_simulators
......@@ -295,6 +295,8 @@ function main() {
shift 2;;
-t | --transport)
TP=$2
echo_info "TP set to ${TP}"
CMAKE_CMD="$CMAKE_CMD -DTP_PROTO=$2"
shift 2;;
-P | --phy_simulators)
SIMUS_PHY=1
......@@ -479,7 +481,7 @@ function main() {
if [ ! -v BUILD_UHD_FROM_SOURCE ] && [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then
install_usrp_uhd_driver $UHD_IMAGES_DIR
fi
fi
fi
if [ "$HW" == "OAI_BLADERF" ] ; then
echo_info "installing packages for BLADERF support"
check_install_bladerf_driver
......@@ -627,7 +629,12 @@ function main() {
compilations $BUILD_DIR benetel_5g.txt benetel_5g
ln -sf libbenetel_5g.so liboai_transpro.so
echo_info "liboai_transpro.so is linked to BENETEL4G transport"
fi
fi
if [ "$TP" == "oran_fhlib_5g" ]; then
compilations $BUILD_DIR oran_fhlib_5g.txt oran_fhlib_5g
ln -sf liboran_fhlib_5g.so liboai_transpro.so
echo_info "liboai_transpro.so is linked to oran_fhlib_5G transport"
fi
fi
fi
......
From d1ad2907b3c3572de193ae770912436fb0a96443 Mon Sep 17 00:00:00 2001
From: "thamizhselvan.k" <thamizhselvan.k@vvdntech.in>
Date: Fri, 27 Jan 2023 16:18:08 +0530
Subject: [PATCH 2/2] disable dedicated bandwidth config for Amarisoft UE
simbox
---
openair2/RRC/NR/MESSAGES/asn1_msg.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index e52e637dd8..f15735b36f 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -1213,10 +1213,8 @@ void fill_initial_cellGroupConfig(int uid,
physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook = NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic;
cellGroupConfig->physicalCellGroupConfig = physicalCellGroupConfig;
- cellGroupConfig->spCellConfig = calloc(1,sizeof(*cellGroupConfig->spCellConfig));
+ cellGroupConfig->spCellConfig = NULL;
- fill_initial_SpCellConfig(uid,cellGroupConfig->spCellConfig,scc,servingcellconfigdedicated,configuration);
-
cellGroupConfig->sCellToAddModList = NULL;
cellGroupConfig->sCellToReleaseList = NULL;
}
--
2.25.1
From a7f20ad7c4ada7d50f21c5a8f15b1baab37481fa Mon Sep 17 00:00:00 2001
From: "thamizhselvan.k" <thamizhselvan.k@vvdntech.in>
Date: Fri, 27 Jan 2023 15:42:36 +0530
Subject: [PATCH 1/4] compile libxran using-gcc and disable avx512
---
fhi_lib/build.sh | 7 ++++---
fhi_lib/lib/Makefile | 23 ++++++++++++-----------
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/fhi_lib/build.sh b/fhi_lib/build.sh
index 22859b5..575bcc5 100755
--- a/fhi_lib/build.sh
+++ b/fhi_lib/build.sh
@@ -70,11 +70,12 @@ echo "LIBXRANSO = ${LIBXRANSO}"
echo "MLOG = ${MLOG}"
cd $XRAN_FH_LIB_DIR
+make clean
make $COMMAND_LINE MLOG=${MLOG} LIBXRANSO=${LIBXRANSO} #DEBUG=1 VERBOSE=1
-echo 'Building xRAN Test Application'
-cd $XRAN_FH_APP_DIR
-make $COMMAND_LINE MLOG=${MLOG} #DEBUG=1 VERBOSE=1
+#echo 'Building xRAN Test Application'
+#cd $XRAN_FH_APP_DIR
+#make $COMMAND_LINE MLOG=${MLOG} #DEBUG=1 VERBOSE=1
if [ -z ${GTEST_ROOT+x} ];
then
diff --git a/fhi_lib/lib/Makefile b/fhi_lib/lib/Makefile
index 579a0c6..de5309d 100644
--- a/fhi_lib/lib/Makefile
+++ b/fhi_lib/lib/Makefile
@@ -23,11 +23,11 @@ MYCUSTOMSPACE1='------------------------------------------------------------'
##############################################################
# Tools configuration
##############################################################
-CC := icc
-CPP := icpc
+CC := gcc
+#CPP := icpc
AS := as
AR := ar
-LD := icc
+LD := gcc
OBJDUMP := objdump
ifeq ($(SHELL),cmd.exe)
@@ -95,9 +95,10 @@ CC_FLAGS += -std=gnu11 -Wall -Wno-deprecated-declarations \
-fPIC \
-Wall \
-Wimplicit-function-declaration \
- -g -O3 -wd1786
+ -g -O0 -mssse3 \
+ -march=native
-CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe -no-prec-div \
+#CPP_FLAGS := -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D_GNU_SOURCE -D_REENTRANT -pipe -no-prec-div \
-no-prec-div -fp-model fast=2 -fPIC \
-no-prec-sqrt -falign-functions=16 -fast-transcendentals \
-Werror -Wno-unused-variable -std=c++11 -mcmodel=large
@@ -121,14 +122,14 @@ PROJECT_OBJ_DIR := build/obj
CC_OBJS := $(patsubst %.c,%.o,$(CC_SRC))
CPP_OBJS := $(patsubst %.cpp,%.o,$(CPP_SRC))
AS_OBJS := $(patsubst %.s,%.o,$(AS_SRC))
-OBJS := $(CC_OBJS) $(CPP_OBJS) $(AS_OBJS) $(LIBS)
+OBJS := $(CC_OBJS) $(AS_OBJS) $(LIBS)
DIRLIST := $(addprefix $(PROJECT_OBJ_DIR)/,$(sort $(dir $(OBJS))))
CC_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CC_OBJS))
CPP_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(CPP_OBJS))
AS_OBJTARGETS := $(addprefix $(PROJECT_OBJ_DIR)/,$(AS_OBJS))
-CPP_COMP := -O3 -xcore-avx512 -restrict -g -fasm-blocks
+CPP_COMP := -O3 -xcore-avx512 -restrict -g
CC_FLAGS_FULL := $(CC_FLAGS) $(INC) $(DEF)
CPP_FLAGS_FULL := $(CPP_FLAGS) $(CPP_COMP) $(INC) $(DEF)
@@ -160,7 +161,7 @@ $(CPP_DEPS) :
@$(CPP) -MM $(subst __up__,../,$(subst __dep__,,$@)) -MT $(PROJECT_OBJ_DIR)/$(patsubst %.cpp,%.o,$(subst __up__,../,$(subst __dep__,,$@))) $(CPP_FLAGS_FULL) >> $(PROJECT_DEP_FILE)
.PHONY : generate_deps
-generate_deps : clear_dep $(CC_DEPS) $(CPP_DEPS)
+generate_deps : clear_dep $(CC_DEPS)
.PHONY : echo_start_build
@@ -211,10 +212,10 @@ welcome_line :
debug : all
release : all
-$(PROJECT_BINARY) : $(DIRLIST) echo_start_build $(GENERATE_DEPS) $(PRE_BUILD) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+$(PROJECT_BINARY) : $(DIRLIST) echo_start_build $(GENERATE_DEPS) $(PRE_BUILD) $(CC_OBJTARGETS) $(AS_OBJTARGETS)
@echo [AR] $(subst $(BUILDDIR)/,,$@)
ifeq ($(XRAN_LIB_SO),)
- @$(AR) $(AR_FLAGS) $@ $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS)
+ @$(AR) $(AR_FLAGS) $@ $(CC_OBJTARGETS) $(AS_OBJTARGETS)
else
- @$(CC) $(CC_OBJTARGETS) $(CPP_OBJTARGETS) $(AS_OBJTARGETS) -shared -fPIC -o $@
+ @$(CC) $(CC_OBJTARGETS) $(AS_OBJTARGETS) -shared -fPIC -o $@
endif
--
2.25.1
From f26a9e9a3b902d56fffcb40644fa7d3e17d793f9 Mon Sep 17 00:00:00 2001
From: "thamizhselvan.k" <thamizhselvan.k@vvdntech.in>
Date: Fri, 27 Jan 2023 15:43:50 +0530
Subject: [PATCH 2/4] return correct slot_id
---
fhi_lib/lib/src/xran_main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c
index 17acc2a..8f5705e 100644
--- a/fhi_lib/lib/src/xran_main.c
+++ b/fhi_lib/lib/src/xran_main.c
@@ -609,6 +609,7 @@ static inline int8_t xran_check_updl_seqid(void *pHandle, uint8_t cc_id, uint8_t
uint32_t xran_slotid_convert(uint16_t slot_id, uint16_t dir) //dir = 0, from PHY slotid to xran spec slotid as defined in 5.3.2, dir=1, from xran slotid to phy slotid
{
+ return slot_id;
#ifdef FCN_ADAPT
return slot_id;
#endif
--
2.25.1
From 3055c4a6cdb3ffa91deb4c6c11ecad0c95fef759 Mon Sep 17 00:00:00 2001
From: "thamizhselvan.k" <thamizhselvan.k@vvdntech.in>
Date: Fri, 27 Jan 2023 15:46:02 +0530
Subject: [PATCH 3/4] disable pkt validate at process_mbuf
---
fhi_lib/lib/src/xran_common.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c
index c4cb3fb..5bbacf7 100644
--- a/fhi_lib/lib/src/xran_common.c
+++ b/fhi_lib/lib/src/xran_common.c
@@ -192,6 +192,7 @@ int process_mbuf(struct rte_mbuf *pkt)
return MBUF_FREE;
}
+#if 0
valid_res = xran_pkt_validate(NULL,
pkt,
iq_samp_buf,
@@ -213,6 +214,7 @@ int process_mbuf(struct rte_mbuf *pkt)
print_dbg("valid_res is wrong [%d] ant %u (%u : %u : %u : %u) seq %u num_bytes %d\n", valid_res, Ant_ID, frame_id, subframe_id, slot_id, symb_id, seq.seq_id, num_bytes);
return MBUF_FREE;
}
+#endif
if (Ant_ID >= p_x_ctx->srs_cfg.eAxC_offset && p_x_ctx->fh_init.srsEnable) {
/* SRS packet has ruportid = 2*num_eAxc + ant_id */
--
2.25.1
From 5c99462d138042f99b3a02cec013f75bbc3732a9 Mon Sep 17 00:00:00 2001
From: "thamizhselvan.k" <thamizhselvan.k@vvdntech.in>
Date: Fri, 27 Jan 2023 15:48:25 +0530
Subject: [PATCH 4/4] process all rx ring
---
fhi_lib/lib/src/xran_common.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c
index 5bbacf7..eaefe45 100644
--- a/fhi_lib/lib/src/xran_common.c
+++ b/fhi_lib/lib/src/xran_common.c
@@ -737,8 +737,8 @@ int32_t ring_processing_func(void)
/* UP first */
for (i = 0; i < ctx->io_cfg.num_vfs && i < (XRAN_VF_MAX - 1); i = i+2){
- if (process_ring(ctx->rx_ring[i]))
- return 0;
+ process_ring(ctx->rx_ring[i]);
+ process_ring(ctx->rx_ring[i+1]);
/* CP next */
if(ctx->io_cfg.id == O_RU) /* process CP only on O-RU */
--
2.25.1
diff --git a/fhi_lib/test/common/common_typedef_xran.h b/fhi_lib/test/common/common_typedef_xran.h
index 9e84bd3..65621f5 100644
--- a/fhi_lib/test/common/common_typedef_xran.h
+++ b/fhi_lib/test/common/common_typedef_xran.h
@@ -88,7 +88,7 @@ typedef enum{
CPU_GENERIC, /*!< C */
SSE4_2, /*!< SSE4_2 */
AVX, /*!< AVX */
- AVX2, /*!< AVX2 */
+ AVX_2, /*!< AVX2 */
AVX_512, /*!< AVX512 */
}instruction_cpu_support;
diff --git a/fhi_lib/test/common/common.hpp b/fhi_lib/test/common/common.hpp
index 9b01b06..64a1baf 100644
--- a/fhi_lib/test/common/common.hpp
+++ b/fhi_lib/test/common/common.hpp
@@ -31,7 +31,7 @@
#include <rte_malloc.h>
#endif
-#include "gtest/gtest.h"
+//#include "gtest/gtest.h"
#include "common_typedef_xran.h"
@@ -106,7 +106,7 @@ json read_json_from_file(const std::string &filename);
\return Pointer to the allocated memory with data from the file.
\throws std::runtime_error when memory cannot be allocated.
*/
-char* read_data_to_aligned_array(const std::string &filename);
+//char* read_data_to_aligned_array(const std::string &filename);
/*!
\brief Measure the TSC on the machine
@@ -140,6 +140,7 @@ unsigned long tsc_tick();
values, e.g. 1, 0.001, 5e-05, etc. or filename. Depends on the get type test framework can either
read the value or load data from the file - and it happens automatically (*pff* MAGIC!).
*/
+#if 0
class KernelTests : public testing::TestWithParam<unsigned>
{
public:
@@ -827,5 +828,6 @@ T* generate_random_real_numbers(const long size, const unsigned alignment, const
return generate_random_numbers<T, std::uniform_real_distribution<T>>(size, alignment, distribution);
}
+#endif
#endif //XRANLIB_COMMON_HPP
diff --git a/fhi_lib/lib/src/xran_common.h b/fhi_lib/lib/src/xran_common.h
index 4f2928d..5028376 100644
--- a/fhi_lib/lib/src/xran_common.h
+++ b/fhi_lib/lib/src/xran_common.h
@@ -351,6 +351,7 @@ uint8_t xran_get_num_ant_elm(void *pHandle);
enum xran_category xran_get_ru_category(void *pHandle);
struct xran_device_ctx *xran_dev_get_ctx(void);
+int xran_is_prach_slot(uint32_t subframe_id, uint32_t slot_id);
int xran_register_cb_mbuf2ring(xran_ethdi_mbuf_send_fn mbuf_send_cp, xran_ethdi_mbuf_send_fn mbuf_send_up);
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI 7.2 Fronthaul Interface 5G SA Tutorial</font></b>
</td>
</tr>
</table>
**Table of Contents**
[[_TOC_]]
# 1. Prerequisites
The hardware on which we have tried this tutorial:
|Hardware (CPU,RAM) |Operating System |NIC (Vendor,Driver,Firmware) |
|--------------------------------------------|----------------------------------|-------------------------------------------------|
|Intel(R) Xeon(R) Gold 6154 (2x18 Core), 64GB|RHEL 8.6 (4.18.0-372.26.1.rt7.183)|QLogic FastLinQ QL41000,qede,mbi 15.35.1 |
|Intel(R) Xeon(R) Gold 6354 18-Core, 128GB |RHEL 8.7 (4.18.0-425.10.1.rt7.220)|Intel XXV710 for 25GbE SFP28,i40e,6.02 0x80003888|
|AMD EPYC 7513 32-Core Processor, 256GB |Ubuntu 20.04 (5.4.143-rt64) |Intel X710 for 10GbE SFP+,i40e,5.04 0x80002530 |
**NOTE**: These are not minimum hardware requirements. This is the configuration of our servers.
We always set our servers to maximum performance mode.
```bash
tuned-adm profile realtime
```
For PTP grandmaster we have used Fibrolan Falcon-RX. The O-RU which we have used for this tutorial is VVDN LPRU.
## 1.1 DPDK(Data Plane Development Kit)
Download DPDK version 20.05.0
```bash
wget http://fast.dpdk.org/rel/dpdk-20.05.tar.xz
```
DPDK Compilation
```bash
tar -xvf dpdk-20.05.tar.xz
cd dpdk-20.05
meson build
cd build
sudo ninja
sudo ninja install
make install T=x86_64-native-linuxapp-gcc
```
## 1.2 Setup
We have mentioned the information for our setup but if you want more information then you can refer to below links,
```bash
1. [O-RAN-SC O-DU Setup Configuration](https://docs.o-ran-sc.org/projects/o-ran-sc-o-du-phy/en/latest/Setup-Configuration_fh.html)
2. [O-RAN Cloud Platform Reference Designs 2.0,O-RAN.WG6.CLOUD-REF-v02.00,February 2021](https://orandownloadsweb.azurewebsites.net/specifications)
```
### 1.2.1 RHEL
These arguments we tried on both RHEL 8.6 (4.18.0-372.26.1.rt7.183.el8_6.x86_64) and 8.7 (4.18.0-425.10.1.rt7.220.el8_7.x86_64)
Update Linux boot arguments
```bash
igb.max_vfs=2 intel_iommu=on iommu=pt intel_pstate=disable nosoftlockup tsc=nowatchdog mitigations=off cgroup_memory=1 cgroup_enable=memory mce=off idle=poll hugepagesz=1G hugepages=40 hugepagesz=2M hugepages=0 default_hugepagesz=1G selinux=0 enforcing=0 nmi_watchdog=0 softlockup_panic=0 audit=0 skew_tick=1 isolcpus=managed_irq,domain,0-2,8-17 nohz_full=0-2,8-17 rcu_nocbs=0-2,8-17 rcu_nocb_poll
```
### 1.2.2 Ubuntu
Install real time kernel followed by updating boot arguments
```bash
isolcpus=0-2,8-17 nohz=on nohz_full=0-2,8-17 rcu_nocbs=0-2,8-17 rcu_nocb_poll nosoftlockup default_hugepagesz=1GB hugepagesz=1G hugepages=10 amd_iommu=on iommu=pt
```
Isolated CPU 0-2 are used for DPDK/ORAN and CPU 8 for `ru_thread` in our example config
## 1.3 PTP configuration
You can refer to the [following o-ran link](https://docs.o-ran-sc.org/projects/o-ran-sc-o-du-phy/en/latest/PTP-configuration_fh.html) for PTP configuration. In our setup we used Fibrolan Falcon-RX for PTP grandmaster.
```bash
git clone http://git.code.sf.net/p/linuxptp/code linuxptp
git checkout v2.0
make && make install
./ptp4l -i ens1f1 -m -H -2 -s -f configs/default.cfg
./phc2sys -w -m -s ens1f1 -R 8 -f configs/default.cfg
```
# 2. Build OAI-FHI gNB
## 2.1 Build ORAN Fronthaul Interface Library
Download ORAN FHI library
```bash
git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git
cd phy
git checkout oran_release_bronze_v1.1
```
Apply patches (available in `oai_folder/cmake_targets/tools/oran_fhi_integration_patches/`)
```bash
git apply oran-fhi-1-compile-libxran-using-gcc-and-disable-avx512.patch
git apply oran-fhi-2-return-correct-slot_id.patch
git apply oran-fhi-3-disable-pkt-validate-at-process_mbuf.patch
git apply oran-fhi-4-process_all_rx_ring.patch
git apply oran-fhi-5-remove-not-used-dependencies.patch
```
Set up the environment (change the path if you use different folders)
```bash
export XRAN_LIB_DIR=~/phy/fhi_lib/lib/build
export XRAN_DIR=~/phy/fhi_lib
export RTE_SDK=~/dpdk-20.05
export RTE_TARGET=x86_64-native-linuxapp-gcc
export RTE_INCLUDE=${RTE_SDK}/${RTE_TARGET}/include
```
Compile Fronthaul Interface Library
```bash
cd phy/fhi_lib/
./build.sh
```
## 2.2 Build OAI gNB
```bash
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git
cd openairinterface5g
git checkout develop
source oaienv
cd cmake_targets
./build_oai --gNB --ninja -t oran_fhlib_5g (Add, -I if you are building for the first time on server for installing external dependencies)
```
# 3. Configure Server and OAI gNB
## 3.1 Update following in fronthaul interface configuration - oran.fhi.json
```
* DU Mac-address: Parameter o_du_macaddr
* RU MAC Address: Parameter o_ru_macaddr
* PCI address: Parameter dpdk_dev_up and dpdk_dev_cp
```
## 3.2 Copy Fronthaul Configuration File
```bash
cd ran_build/build
cp ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/oran.fhi.json .
```
## 3.2 Bind Devices
```bash
sudo modprobe vfio_pci
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci 51:0e.0
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci 51:0e.1
```
## 3.3 Bind Devices
```bash
echo "2" > /sys/class/net/ens1f1/device/sriov_numvfs
sudo ip link set ens1f1 vf 0 mac 00:11:22:33:44:66 spoofchk off
sudo ip link set ens1f1 vf 1 mac 00:11:22:33:44:66 spoofchk off
sudo modprobe vfio_pci
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci 51:0e.0
sudo /usr/local/bin/dpdk-devbind.py --bind vfio-pci 51:0e.1
```
# 4. Run OAI gNB
## 4.1 Run OAI gNB
```bash
cd ran_build/build
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/oran.fh.band78.fr1.273PRB.conf --sa --reorder-thread-disable
```
......@@ -86,6 +86,7 @@ Some directories under `radio` contain READMEs:
- [RFsimulator](../radio/rfsimulator/README.md)
- [USRP](../radio/USRP/README.md)
- [O-RAN 7.2 FHI](./ORAN_FHI7.2_Tutorial.md)
- [BladeRF](../radio/BLADERF/README)
- [IQPlayer](../radio/iqplayer/DOC/iqrecordplayer_usage.md), and [general documentation](./iqrecordplayer_usage.md)
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include "oran_isolate.h"
#include "xran_lib_wrap.hpp"
#include "common.hpp"
#include "xran_compression.h"
#include "xran_sync_api.h"
// Declare variable useful for the send buffer function
struct xran_device_ctx *p_xran_dev_ctx_2;
volatile uint8_t first_call_set = 0;
volatile uint8_t first_rx_set = 0;
// Variable declaration useful for fill IQ samples from file
#define IQ_PLAYBACK_BUFFER_BYTES (XRAN_NUM_OF_SLOT_IN_TDD_LOOP * N_SYM_PER_SLOT * XRAN_MAX_PRBS * N_SC_PER_PRB * 4L)
int16_t *p_tx_play_buffer[MAX_ANT_CARRIER_SUPPORTED];
int iq_playback_buffer_size_dl = IQ_PLAYBACK_BUFFER_BYTES;
int32_t tx_play_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_play_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
int rx_tti;
int rx_sym;
volatile uint32_t rx_cb_tti = 0;
volatile uint32_t rx_cb_frame = 0;
volatile uint32_t rx_cb_subframe = 0;
volatile uint32_t rx_cb_slot = 0;
#define GetFrameNum(tti, SFNatSecStart, numSubFramePerSystemFrame, numSlotPerSubFrame) \
((((uint32_t)tti / ((uint32_t)numSubFramePerSystemFrame * (uint32_t)numSlotPerSubFrame)) + SFNatSecStart) & 0x3FF)
#define GetSlotNum(tti, numSlotPerSfn) ((uint32_t)tti % ((uint32_t)numSlotPerSfn))
// Declare the function useful to load IQs from file
int sys_load_file_to_buff(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num)
{
unsigned int file_size = 0;
int num = 0;
if (size) {
if (filename && bufname) {
FILE *file;
printf("Loading file %s to %s: ", filename, bufname);
file = fopen(filename, "rb");
if (file == NULL) {
printf("can't open file %s!!!", filename);
exit(-1);
} else {
fseek(file, 0, SEEK_END);
file_size = ftell(file);
fseek(file, 0, SEEK_SET);
if ((file_size > size) || (file_size == 0))
file_size = size;
printf("Reading IQ samples from file: File Size: %d [Buffer Size: %d]\n", file_size, size);
num = fread(pBuffer, buffers_num, size, file);
fflush(file);
fclose(file);
printf("from addr (0x%lx) size (%d) bytes num (%d)", (uint64_t)pBuffer, file_size, num);
}
printf(" \n");
} else {
printf(" the file name, buffer name are not set!!!");
}
} else {
printf(" the %s is free: size = %d bytes!!!", bufname, size);
}
return num;
}
void xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
{
xran_cb_tag *callback_tag = (xran_cb_tag *)pCallbackTag;
uint64_t second;
uint32_t tti;
uint32_t frame;
uint32_t subframe;
uint32_t slot;
tti = xran_get_slot_idx(&frame, &subframe, &slot, &second);
rx_tti = callback_tag->slotiId;
rx_sym = callback_tag->symbol;
if (rx_sym == 7) {
if (first_call_set) {
if (!first_rx_set) {
printf("first_rx is set\n");
}
first_rx_set = 1;
}
rx_cb_tti = tti;
rx_cb_frame = frame;
rx_cb_subframe = subframe;
rx_cb_slot = slot;
}
}
void xran_fh_srs_callback(void *pCallbackTag, xran_status_t status)
{
rte_pause();
}
void xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status)
{
rte_pause();
}
int physide_dl_tti_call_back(void *param)
{
if (!first_call_set)
printf("first_call set from phy cb first_call_set=%p\n", &first_call_set);
first_call_set = 1;
return 0;
}
int physide_ul_half_slot_call_back(void *param)
{
rte_pause();
return 0;
}
int physide_ul_full_slot_call_back(void *param)
{
rte_pause();
return 0;
}
#ifdef __cplusplus
extern "C" {
#endif
void *define_oran_pointer()
{
xranLibWraper *xranlib;
xranlib = new xranLibWraper;
// xranLibWraper *xranlib = (xranLibWraper*) calloc(1,sizeof(xranLibWraper));
return xranlib;
}
void dump_oran_config(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
int numerology = xranlib->get_numerology();
int duplex_type = xranlib->get_duplextype();
int num_cc = xranlib->get_num_cc();
int num_eaxc = xranlib->get_num_eaxc();
int num_eaxc_ul = xranlib->get_num_eaxc_ul();
int ndlrbs = xranlib->get_num_dlrbs();
int nulrbs = xranlib->get_num_ulrbs();
printf("**--**--**--**--**--**--**--**--**--**--**--**\n");
printf("ORAN Configuration\n");
printf("* Numerology = %d\n", numerology);
printf("* Duplex Type = %d\n", duplex_type);
printf("* Number CC = %d\n", num_cc);
printf("* Number eAxc = %d\n", num_eaxc);
printf("* Number eAxc UL = %d\n", num_eaxc_ul);
printf("* Number RBs DL = %d\n", ndlrbs);
printf("* Number RBs UL = %d\n", nulrbs);
printf("**--**--**--**--**--**--**--**--**--**--**--**\n");
}
int setup_oran(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
if (xranlib->SetUp() < 0) {
return (-1);
}
return (0);
}
int open_oran_callback(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
xranlib->Open(nullptr, nullptr, (void *)xran_fh_rx_callback, (void *)xran_fh_rx_prach_callback, (void *)xran_fh_srs_callback);
return (0);
}
int open_oran(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
struct xran_fh_config *pCfg = (struct xran_fh_config *)malloc(sizeof(struct xran_fh_config));
assert(pCfg != NULL);
xranlib->get_cfg_fh(pCfg);
xran_open(xranlib->get_xranhandle(), pCfg);
return (0);
}
int initialize_oran(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
xranlib->Init();
return (0);
}
int start_oran(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
xranlib->Start();
return (0);
}
int stop_oran(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
xranlib->Stop();
return (0);
}
int close_oran(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
xranlib->Close();
return (0);
}
int register_physide_callbacks(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
xran_reg_physide_cb(xranlib->get_xranhandle(), physide_dl_tti_call_back, xranlib, 1, XRAN_CB_TTI);
xran_reg_physide_cb(xranlib->get_xranhandle(), physide_ul_half_slot_call_back, NULL, 10, XRAN_CB_HALF_SLOT_RX);
xran_reg_physide_cb(xranlib->get_xranhandle(), physide_ul_full_slot_call_back, NULL, 10, XRAN_CB_FULL_SLOT_RX);
return (0);
}
int load_iq_from_file(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
int numCCPorts_ = xranlib->get_num_cc();
int num_eAxc_ = xranlib->get_num_eaxc();
printf("numCCPorts_ =%d, num_eAxc_=%d, MAX_ANT_CARRIER_SUPPORTED =%d\n", numCCPorts_, num_eAxc_, MAX_ANT_CARRIER_SUPPORTED);
int i;
const char *IQ_filename[MAX_ANT_CARRIER_SUPPORTED];
for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED; i++) {
if ((i == 0) || (i == 1) || (i == 2) || (i == 3)) {
IQ_filename[0] = "/home/oba/PISONS/phy/fhi_lib/app/usecase/mu0_5mhz/ant_0.bin";
IQ_filename[1] = "/home/oba/PISONS/phy/fhi_lib/app/usecase/mu0_5mhz/ant_1.bin";
IQ_filename[2] = "/home/oba/PISONS/phy/fhi_lib/app/usecase/mu0_5mhz/ant_2.bin";
IQ_filename[3] = "/home/oba/PISONS/phy/fhi_lib/app/usecase/mu0_5mhz/ant_3.bin";
} else {
IQ_filename[i] = "/0";
}
}
int32_t number_slots = 40; // According to wrapper.hpp uint32_t m_nSlots = 10; but for the file 5MHz is set to 40
uint32_t numerology = xranlib->get_numerology(); // According to the conf file is mu number
uint32_t bandwidth = 5; // According to the wrapper.hpp since we are reading the 5MHz files
uint32_t sub6 = xranlib->get_sub6();
iq_playback_buffer_size_dl = (number_slots * N_SYM_PER_SLOT * N_SC_PER_PRB * xranlib->get_num_rbs(numerology, bandwidth, sub6) * 4L);
const char *string_msg = "DL IFFT IN IQ Samples in binary format";
for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (int32_t)(numCCPorts_ * num_eAxc_); i++) {
char *name = const_cast<char *>(IQ_filename[i]);
char *string = const_cast<char *>(string_msg);
if (((uint8_t *)IQ_filename[i])[0] != 0) {
p_tx_play_buffer[i] = (int16_t *)malloc(iq_playback_buffer_size_dl);
assert(NULL != (p_tx_play_buffer[i]));
tx_play_buffer_size[i] = (int32_t)iq_playback_buffer_size_dl;
printf("Loading file [%d] %s \n", i, IQ_filename[i]);
tx_play_buffer_size[i] = sys_load_file_to_buff(name, string, (uint8_t *)p_tx_play_buffer[i], tx_play_buffer_size[i], 1);
tx_play_buffer_position[i] = 0;
} else {
p_tx_play_buffer[i] = (int16_t *)malloc(iq_playback_buffer_size_dl);
tx_play_buffer_size[i] = 0;
tx_play_buffer_position[i] = 0;
}
}
return (0);
}
int xran_fh_tx_send_buffer(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
int32_t flowId;
void *ptr = NULL;
char *pos = NULL;
p_xran_dev_ctx_2 = xran_dev_get_ctx();
if (p_xran_dev_ctx_2 != NULL) {
printf("p_xran_dev_ctx_2=%p\n", p_xran_dev_ctx_2);
}
int num_eaxc = xranlib->get_num_eaxc();
int num_eaxc_ul = xranlib->get_num_eaxc_ul();
uint32_t xran_max_antenna_nr = RTE_MAX(num_eaxc, num_eaxc_ul);
int32_t nSectorNum;
/*
for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
{
nSectorIndex[nSectorNum] = nSectorNum;
}
*/
nSectorNum = xranlib->get_num_cc();
int maxflowid = num_eaxc * (nSectorNum - 1) + (xran_max_antenna_nr - 1);
printf("the maximum flowID will be=%d\n", maxflowid);
for (uint16_t cc_id = 0; cc_id < nSectorNum; cc_id++) {
for (int32_t tti = 0; tti < XRAN_N_FE_BUF_LEN; tti++) {
for (uint8_t ant_id = 0; ant_id < xran_max_antenna_nr; ant_id++) {
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
flowId = num_eaxc * cc_id + ant_id;
uint8_t *pData = p_xran_dev_ctx_2->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT].pData;
uint8_t *pPrbMapData = p_xran_dev_ctx_2->sFrontHaulTxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers->pData;
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData;
ptr = pData;
pos = ((char *)p_tx_play_buffer[flowId]) + tx_play_buffer_position[flowId];
uint8_t *u8dptr;
struct xran_prb_map *pRbMap = pPrbMap;
int32_t sym_id = sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT;
if (ptr && pos) {
uint32_t idxElm = 0;
u8dptr = (uint8_t *)ptr;
int16_t payload_len = 0;
uint8_t *dst = (uint8_t *)u8dptr;
uint8_t *src = (uint8_t *)pos;
struct xran_prb_elm *p_prbMapElm = &pRbMap->prbMap[idxElm];
dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod);
for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
struct xran_section_desc *p_sec_desc = NULL;
p_prbMapElm = &pRbMap->prbMap[idxElm];
p_sec_desc = p_prbMapElm->p_sec_desc[sym_id];
if (p_sec_desc == NULL) {
printf("p_sec_desc == NULL\n");
exit(-1);
}
src = (uint8_t *)(pos + p_prbMapElm->nRBStart * N_SC_PER_PRB * 4L);
if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) {
payload_len = p_prbMapElm->nRBSize * N_SC_PER_PRB * 4L;
rte_memcpy(dst, src, payload_len);
} else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) {
printf("idxElm=%d, compMeth==BLKFLOAT\n", idxElm);
struct xranlib_compress_request bfp_com_req;
struct xranlib_compress_response bfp_com_rsp;
memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
bfp_com_req.data_in = (int16_t *)src;
bfp_com_req.numRBs = p_prbMapElm->nRBSize;
bfp_com_req.len = p_prbMapElm->nRBSize * N_SC_PER_PRB * 4L;
bfp_com_req.compMethod = p_prbMapElm->compMethod;
bfp_com_req.iqWidth = p_prbMapElm->iqWidth;
bfp_com_rsp.data_out = (int8_t *)dst;
bfp_com_rsp.len = 0;
xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp);
payload_len = bfp_com_rsp.len;
} else {
printf("p_prbMapElm->compMethod == %d is not supported\n", p_prbMapElm->compMethod);
exit(-1);
}
p_sec_desc->iq_buffer_offset = RTE_PTR_DIFF(dst, u8dptr);
p_sec_desc->iq_buffer_len = payload_len;
dst += payload_len;
dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod);
}
} else {
exit(-1);
printf("ptr ==NULL\n");
}
}
}
}
}
return (0);
}
int read_prach_data(ru_info_t *ru, int frame, int slot)
{
p_xran_dev_ctx_2 = xran_dev_get_ctx();
struct rte_mbuf *mb;
/* calculate tti and subframe_id from frame, slot num */
int tti = 20 * (frame) + (slot);
uint32_t subframe = XranGetSubFrameNum(tti, 2, 10);
uint32_t is_prach_slot = xran_is_prach_slot(subframe, (slot % 2));
int sym_idx = 0;
struct xran_prach_cp_config *pPrachCPConfig = &(p_xran_dev_ctx_2->PrachCPConfig);
/* If it is PRACH slot, copy prach IQ from XRAN PRACH buffer to OAI PRACH buffer */
if (is_prach_slot) {
for (sym_idx = 0; sym_idx < pPrachCPConfig->numSymbol; sym_idx++) {
for (int aa = 0; aa < ru->nb_rx; aa++) {
mb = (struct rte_mbuf *)p_xran_dev_ctx_2->sFHPrachRxBbuIoBufCtrl[tti % 40][0][aa].sBufferList.pBuffers[sym_idx].pCtrl;
if (mb) {
uint16_t *dst, *src;
int idx = 0;
dst = (uint16_t *)((uint8_t *)ru->prach_buf[aa] + (sym_idx * 576));
src = (uint16_t *)((uint8_t *)p_xran_dev_ctx_2->sFHPrachRxBbuIoBufCtrl[tti % 40][0][aa].sBufferList.pBuffers[sym_idx].pData);
/* convert Network order to host order */
for (idx = 0; idx < 576 / 2; idx++) {
dst[idx] = ntohs(src[idx]);
}
} else {
/* TODO: Unlikely this code never gets executed */
printf("%s():%d, There is no prach ctrl data for symb %d ant %d\n", __func__, __LINE__, sym_idx, aa);
}
}
}
}
return (0);
}
int xran_fh_rx_read_slot(void *xranlib_, ru_info_t *ru, int *frame, int *slot, int oframe, int oslot, uint8_t sync)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
void *ptr = NULL;
int32_t *pos = NULL;
int idx = 0;
static int print_tmp = 1;
static int print_tmp_1 = 1;
while (first_call_set != 1) {
if (print_tmp) {
print_tmp = 0;
printf("wait in ru_thread() till first_call_set is set in xran\n");
}
}
while (first_rx_set != 1) {
if (print_tmp_1) {
print_tmp_1 = 0;
printf("wait in ru_thread for first_rx_set to set in xran\n");
}
}
volatile uint32_t prev_rx_cb_tti;
int tti;
prev_rx_cb_tti = rx_cb_tti;
*frame = rx_cb_frame;
*slot = (rx_cb_subframe * 2) + rx_cb_slot;
tti = (*frame * 20) + *slot;
while (rx_cb_tti == prev_rx_cb_tti) {
}
read_prach_data(ru, *frame, *slot);
p_xran_dev_ctx_2 = xran_dev_get_ctx();
int num_eaxc = xranlib->get_num_eaxc();
int num_eaxc_ul = xranlib->get_num_eaxc_ul();
uint32_t xran_max_antenna_nr = RTE_MAX(num_eaxc, num_eaxc_ul);
int slot_offset_rxdata = 3 & (*slot);
uint32_t slot_size = 4 * 14 * 4096;
uint8_t *rx_data = (uint8_t *)ru->rxdataF[0];
uint8_t *start_ptr = NULL;
for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet.
for (uint8_t ant_id = 0; ant_id < xran_max_antenna_nr && ant_id < ru->nb_rx; ant_id++) {
rx_data = (uint8_t *)ru->rxdataF[ant_id];
start_ptr = rx_data + (slot_size * slot_offset_rxdata);
// This loop would better be more inner to avoid confusion and maybe also errors.
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
uint8_t *pData = p_xran_dev_ctx_2->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT].pData;
uint8_t *pPrbMapData = p_xran_dev_ctx_2->sFrontHaulRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers->pData;
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData;
ptr = pData;
pos = (int32_t *)(start_ptr + (4 * sym_idx * 4096));
uint8_t *u8dptr;
struct xran_prb_map *pRbMap = pPrbMap;
int32_t sym_id = sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT;
if (ptr && pos) {
uint32_t idxElm = 0;
u8dptr = (uint8_t *)ptr;
int16_t payload_len = 0;
uint8_t *src = (uint8_t *)u8dptr;
// first half
uint8_t *src1 = (uint8_t *)u8dptr;
uint8_t *dst1 = (uint8_t *)pos;
// second half
uint8_t *src2 = (uint8_t *)u8dptr;
uint8_t *dst2 = (uint8_t *)pos;
struct xran_prb_elm *p_prbMapElm = &pRbMap->prbMap[idxElm];
for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
struct xran_section_desc *p_sec_desc = NULL;
p_prbMapElm = &pRbMap->prbMap[idxElm];
p_sec_desc = p_prbMapElm->p_sec_desc[sym_id];
if (pRbMap->nPrbElm == 1 && idxElm == 0) {
src = pData;
} else if (p_sec_desc->pData == NULL) {
return -1;
} else {
src = p_sec_desc->pData;
}
src2 = src;
if (p_sec_desc == NULL) {
printf("p_sec_desc == NULL\n");
exit(-1);
}
// Calculation of the pointer for the section in the buffer.
// first half
dst1 = (uint8_t *)(pos + p_prbMapElm->nRBStart * N_SC_PER_PRB);
// second half
dst2 = (uint8_t *)(pos + (p_prbMapElm->nRBStart * N_SC_PER_PRB + 3276 / 2) + 4096 - 3276);
if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) {
payload_len = p_prbMapElm->nRBSize * N_SC_PER_PRB * 4L;
src1 = src2 + payload_len / 2;
for (idx = 0; idx < payload_len / (2 * sizeof(int16_t)); idx++) {
((uint16_t *)dst1)[idx] = ntohs(((uint16_t *)src1)[idx]);
((uint16_t *)dst2)[idx] = ntohs(((uint16_t *)src2)[idx]);
}
} else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) {
struct xranlib_decompress_request bfp_decom_req_2;
struct xranlib_decompress_response bfp_decom_rsp_2;
struct xranlib_decompress_request bfp_decom_req_1;
struct xranlib_decompress_response bfp_decom_rsp_1;
payload_len = (3 * p_prbMapElm->iqWidth + 1) * p_prbMapElm->nRBSize;
memset(&bfp_decom_req_2, 0, sizeof(struct xranlib_decompress_request));
memset(&bfp_decom_rsp_2, 0, sizeof(struct xranlib_decompress_response));
memset(&bfp_decom_req_1, 0, sizeof(struct xranlib_decompress_request));
memset(&bfp_decom_rsp_1, 0, sizeof(struct xranlib_decompress_response));
bfp_decom_req_2.data_in = (int8_t *)src2;
bfp_decom_req_2.numRBs = p_prbMapElm->nRBSize / 2;
bfp_decom_req_2.len = payload_len / 2;
bfp_decom_req_2.compMethod = p_prbMapElm->compMethod;
bfp_decom_req_2.iqWidth = p_prbMapElm->iqWidth;
bfp_decom_rsp_2.data_out = (int16_t *)dst2;
bfp_decom_rsp_2.len = 0;
xranlib_decompress_avx512(&bfp_decom_req_2, &bfp_decom_rsp_2);
int16_t first_half_len = bfp_decom_rsp_2.len;
src1 = src2 + (payload_len / 2);
bfp_decom_req_1.data_in = (int8_t *)src1;
bfp_decom_req_1.numRBs = p_prbMapElm->nRBSize / 2;
bfp_decom_req_1.len = payload_len / 2;
bfp_decom_req_1.compMethod = p_prbMapElm->compMethod;
bfp_decom_req_1.iqWidth = p_prbMapElm->iqWidth;
bfp_decom_rsp_1.data_out = (int16_t *)dst1;
bfp_decom_rsp_1.len = 0;
xranlib_decompress_avx512(&bfp_decom_req_1, &bfp_decom_rsp_1);
payload_len = bfp_decom_rsp_1.len + first_half_len;
} else {
printf("p_prbMapElm->compMethod == %d is not supported\n", p_prbMapElm->compMethod);
exit(-1);
}
}
} else {
exit(-1);
printf("ptr ==NULL\n");
}
}
}
}
return (0);
}
int xran_fh_tx_send_slot(void *xranlib_, ru_info_t *ru, int frame, int slot, uint64_t timestamp)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
int tti = /*frame*SUBFRAMES_PER_SYSTEMFRAME*SLOTNUM_PER_SUBFRAME+*/ 20 * frame + slot; // commented out temporarily to check that compilation of oran 5g is working.
void *ptr = NULL;
int32_t *pos = NULL;
int idx = 0;
p_xran_dev_ctx_2 = xran_dev_get_ctx();
#if 0
if (p_xran_dev_ctx_2 != NULL){
printf("p_xran_dev_ctx_2=%d\n",p_xran_dev_ctx_2);
}
#endif
int num_eaxc = xranlib->get_num_eaxc();
int num_eaxc_ul = xranlib->get_num_eaxc_ul();
uint32_t xran_max_antenna_nr = RTE_MAX(num_eaxc, num_eaxc_ul);
/*
for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
{
nSectorIndex[nSectorNum] = nSectorNum;
}
*/
for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet.
for (uint8_t ant_id = 0; ant_id < xran_max_antenna_nr && ant_id < ru->nb_tx; ant_id++) {
// This loop would better be more inner to avoid confusion and maybe also errors.
for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) {
uint8_t *pData = p_xran_dev_ctx_2->sFrontHaulTxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT].pData;
uint8_t *pPrbMapData = p_xran_dev_ctx_2->sFrontHaulTxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][cc_id][ant_id].sBufferList.pBuffers->pData;
struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData;
ptr = pData;
pos = &ru->txdataF_BF[ant_id][sym_idx * 4096 /*fp->ofdm_symbol_size*/]; // We had to use a different ru structure than benetel so the access to the buffer is not the same.
uint8_t *u8dptr;
struct xran_prb_map *pRbMap = pPrbMap;
int32_t sym_id = sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT;
if (ptr && pos) {
uint32_t idxElm = 0;
u8dptr = (uint8_t *)ptr;
int16_t payload_len = 0;
uint8_t *dst = (uint8_t *)u8dptr;
// first half
uint8_t *dst1 = (uint8_t *)u8dptr;
uint8_t *src1 = (uint8_t *)pos;
// second half
uint8_t *dst2 = (uint8_t *)u8dptr;
uint8_t *src2 = (uint8_t *)pos;
struct xran_prb_elm *p_prbMapElm = &pRbMap->prbMap[idxElm];
for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) {
struct xran_section_desc *p_sec_desc = NULL;
p_prbMapElm = &pRbMap->prbMap[idxElm];
p_sec_desc = p_prbMapElm->p_sec_desc[sym_id];
payload_len = p_prbMapElm->nRBSize * N_SC_PER_PRB * 4L;
dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod);
dst2 = dst;
dst1 = dst2 + payload_len / 2;
if (p_sec_desc == NULL) {
printf("p_sec_desc == NULL\n");
exit(-1);
}
// Calculation of the pointer for the section in the buffer.
// first half
src1 = (uint8_t *)(pos + p_prbMapElm->nRBStart * N_SC_PER_PRB);
// second half
src2 = (uint8_t *)(pos + (p_prbMapElm->nRBStart * N_SC_PER_PRB + 3276 / 2) + 4096 - 3276);
if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) {
/* convert to Network order */
for (idx = 0; idx < payload_len / (2 * sizeof(uint16_t)); idx++) {
((uint16_t *)dst1)[idx] = htons(((uint16_t *)src1)[idx]);
((uint16_t *)dst2)[idx] = htons(((uint16_t *)src2)[idx]);
}
} else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) {
printf("idxElm=%d, compMeth==BLKFLOAT\n", idxElm);
struct xranlib_compress_request bfp_com_req;
struct xranlib_compress_response bfp_com_rsp;
memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));
bfp_com_req.data_in = (int16_t *)src2;
bfp_com_req.numRBs = p_prbMapElm->nRBSize / 2;
bfp_com_req.len = payload_len / 2;
bfp_com_req.compMethod = p_prbMapElm->compMethod;
bfp_com_req.iqWidth = p_prbMapElm->iqWidth;
bfp_com_rsp.data_out = (int8_t *)dst2;
bfp_com_rsp.len = 0;
xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp);
int16_t first_half_len = bfp_com_rsp.len;
dst1 = dst2 + first_half_len;
bfp_com_req.data_in = (int16_t *)src1;
bfp_com_req.numRBs = p_prbMapElm->nRBSize / 2;
bfp_com_req.len = payload_len / 2;
bfp_com_req.compMethod = p_prbMapElm->compMethod;
bfp_com_req.iqWidth = p_prbMapElm->iqWidth;
bfp_com_rsp.data_out = (int8_t *)dst1;
bfp_com_rsp.len = 0;
xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp);
payload_len = bfp_com_rsp.len + first_half_len;
} else {
printf("p_prbMapElm->compMethod == %d is not supported\n", p_prbMapElm->compMethod);
exit(-1);
}
p_sec_desc->iq_buffer_offset = RTE_PTR_DIFF(dst, u8dptr);
p_sec_desc->iq_buffer_len = payload_len;
dst += payload_len;
dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod);
}
// The tti should be updated as it increased.
pRbMap->tti_id = tti;
} else {
exit(-1);
printf("ptr ==NULL\n");
}
}
}
}
return (0);
}
#ifdef __cplusplus
}
#endif
struct xran_common_counters x_counters;
uint64_t nTotalTime;
uint64_t nUsedTime;
uint32_t nCoreUsed;
float nUsedPercent;
uint64_t old_rx_counter = 0;
uint64_t old_tx_counter = 0;
#ifdef __cplusplus
extern "C" {
#endif
int compute_xran_statistics(void *xranlib_)
{
xranLibWraper *xranlib = ((xranLibWraper *)xranlib_);
if (xran_get_common_counters(xranlib->get_xranhandle(), &x_counters) == XRAN_STATUS_SUCCESS) {
xran_get_time_stats(&nTotalTime, &nUsedTime, &nCoreUsed, 1);
nUsedPercent = ((float)nUsedTime * 100.0) / (float)nTotalTime;
printf("[rx %7ld pps %7ld kbps %7ld][tx %7ld pps %7ld kbps %7ld] [on_time %ld early %ld late %ld corrupt %ld pkt_dupl %ld Total %ld] IO Util: %5.2f %%\n",
x_counters.rx_counter,
x_counters.rx_counter - old_rx_counter,
x_counters.rx_bytes_per_sec * 8 / 1000L,
x_counters.tx_counter,
x_counters.tx_counter - old_tx_counter,
x_counters.tx_bytes_per_sec * 8 / 1000L,
x_counters.Rx_on_time,
x_counters.Rx_early,
x_counters.Rx_late,
x_counters.Rx_corrupt,
x_counters.Rx_pkt_dupl,
x_counters.Total_msgs_rcvd,
nUsedPercent);
if (x_counters.rx_counter > old_rx_counter)
old_rx_counter = x_counters.rx_counter;
if (x_counters.tx_counter > old_tx_counter)
old_tx_counter = x_counters.tx_counter;
} else {
printf("error xran_get_common_counters\n");
return (1);
}
return (0);
}
void check_xran_ptp_sync()
{
int res;
if ((res = xran_is_synchronized()) != 0)
printf("Machine is not synchronized using PTP (%x)!\n", res);
else
printf("Machine is synchronized using PTP!\n");
}
#ifdef __cplusplus
}
#endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _ORAN_H_
#define _ORAN_H_
#include "shared_buffers.h"
#include "common_lib.h"
void oran_fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp);
void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot);
int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
typedef struct {
eth_state_t e;
shared_buffers buffers;
rru_config_msg_type_t last_msg;
int capabilities_sent;
void *oran_priv;
} oran_eth_state_t;
#endif /* _ORAN_H_ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include "common_lib.h"
#include "ethernet_lib.h"
#include "oran_isolate.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "openair1/PHY/defs_gNB.h"
typedef struct {
eth_state_t e;
rru_config_msg_type_t last_msg;
int capabilities_sent;
void *oran_priv;
} oran_eth_state_t;
int trx_oran_start(openair0_device *device)
{
printf("ORAN: %s\n", __FUNCTION__);
oran_eth_state_t *s = device->priv;
// Start ORAN
if (start_oran(s->oran_priv) != 0) {
printf("%s:%d:%s: Start ORAN failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
} else {
printf("Start ORAN. Done\n");
}
return 0;
}
void trx_oran_end(openair0_device *device)
{
printf("ORAN: %s\n", __FUNCTION__);
oran_eth_state_t *s = device->priv;
stop_oran(s->oran_priv);
close_oran(s->oran_priv);
}
int trx_oran_stop(openair0_device *device)
{
printf("ORAN: %s\n", __FUNCTION__);
oran_eth_state_t *s = device->priv;
stop_oran(s->oran_priv);
return (0);
}
int trx_oran_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int exmimo_dump_config)
{
printf("ORAN: %s\n", __FUNCTION__);
return (0);
}
int trx_oran_set_gains(openair0_device *device, openair0_config_t *openair0_cfg)
{
printf("ORAN: %s\n", __FUNCTION__);
return (0);
}
int trx_oran_get_stats(openair0_device *device)
{
printf("ORAN: %s\n", __FUNCTION__);
return (0);
}
int trx_oran_reset_stats(openair0_device *device)
{
printf("ORAN: %s\n", __FUNCTION__);
return (0);
}
int ethernet_tune(openair0_device *device, unsigned int option, int value)
{
printf("ORAN: %s\n", __FUNCTION__);
return 0;
}
int trx_oran_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags)
{
printf("ORAN: %s\n", __FUNCTION__);
return 0;
}
int trx_oran_read_raw(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc)
{
printf("ORAN: %s\n", __FUNCTION__);
return 0;
}
char *msg_type(int t)
{
static char *s[12] = {
"RAU_tick",
"RRU_capabilities",
"RRU_config",
"RRU_config_ok",
"RRU_start",
"RRU_stop",
"RRU_sync_ok",
"RRU_frame_resynch",
"RRU_MSG_max_num",
"RRU_check_sync",
"RRU_config_update",
"RRU_config_update_ok",
};
if (t < 0 || t > 11)
return "UNKNOWN";
return s[t];
}
int trx_oran_ctlsend(openair0_device *device, void *msg, ssize_t msg_len)
{
RRU_CONFIG_msg_t *rru_config_msg = msg;
oran_eth_state_t *s = device->priv;
printf("ORAN: %s\n", __FUNCTION__);
printf(" rru_config_msg->type %d [%s]\n", rru_config_msg->type, msg_type(rru_config_msg->type));
s->last_msg = rru_config_msg->type;
return msg_len;
}
int trx_oran_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len)
{
RRU_CONFIG_msg_t *rru_config_msg = msg;
oran_eth_state_t *s = device->priv;
printf("ORAN: %s\n", __FUNCTION__);
if (s->last_msg == RAU_tick && s->capabilities_sent == 0) {
printf("ORAN ctrlrcv RRU_tick received and send capabilities hard coded\n");
RRU_capabilities_t *cap;
rru_config_msg->type = RRU_capabilities;
rru_config_msg->len = sizeof(RRU_CONFIG_msg_t) - MAX_RRU_CONFIG_SIZE + sizeof(RRU_capabilities_t);
// Fill RRU capabilities (see openair1/PHY/defs_RU.h)
// For now they are hard coded - try to retreive the params from openari device
cap = (RRU_capabilities_t *)&rru_config_msg->msg[0];
cap->FH_fmt = OAI_IF4p5_only;
cap->num_bands = 1;
cap->band_list[0] = 78;
// cap->num_concurrent_bands = 1; component carriers
cap->nb_rx[0] = 1; // device->openair0_cfg->rx_num_channels;
cap->nb_tx[0] = 1; // device->openair0_cfg->tx_num_channels;
cap->max_pdschReferenceSignalPower[0] = -27;
cap->max_rxgain[0] = 90;
cap->N_RB_DL[0] = 106;
cap->N_RB_UL[0] = 106;
s->capabilities_sent = 1;
return rru_config_msg->len;
}
if (s->last_msg == RRU_config) {
printf("Oran RRU_config\n");
rru_config_msg->type = RRU_config_ok;
}
return 0;
}
void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot)
{
oran_eth_state_t *s = ru->ifdevice.priv;
int symbol;
int32_t *rxdata;
int antenna;
static uint8_t sync = 0;
ru_info_t ru_info;
ru_info.nb_rx = ru->nb_rx;
ru_info.rxdataF = ru->common.rxdataF;
ru_info.prach_buf = (int *)ru->prach_rxsigF[0]; // index: [prach_oca][ant_id]
RU_proc_t *proc = &ru->proc;
extern uint16_t sl_ahead;
int f, sl;
int ret = xran_fh_rx_read_slot(s->oran_priv, &ru_info, &f, &sl, *frame, *slot, sync);
if (ret != 0) {
printf("ORAN: ORAN_fh_if4p5_south_in ERROR in RX function \n");
}
proc->tti_rx = sl;
proc->frame_rx = f;
proc->tti_tx = (sl + sl_ahead) % 20;
proc->frame_tx = (sl > (19 - sl_ahead)) ? (f + 1) & 1023 : f;
if (proc->first_rx == 0) {
if (proc->tti_rx != *slot) {
LOG_E(PHY, "Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, slot %d)\n", proc->tti_rx, *slot);
*slot = proc->tti_rx;
}
if (proc->frame_rx != *frame) {
LOG_E(PHY, "Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d proc->tti_rx %d tti %d)\n", proc->frame_rx, *frame, proc->tti_rx, *slot);
*frame = proc->frame_rx;
}
} else {
proc->first_rx = 0;
LOG_I(PHY, "before adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx);
*frame = proc->frame_rx;
*slot = proc->tti_rx;
LOG_I(PHY, "After adjusting, OAI: frame=%d slot=%d, XRAN: frame=%d slot=%d\n", *frame, *slot, proc->frame_rx, proc->tti_rx);
}
sync = 1;
}
void oran_fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
{
openair0_device *device = &ru->ifdevice;
oran_eth_state_t *s = device->priv;
ru_info_t ru_info;
ru_info.nb_tx = ru->nb_tx;
ru_info.txdataF_BF = ru->common.txdataF_BF;
// printf("south_out:\tframe=%d\tslot=%d\ttimestamp=%ld\n",frame,slot,timestamp);
int ret = xran_fh_tx_send_slot(s->oran_priv, &ru_info, frame, slot, timestamp);
if (ret != 0) {
printf("ORAN: ORAN_fh_if4p5_south_out ERROR in TX function \n");
}
}
void *get_internal_parameter(char *name)
{
printf("ORAN: %s\n", __FUNCTION__);
if (!strcmp(name, "fh_if4p5_south_in"))
return (void *)oran_fh_if4p5_south_in;
if (!strcmp(name, "fh_if4p5_south_out"))
return (void *)oran_fh_if4p5_south_out;
return NULL;
}
__attribute__((__visibility__("default"))) int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params)
{
oran_eth_state_t *eth;
device->Mod_id = 0;
device->transp_type = ETHERNET_TP;
device->trx_start_func = trx_oran_start;
device->trx_get_stats_func = trx_oran_get_stats;
device->trx_reset_stats_func = trx_oran_reset_stats;
device->trx_end_func = trx_oran_end;
device->trx_stop_func = trx_oran_stop;
device->trx_set_freq_func = trx_oran_set_freq;
device->trx_set_gains_func = trx_oran_set_gains;
device->trx_write_func = trx_oran_write_raw;
device->trx_read_func = trx_oran_read_raw;
device->trx_ctlsend_func = trx_oran_ctlsend;
device->trx_ctlrecv_func = trx_oran_ctlrecv;
device->get_internal_parameter = get_internal_parameter;
eth = (oran_eth_state_t *)calloc(1, sizeof(oran_eth_state_t));
if (eth == NULL) {
AssertFatal(0 == 1, "out of memory\n");
}
eth->e.flags = ETH_RAW_IF4p5_MODE;
eth->e.compression = NO_COMPRESS;
eth->e.if_name = eth_params->local_if_name;
eth->oran_priv = define_oran_pointer();
device->priv = eth;
device->openair0_cfg = &openair0_cfg[0];
eth->last_msg = (rru_config_msg_type_t)-1;
oran_eth_state_t *s = eth;
printf("ORAN: %s\n", __FUNCTION__);
// Check if the machine is PTP sync
check_xran_ptp_sync();
// SetUp
if (setup_oran(s->oran_priv) != 0) {
printf("%s:%d:%s: SetUp ORAN failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
} else {
printf("SetUp ORAN. Done\n");
}
// Dump ORAN config
dump_oran_config(s->oran_priv);
// Register physide callbacks
register_physide_callbacks(s->oran_priv);
printf("Register physide callbacks. Done\n");
// Open callbacks
open_oran_callback(s->oran_priv);
printf("Open Oran callbacks. Done\n");
// Init ORAN
initialize_oran(s->oran_priv);
printf("Init Oran. Done\n");
// Open ORAN
open_oran(s->oran_priv);
printf("xran_open. Done\n");
return 0;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _ORAN_ISOLATE_H_
#define _ORAN_ISOLATE_H_
#include <stdio.h>
#include <pthread.h>
#include <stdint.h>
/*
* Structure added to bear the information needed from OAI RU
*/
typedef struct ru_info_s {
// Needed for UL
int nb_rx;
int32_t **rxdataF;
// Needed for DL
int nb_tx;
int32_t **txdataF_BF;
// Needed for Prach
int **prach_buf;
} ru_info_t;
#ifdef __cplusplus
extern "C" {
#endif
void *define_oran_pointer();
void dump_oran_config(void *xranlib_);
int setup_oran(void *xranlib_);
int open_oran_callback(void *xranlib_);
int open_oran(void *xranlib_);
int initialize_oran(void *xranlib_);
int start_oran(void *xranlib_);
int stop_oran(void *xranlib_);
int close_oran(void *xranlib_);
int register_physide_callbacks(void *xranlib_);
int load_iq_from_file(void *xranlib_);
int xran_fh_rx_read_slot(void *xranlib_, ru_info_t *ru, int *frame, int *slot, int oframe, int oslot, uint8_t sync);
int xran_fh_tx_send_buffer(void *xranlib_);
int xran_fh_tx_send_slot(void *xranlib_, ru_info_t *ru, int frame, int slot, uint64_t timestamp);
int compute_xran_statistics(void *xranlib_);
void check_xran_ptp_sync();
#ifdef __cplusplus
}
#endif
#endif /* _ORAN_ISOLATE_H_ */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "xran_lib_wrap.hpp"
#include <fstream>
json read_json_from_file(const std::string &filename)
{
json result;
std::ifstream json_stream(filename);
if (!json_stream.is_open())
throw missing_config_file_exception();
json_stream >> result;
return result;
}
uint16_t xranLibWraper::get_eaxcid_mask(int numbit, int shift)
{
uint16_t result = 0;
for (int i = 0; i < numbit; i++) {
result = result << 1;
result += 1;
}
return (result << shift);
}
int xranLibWraper::init_memory()
{
xran_status_t status;
int32_t i, j, k;
uint32_t z;
SWXRANInterfaceTypeEnum eInterfaceType;
void *ptr;
void *mb;
uint32_t *u32dptr;
uint32_t xran_max_antenna_nr = RTE_MAX(get_num_eaxc(), get_num_eaxc_ul());
uint32_t xran_max_ant_array_elm_nr = RTE_MAX(get_num_antelmtrx(), xran_max_antenna_nr);
std::cout << "XRAN front haul xran_mm_init" << std::endl;
status = xran_mm_init(m_xranhandle, (uint64_t)SW_FPGA_FH_TOTAL_BUFFER_LEN, SW_FPGA_SEGMENT_BUFFER_LEN);
if (status != XRAN_STATUS_SUCCESS) {
std::cout << "Failed at XRAN front haul xran_mm_init" << std::endl;
return (-1);
}
#if 0
// Define the sizes according to the specified parameters in the conf file not up to the maximim boudary
/* initialize maximum instances to have flexibility for the tests */
int nInstanceNum = XRAN_MAX_SECTOR_NR;
/* initialize maximum supported CC to have flexibility on the test */
int32_t nSectorNum = 6; //XRAN_MAX_SECTOR_NR;
#endif
int32_t nSectorNum = get_num_cc();
int nInstanceNum = get_num_cc();
for (k = 0; k < XRAN_PORTS_NUM; k++) {
status = xran_sector_get_instances(m_xranhandle, nInstanceNum, &m_nInstanceHandle[k][0]);
if (status != XRAN_STATUS_SUCCESS) {
std::cout << "get sector instance failed " << k << " for XRAN nInstanceNum " << nInstanceNum << std::endl;
return (-1);
}
for (i = 0; i < nInstanceNum; i++)
std::cout << __func__ << " [" << k << "]: CC " << i << " handle " << m_nInstanceHandle[0][i] << std::endl;
}
std::cout << "Sucess xran_mm_init" << std::endl;
/* Init Memory */
printf("wrapper.hpp: Init memory *** XRANFTHTX_OUT ***\n");
for (i = 0; i < nSectorNum; i++) {
eInterfaceType = XRANFTHTX_OUT;
printf("Call xran_bm_init %d\n", i);
status =
xran_bm_init(m_nInstanceHandle[0][i], &m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT, m_nSW_ToFpga_FTH_TxBufferLen);
if (status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
for (j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
for (z = 0; z < xran_max_antenna_nr; z++) {
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFrontHaulTxBuffers[j][i][z][0];
for (k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = m_nSW_ToFpga_FTH_TxBufferLen; // 14 symbols 3200bytes/symbol
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
if (status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer, status " << status << std::endl;
return (-1);
}
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
if (ptr) {
u32dptr = (uint32_t *)(ptr);
memset(u32dptr, 0x0, m_nSW_ToFpga_FTH_TxBufferLen);
}
}
}
}
/* C-plane DL */
printf("wrapper.hpp: Init memory *** XRANFTHTX_SEC_DESC_OUT ***\n");
eInterfaceType = XRANFTHTX_SEC_DESC_OUT;
status = xran_bm_init(m_nInstanceHandle[0][i],
&m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT * XRAN_MAX_SECTIONS_PER_SYM,
sizeof(struct xran_section_desc));
if (XRAN_STATUS_SUCCESS != status) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
printf("wrapper.hpp: Init memory *** XRANFTHTX_PRB_MAP_OUT ***\n");
eInterfaceType = XRANFTHTX_PRB_MAP_OUT;
status =
xran_bm_init(m_nInstanceHandle[0][i], &m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
if (status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
for (j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
for (z = 0; z < xran_max_antenna_nr; z++) {
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFrontHaulTxPrbMapBuffers[j][i][z];
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
if (status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer, status " << status << std::endl;
return (-1);
}
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
void *sd_ptr;
void *sd_mb;
int elm_id;
struct xran_prb_map *p_rb_map = (struct xran_prb_map *)ptr;
for (elm_id = 0; elm_id < XRAN_MAX_SECTIONS_PER_SYM; elm_id++) {
struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id];
for (k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][XRANFTHTX_SEC_DESC_OUT], &sd_ptr, &sd_mb);
if (XRAN_STATUS_SUCCESS != status) {
std::cout << __LINE__ << "SD Failed at xran_bm_allocate_buffer , status %d\n" << status << std::endl;
return (-1);
}
pPrbElem->p_sec_desc[k] = (struct xran_section_desc *)sd_ptr;
}
}
}
}
}
for (i = 0; i < nSectorNum; i++) {
printf("wrapper.hpp: Init memory *** XRANFTHRX_IN ***\n");
eInterfaceType = XRANFTHRX_IN;
status = xran_bm_init(m_nInstanceHandle[0][i],
&m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT,
m_nSW_ToFpga_FTH_TxBufferLen); /* ????, actual alloc size is m_nFpgaToSW_FTH_RxBUfferLen */
if (status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
for (j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
for (z = 0; z < xran_max_antenna_nr; z++) {
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFrontHaulRxBuffers[j][i][z][0];
for (k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = m_nFpgaToSW_FTH_RxBufferLen;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
if (status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer, status " << status << std::endl;
return (-1);
}
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
if (ptr) {
u32dptr = (uint32_t *)(ptr);
memset(u32dptr, 0x0, m_nFpgaToSW_FTH_RxBufferLen);
}
}
}
}
printf("wrapper.hpp: Init memory *** XRANFTHTX_SEC_DESC_IN ***\n");
eInterfaceType = XRANFTHTX_SEC_DESC_IN;
status = xran_bm_init(m_nInstanceHandle[0][i],
&m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT * XRAN_MAX_SECTIONS_PER_SYM,
sizeof(struct xran_section_desc));
if (XRAN_STATUS_SUCCESS != status) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
printf("wrapper.hpp: Init memory *** XRANFTHRX_PRB_MAP_IN ***\n");
eInterfaceType = XRANFTHRX_PRB_MAP_IN;
status =
xran_bm_init(m_nInstanceHandle[0][i], &m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
if (status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
for (j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
for (z = 0; z < xran_max_antenna_nr; z++) {
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFrontHaulRxPrbMapBuffers[j][i][z];
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
if (status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer , status " << status << std::endl;
return (-1);
}
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
void *sd_ptr;
void *sd_mb;
int elm_id;
struct xran_prb_map *p_rb_map = (struct xran_prb_map *)ptr;
for (elm_id = 0; elm_id < XRAN_MAX_SECTIONS_PER_SYM; elm_id++) {
struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id];
for (k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][XRANFTHTX_SEC_DESC_IN], &sd_ptr, &sd_mb);
if (XRAN_STATUS_SUCCESS != status) {
std::cout << __LINE__ << "SD Failed at xran_bm_allocate_buffer , status %d\n" << status << std::endl;
return (-1);
}
pPrbElem->p_sec_desc[k] = (struct xran_section_desc *)sd_ptr;
}
}
}
}
}
for (i = 0; i < nSectorNum; i++) {
printf("wrapper.hpp: Init memory *** XRANFTHRACH_IN ***\n");
eInterfaceType = XRANFTHRACH_IN;
status = xran_bm_init(
m_nInstanceHandle[0][i], &m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN * xran_max_antenna_nr * XRAN_NUM_OF_SYMBOL_PER_SLOT, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
if (status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
for (j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
for (z = 0; z < xran_max_antenna_nr; z++) {
m_sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = xran_max_antenna_nr;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFHPrachRxBuffers[j][i][z][0];
for (k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = FPGA_TO_SW_PRACH_RX_BUFFER_LEN;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
if (status != XRAN_STATUS_SUCCESS) {
std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer, status " << status << std::endl;
return (-1);
}
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
if (ptr) {
u32dptr = (uint32_t *)(ptr);
memset(u32dptr, 0x0, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
}
}
}
}
}
/* Insert the allocation of srs buffers useful for xran_5g_srs_req()
Code taken from sample app */
/* Add SRS rx buffer */
for (i = 0; i < nSectorNum && xran_max_ant_array_elm_nr; i++) {
printf("wrapper.hpp: Init memory *** XRANSRS_IN ***\n");
eInterfaceType = XRANSRS_IN;
status = xran_bm_init(m_nInstanceHandle[0][i],
&m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
XRAN_N_FE_BUF_LEN * xran_max_ant_array_elm_nr * XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT,
m_nSW_ToFpga_FTH_TxBufferLen);
if (XRAN_STATUS_SUCCESS != status) {
std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
return (-1);
}
for (j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
for (z = 0; z < xran_max_ant_array_elm_nr; z++) {
m_sFHSrsRxBbuIoBufCtrl[j][i][z].bValid = 0;
m_sFHSrsRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
m_sFHSrsRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
m_sFHSrsRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
m_sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = xran_max_ant_array_elm_nr; /* ant number */
m_sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFHSrsRxBuffers[j][i][z][0];
for (k = 0; k < XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT; k++) {
m_sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = m_nSW_ToFpga_FTH_TxBufferLen;
m_sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
m_sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
if (XRAN_STATUS_SUCCESS != status) {
std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer, status " << status << std::endl;
return (-1);
}
m_sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
m_sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
if (ptr) {
u32dptr = (uint32_t *)(ptr);
memset(u32dptr, 0x0, m_nSW_ToFpga_FTH_TxBufferLen);
}
}
}
}
}
return (0);
}
// Class Constructor
xranLibWraper::xranLibWraper()
{
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Put here all the variables that are hard coded and assign them to a variable.
// This should then be changed to a dynamic config
// At least for now we group all the hard coded value we want to get rid of them
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// From xran_io_cfg of xran_fh_o_du.h
uint8_t id_ = 0;
uint8_t num_vfs_ = 2;
// From xran_eaxcid_config of xran_fh_o_du.h
uint8_t bit_cuPortId_ = 12; //(??) bitnum_bandsec + bitnum_ccid + bitnum_ruport;
uint8_t bit_bandSectorId_ = 8; //(??) bitnum_ccid + bitnum_ruport;
uint8_t bit_ccId_ = 4; //(??) bitnum_ruport;
uint8_t bit_ruPortId_ = 0;
uint16_t mask_cuPortId_ = 0xf000; // get_eaxcid_mask(bitnum_cuport, m_xranInit.eAxCId_conf.bit_cuPortId);
uint16_t mask_bandSectorId_ = 0x0f00; // get_eaxcid_mask(bitnum_bandsec, m_xranInit.eAxCId_conf.bit_bandSectorId);
uint16_t mask_ccId_ = 0x00f0; // get_eaxcid_mask(bitnum_ccid, m_xranInit.eAxCId_conf.bit_ccId);
uint16_t mask_ruPortId_ = 0x000f; // get_eaxcid_mask(bitnum_ruport, m_xranInit.eAxCId_conf.bit_ruPortId);
// From xran_fh_init of xran_fh_o_du.h
uint8_t enableCP_ = 1;
uint8_t prachEnable_ = 1;
int32_t debugStop_ = 0;
int32_t debugStopCount_ = 0;
int32_t DynamicSectionEna_ = 0;
const char *filePrefix_ = "wls";
// Independent
m_nSlots = 0;
m_du_mac[0] = 0x00;
m_du_mac[1] = 0x11;
m_du_mac[2] = 0x22;
m_du_mac[3] = 0x33;
m_du_mac[4] = 0x44;
m_du_mac[5] = 0x55;
int i, temp, j;
std::string tmpstr;
unsigned int tmp_mac[6];
m_global_cfg = read_json_from_file(XRAN_UT_CFG_FILENAME);
memset(&m_xranInit, 0, sizeof(xran_fh_init));
m_xranInit.io_cfg.id = id_;
/* DPDK configuration */
m_dpdk_dev_up = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdk_dev_up");
m_dpdk_dev_cp = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdk_dev_cp");
m_xranInit.io_cfg.dpdk_dev[XRAN_CP_VF] = (m_dpdk_dev_cp == "") ? NULL : (char *)&m_dpdk_dev_cp[0];
m_xranInit.io_cfg.dpdk_dev[XRAN_UP_VF] = (m_dpdk_dev_cp == "") ? NULL : (char *)&m_dpdk_dev_up[0];
std::cout << "UP_VF [" << m_xranInit.io_cfg.dpdk_dev[XRAN_UP_VF] << "], CP_VF [" << m_xranInit.io_cfg.dpdk_dev[XRAN_CP_VF] << "]" << std::endl;
m_xranInit.io_cfg.num_vfs = num_vfs_;
printf(
"wrapper.hpp: m_xranInit.io_cfg.dpdk_dev[%d] =%s, m_xranInit.io_cfg.dpdk_dev[%d]=%s\n", XRAN_UP_VF, m_xranInit.io_cfg.dpdk_dev[XRAN_UP_VF], XRAN_CP_VF, m_xranInit.io_cfg.dpdk_dev[XRAN_CP_VF]);
m_xranInit.io_cfg.core = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "core");
m_xranInit.io_cfg.system_core = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "system_core");
uint8_t tmp_pkt_proc_core = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "pkt_proc_core");
m_xranInit.io_cfg.pkt_proc_core = (uint64_t)1 << tmp_pkt_proc_core;
m_xranInit.io_cfg.pkt_aux_core = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "pkt_aux_core");
m_xranInit.io_cfg.timing_core = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "timing_core");
std::string bbdev_mode = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "bbdev_mode");
if (bbdev_mode == "sw")
m_xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_MODE_HW_OFF;
else if (bbdev_mode == "hw")
m_xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_MODE_HW_ON;
else if (bbdev_mode == "none")
m_xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED;
else {
std::cout << "Invalid BBDev mode [" << bbdev_mode << "], bbdev won't be used." << std::endl;
m_xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED;
}
m_xranInit.dpdkBasebandFecMode = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdkBasebandFecMode");
m_dpdk_bbdev = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdkBasebandDevice");
m_xranInit.dpdkBasebandDevice = (m_dpdk_bbdev == "") ? NULL : (char *)&m_dpdk_bbdev;
/* Network configurations */
m_xranInit.mtu = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "mtu");
std::string du_mac_str = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "o_du_macaddr");
std::string ru_mac_str = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "o_ru_macaddr");
/* using temp variables to resolve KW issue */
std::sscanf(du_mac_str.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x", &tmp_mac[0], &tmp_mac[1], &tmp_mac[2], &tmp_mac[3], &tmp_mac[4], &tmp_mac[5]);
for (i = 0; i < 6; i++)
m_du_mac[i] = (uint8_t)tmp_mac[i];
std::sscanf(ru_mac_str.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x", &tmp_mac[0], &tmp_mac[1], &tmp_mac[2], &tmp_mac[3], &tmp_mac[4], &tmp_mac[5]);
for (j = 0; j < XRAN_VF_MAX; j++) {
for (i = 0; i < 6; i++)
m_ru_mac[j][i] = (uint8_t)tmp_mac[i];
}
m_xranInit.p_o_du_addr = (int8_t *)m_du_mac;
m_xranInit.p_o_ru_addr = (int8_t *)m_ru_mac;
m_xranInit.cp_vlan_tag = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "cp_vlan_tag");
m_xranInit.up_vlan_tag = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "up_vlan_tag");
/* eAxCID configurations */
// int bitnum_cuport = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_cuPortId"); // Hard C
// int bitnum_bandsec = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_bandSectorId"); //Hard C
// int bitnum_ccid = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_ccId"); //Hard C
// int bitnum_ruport = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_ruPortId"); //Hard C
m_xranInit.eAxCId_conf.bit_cuPortId = bit_cuPortId_;
m_xranInit.eAxCId_conf.bit_bandSectorId = bit_bandSectorId_;
m_xranInit.eAxCId_conf.bit_ccId = bit_ccId_;
m_xranInit.eAxCId_conf.bit_ruPortId = bit_ruPortId_;
m_xranInit.eAxCId_conf.mask_cuPortId = mask_cuPortId_;
m_xranInit.eAxCId_conf.mask_bandSectorId = mask_bandSectorId_;
m_xranInit.eAxCId_conf.mask_ccId = mask_ccId_;
m_xranInit.eAxCId_conf.mask_ruPortId = mask_ruPortId_;
m_xranInit.totalBfWeights = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "totalBfWeights");
m_xranInit.Tadv_cp_dl = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Tadv_cp_dl");
m_xranInit.T2a_min_cp_dl = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_cp_dl");
m_xranInit.T2a_max_cp_dl = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_cp_dl");
m_xranInit.T2a_min_cp_ul = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_cp_ul");
m_xranInit.T2a_max_cp_ul = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_cp_ul");
m_xranInit.T2a_min_up = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_up");
m_xranInit.T2a_max_up = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_up");
m_xranInit.Ta3_min = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta3_min");
m_xranInit.Ta3_max = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta3_max");
m_xranInit.T1a_min_cp_dl = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_cp_dl");
m_xranInit.T1a_max_cp_dl = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_cp_dl");
m_xranInit.T1a_min_cp_ul = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_cp_ul");
m_xranInit.T1a_max_cp_ul = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_cp_ul");
m_xranInit.T1a_min_up = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_up");
m_xranInit.T1a_max_up = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_up");
m_xranInit.Ta4_min = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta4_min");
m_xranInit.Ta4_max = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta4_max");
m_xranInit.enableCP = enableCP_;
m_xranInit.prachEnable = prachEnable_;
m_xranInit.debugStop = debugStop_;
m_xranInit.debugStopCount = debugStopCount_;
m_xranInit.DynamicSectionEna = DynamicSectionEna_;
m_xranInit.filePrefix = const_cast<char *>(filePrefix_);
m_bSub6 = get_globalcfg<bool>(XRAN_UT_KEY_GLOBALCFG_RU, "sub6");
memset(&m_xranConf, 0, sizeof(struct xran_fh_config));
tmpstr = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "duplex");
if (tmpstr == "FDD") {
m_xranConf.frame_conf.nFrameDuplexType = 0;
} else if (tmpstr == "TDD") {
m_xranConf.frame_conf.nFrameDuplexType = 1;
std::string slotcfg_key = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "slot_config");
int numcfg = get_globalcfg<int>(slotcfg_key, "period");
m_xranConf.frame_conf.nTddPeriod = numcfg;
for (int i = 0; i < numcfg; i++) {
std::stringstream slotcfgname;
slotcfgname << "slot" << i;
std::vector<int> slotcfg = get_globalcfg_array<int>(slotcfg_key, slotcfgname.str());
for (uint16_t j = 0; j < slotcfg.size(); j++) {
m_xranConf.frame_conf.sSlotConfig[i].nSymbolType[j] = slotcfg[j];
}
m_xranConf.frame_conf.sSlotConfig[i].reserved[0] = 0;
m_xranConf.frame_conf.sSlotConfig[i].reserved[1] = 0;
}
} else {
std::cout << "*** Invalid Duplex type [" << tmpstr << "] !!!" << std::endl;
std::cout << "****** Set it to FDD... " << std::endl;
m_xranConf.frame_conf.nFrameDuplexType = 0;
}
m_xranConf.frame_conf.nNumerology = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "mu");
if (m_xranConf.frame_conf.nNumerology > 3) {
std::cout << "*** Invalid Numerology [" << m_xranConf.frame_conf.nNumerology << "] !!!" << std::endl;
m_xranConf.frame_conf.nNumerology = 1;
std::cout << "****** Setting it to " << m_xranConf.frame_conf.nNumerology << "..." << std::endl;
}
switch (m_xranConf.frame_conf.nNumerology) {
case 0: /* Numerology - 0 */
m_nSlots = 10;
break;
case 1: /* Numerology - 1 */
m_nSlots = 20;
break;
case 2: /* Numerology - 2 */
m_nSlots = 40;
break;
case 3: /* Numerology - 3 */
m_nSlots = 80;
break;
}
std::cout << "*** Numerology [" << m_xranConf.frame_conf.nNumerology << "] " << std::endl;
std::cout << "*** Number of Slot [" << m_nSlots << "] " << std::endl;
m_xranConf.nCC = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "num_cc");
if (m_xranConf.nCC > XRAN_MAX_SECTOR_NR) {
std::cout << "*** Exceeds maximum number of carriers supported [" << m_xranConf.nCC << "] !!!" << std::endl;
m_xranConf.nCC = XRAN_MAX_SECTOR_NR;
std::cout << "****** Adjusted to " << m_xranConf.nCC << "..." << std::endl;
}
m_xranConf.neAxc = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "num_eaxc");
if (m_xranConf.neAxc > XRAN_MAX_ANTENNA_NR) {
std::cout << "*** Exceeds maximum number of antenna supported [" << m_xranConf.neAxc << "] !!!" << std::endl;
m_xranConf.neAxc = XRAN_MAX_ANTENNA_NR;
std::cout << "****** Adjusted to " << m_xranConf.neAxc << "..." << std::endl;
}
m_bSub6 = get_globalcfg<bool>(XRAN_UT_KEY_GLOBALCFG_RU, "sub6");
temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "chbw_dl");
m_xranConf.nDLRBs = get_num_rbs(get_numerology(), temp, m_bSub6);
temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "chbw_ul");
m_xranConf.nULRBs = get_num_rbs(get_numerology(), temp, m_bSub6);
m_xranConf.nAntElmTRx = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "ant_elm_trx");
m_xranConf.nDLFftSize = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
m_xranConf.nULFftSize = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
m_xranConf.prach_conf.nPrachConfIdx = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "config_id");
m_xranConf.prach_conf.nPrachSubcSpacing = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "scs");
m_xranConf.prach_conf.nPrachFreqStart = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "freq_start");
m_xranConf.prach_conf.nPrachFreqOffset = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "freq_offset");
m_xranConf.prach_conf.nPrachFilterIdx = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "filter_id");
m_xranConf.prach_conf.nPrachZeroCorrConf = 0;
m_xranConf.prach_conf.nPrachRestrictSet = 0;
m_xranConf.prach_conf.nPrachRootSeqIdx = 0;
tmpstr = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "category");
if (tmpstr == "A")
m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_A;
else if (tmpstr == "B")
m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_B;
else {
std::cout << "*** Invalid RU Category [" << tmpstr << "] !!!" << std::endl;
std::cout << "****** Set it to Category A... " << std::endl;
m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_A;
}
m_xranConf.ru_conf.iqWidth = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "iq_width");
std::cout << "*** IQ Width [" << m_xranConf.ru_conf.iqWidth << "]" << std::endl;
m_xranConf.ru_conf.compMeth = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "comp_meth");
std::cout << "*** Compression Method [" << m_xranConf.ru_conf.compMeth << "]" << std::endl;
temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
m_xranConf.ru_conf.fftSize = 0;
while (temp >>= 1)
++m_xranConf.ru_conf.fftSize;
m_xranConf.ru_conf.byteOrder = XRAN_NE_BE_BYTE_ORDER;
m_xranConf.ru_conf.iqOrder = XRAN_I_Q_ORDER;
m_xranConf.log_level = 1;
}
// Class Destructor
xranLibWraper::~xranLibWraper()
{
}
int xranLibWraper::SetUp()
{
int i;
printf("O-DU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
m_xranInit.p_o_du_addr[0],
m_xranInit.p_o_du_addr[1],
m_xranInit.p_o_du_addr[2],
m_xranInit.p_o_du_addr[3],
m_xranInit.p_o_du_addr[4],
m_xranInit.p_o_du_addr[5]);
printf("O-RU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
m_xranInit.p_o_ru_addr[0],
m_xranInit.p_o_ru_addr[1],
m_xranInit.p_o_ru_addr[2],
m_xranInit.p_o_ru_addr[3],
m_xranInit.p_o_ru_addr[4],
m_xranInit.p_o_ru_addr[5]);
printf("eAxCID - %d:%d:%d:%d (%04x, %04x, %04x, %04x)\n",
m_xranInit.eAxCId_conf.bit_cuPortId,
m_xranInit.eAxCId_conf.bit_bandSectorId,
m_xranInit.eAxCId_conf.bit_ccId,
m_xranInit.eAxCId_conf.bit_ruPortId,
m_xranInit.eAxCId_conf.mask_cuPortId,
m_xranInit.eAxCId_conf.mask_bandSectorId,
m_xranInit.eAxCId_conf.mask_ccId,
m_xranInit.eAxCId_conf.mask_ruPortId);
printf("Total BF Weights : %d\n", m_xranInit.totalBfWeights);
xran_init(0, NULL, &m_xranInit, &argv[0], &m_xranhandle);
for (i = 0; i < XRAN_MAX_SECTOR_NR; i++)
m_nSectorIndex[i] = i;
/* set to maximum length to support multiple cases */
m_nFpgaToSW_FTH_RxBufferLen = 13168; /* 273*12*4 + 64*/
m_nSW_ToFpga_FTH_TxBufferLen =
13168 + /* 273*12*4 + 64* + ETH AND ORAN HDRs */
XRAN_MAX_SECTIONS_PER_SYM * (RTE_PKTMBUF_HEADROOM + sizeof(struct rte_ether_hdr) + sizeof(struct xran_ecpri_hdr) + sizeof(struct radio_app_common_hdr) + sizeof(struct data_section_hdr));
printf("wrapper.hpp: nFpgaToSW_FTH_RxBufferLen=%d , nSW_ToFpga_FTH_TxBufferLen=%d\n", m_nFpgaToSW_FTH_RxBufferLen, m_nSW_ToFpga_FTH_TxBufferLen);
if (init_memory() < 0) {
std::cout << "Fatal Error on Initialization !!!" << std::endl;
std::cout << "INIT FAILED" << std::endl;
return (-1);
}
std::cout << "INIT DONE" << std::endl;
return (0);
}
void xranLibWraper::TearDown()
{
if (m_xranhandle) {
xran_close(m_xranhandle);
m_xranhandle = nullptr;
std::cout << "CLOSE DONE" << std::endl;
} else
std::cout << "ALREADY CLOSED" << std::endl;
}
//------------------------------------------------------------------------------------------------------------------------------------------------
int xranLibWraper::Init(struct xran_fh_config *pCfg)
{
int32_t nSectorNum;
uint32_t i;
int32_t cc_id, tti;
uint32_t ant_id;
struct xran_prb_map *pRbMap = NULL;
uint32_t xran_max_antenna_nr = RTE_MAX(get_num_eaxc(), get_num_eaxc_ul());
uint8_t symbol_counter = 0;
uint8_t symbol_config = 0;
uint8_t mixed_slot = 0;
uint8_t mixed_slot_dl_symbol = 0;
uint8_t mixed_slot_dl_start_symbol = 0;
bool mixed_slot_dl_start_symbol_found = 0;
uint8_t mixed_slot_ul_symbol = 0;
uint8_t mixed_slot_ul_start_symbol = 0;
bool mixed_slot_ul_start_symbol_found = 0;
uint8_t mixed_slot_gaurd_symbol = 0;
uint8_t mixed_slot_tti_index[40];
/* Update member variables */
if (pCfg)
memcpy(&m_xranConf, pCfg, sizeof(struct xran_fh_config));
/* Init timer context */
xran_lib_ota_tti = 0;
xran_lib_ota_sym = 0;
xran_lib_ota_sym_idx = 0;
for (i = 0; i < MAX_NUM_OF_XRAN_CTX; i++)
m_timer_ctx[i].tti_to_process = i;
nSectorNum = get_num_cc();
/* Cat B RU support */
if (get_rucategory() == XRAN_CATEGORY_B) {
/* 10 * [14*32*273*2*2] = 4892160 bytes */
iq_bfw_buffer_size_dl = (m_nSlots * N_SYM_PER_SLOT * get_num_antelmtrx() * get_num_dlrbs() * 4L);
iq_bfw_buffer_size_ul = (m_nSlots * N_SYM_PER_SLOT * get_num_antelmtrx() * get_num_ulrbs() * 4L);
for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(get_num_cc() * get_num_eaxc()); i++) {
p_tx_dl_bfw_buffer[i] = (int16_t *)malloc(iq_bfw_buffer_size_dl);
tx_dl_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_dl;
if (p_tx_dl_bfw_buffer[i] == NULL)
return (-1);
memset(p_tx_dl_bfw_buffer[i], 'D', iq_bfw_buffer_size_dl);
tx_dl_bfw_buffer_position[i] = 0;
p_tx_ul_bfw_buffer[i] = (int16_t *)malloc(iq_bfw_buffer_size_ul);
tx_ul_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_ul;
if (p_tx_ul_bfw_buffer[i] == NULL)
return (-1);
memset(p_tx_ul_bfw_buffer[i], 'U', iq_bfw_buffer_size_ul);
tx_ul_bfw_buffer_position[i] = 0;
}
}
for (uint8_t period_counter = 0; period_counter < m_xranConf.frame_conf.nTddPeriod; period_counter++) {
uint8_t symbol;
symbol_config = m_xranConf.frame_conf.sSlotConfig[period_counter].nSymbolType[0];
for (symbol = 0; symbol < 14; symbol++) {
if (symbol_config == m_xranConf.frame_conf.sSlotConfig[period_counter].nSymbolType[symbol])
symbol_counter++;
}
if (symbol_counter != 14) {
mixed_slot = period_counter;
symbol = 0;
while (symbol < 14) {
switch (m_xranConf.frame_conf.sSlotConfig[period_counter].nSymbolType[symbol]) {
case 0: /* DL Symbol */
if (!mixed_slot_dl_start_symbol_found) {
mixed_slot_dl_start_symbol_found = 1;
mixed_slot_dl_start_symbol = symbol;
}
mixed_slot_dl_symbol++;
break;
case 1: /* UL Symbol */
if (!mixed_slot_ul_start_symbol_found) {
mixed_slot_ul_start_symbol_found = 1;
mixed_slot_ul_start_symbol = symbol;
}
mixed_slot_ul_symbol++;
break;
default: /* Guard Period */
mixed_slot_gaurd_symbol++;
}
symbol++;
}
break;
}
symbol_counter = 0;
printf("\n");
}
memset(mixed_slot_tti_index, 0, sizeof(mixed_slot_tti_index));
mixed_slot_tti_index[mixed_slot] = 1;
for (uint8_t kk = 1; kk < (XRAN_N_FE_BUF_LEN / m_xranConf.frame_conf.nTddPeriod); kk++) {
mixed_slot_tti_index[kk * (m_xranConf.frame_conf.nTddPeriod) + mixed_slot] = 1;
}
/* Init RB map */
for (cc_id = 0; cc_id < nSectorNum; cc_id++) {
for (tti = 0; tti < XRAN_N_FE_BUF_LEN; tti++) {
for (ant_id = 0; ant_id < xran_max_antenna_nr; ant_id++) {
// flowId = xran_max_antenna_nr*cc_id + ant_id;
/* C-plane DL */
pRbMap = (struct xran_prb_map *)m_sFrontHaulTxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
if (pRbMap) {
pRbMap->dir = XRAN_DIR_DL;
pRbMap->xran_port = 0;
pRbMap->band_id = 0;
pRbMap->cc_id = cc_id;
pRbMap->ru_port_id = ant_id;
pRbMap->tti_id = tti;
pRbMap->start_sym_id = 0;
pRbMap->nPrbElm = 1;
pRbMap->prbMap[0].nRBStart = 0;
pRbMap->prbMap[0].nRBSize = get_num_dlrbs();
if (mixed_slot_tti_index[tti]) {
pRbMap->prbMap[0].nStartSymb = mixed_slot_dl_start_symbol;
pRbMap->prbMap[0].numSymb = mixed_slot_dl_symbol;
} else {
pRbMap->prbMap[0].nStartSymb = 0;
pRbMap->prbMap[0].numSymb = 14;
}
pRbMap->prbMap[0].nBeamIndex = 0;
/* Update according to the target compression in oran.fhi.json */
pRbMap->prbMap[0].compMethod = m_xranConf.ru_conf.compMeth; /* xran_compression_method */
/* Update according to the target compression in oran.fhi.json */
pRbMap->prbMap[0].iqWidth = m_xranConf.ru_conf.iqWidth;
if (get_rucategory() == XRAN_CATEGORY_A) {
pRbMap->prbMap[0].BeamFormingType = XRAN_BEAM_ID_BASED;
pRbMap->prbMap[0].bf_weight_update = 0;
} else if (get_rucategory() == XRAN_CATEGORY_B) {
pRbMap->prbMap[0].BeamFormingType = XRAN_BEAM_WEIGHT;
pRbMap->prbMap[0].bf_weight_update = 1;
} /* else if(get_rucategory() == XRAN_CATEGORY_B) */
} /* if(pRbMap) */
else {
std::cout << "DL pRbMap ==NULL" << std::endl;
}
/* C-plane UL */
pRbMap = (struct xran_prb_map *)m_sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
if (pRbMap) {
pRbMap->dir = XRAN_DIR_UL;
pRbMap->xran_port = 0;
pRbMap->band_id = 0;
pRbMap->cc_id = cc_id;
pRbMap->ru_port_id = ant_id;
pRbMap->tti_id = tti;
pRbMap->start_sym_id = 0;
pRbMap->nPrbElm = 1;
pRbMap->prbMap[0].nRBStart = 0;
pRbMap->prbMap[0].nRBSize = get_num_ulrbs();
if (mixed_slot_tti_index[tti]) {
pRbMap->prbMap[0].nStartSymb = mixed_slot_ul_start_symbol;
pRbMap->prbMap[0].numSymb = mixed_slot_ul_symbol;
} else {
pRbMap->prbMap[0].nStartSymb = 0;
pRbMap->prbMap[0].numSymb = 14;
}
pRbMap->prbMap[0].nBeamIndex = 0;
/* xran_compression_method */
/* Modify according to the target compression from oran.fhi.json */
pRbMap->prbMap[0].compMethod = m_xranConf.ru_conf.compMeth;
/* Update IQ-Width based on oran.fhi.json */
pRbMap->prbMap[0].iqWidth = m_xranConf.ru_conf.iqWidth;
if (get_rucategory() == XRAN_CATEGORY_A) {
pRbMap->prbMap[0].BeamFormingType = XRAN_BEAM_ID_BASED;
pRbMap->prbMap[0].bf_weight_update = 0;
} else if (get_rucategory() == XRAN_CATEGORY_B) {
pRbMap->prbMap[0].BeamFormingType = XRAN_BEAM_WEIGHT;
pRbMap->prbMap[0].bf_weight_update = 1;
} /* else if(get_rucategory() == XRAN_CATEGORY_B) */
} /* if(pRbMap) */
else {
std::cout << "UL: pRbMap ==NULL" << std::endl;
}
}
}
}
return (0);
}
void xranLibWraper::Cleanup()
{
uint32_t i;
if (get_rucategory() == XRAN_CATEGORY_B) {
for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(get_num_cc() * get_num_eaxc()); i++) {
if (p_tx_dl_bfw_buffer[i]) {
free(p_tx_dl_bfw_buffer[i]);
p_tx_dl_bfw_buffer[i] = NULL;
}
if (p_tx_ul_bfw_buffer[i]) {
free(p_tx_ul_bfw_buffer[i]);
p_tx_ul_bfw_buffer[i] = NULL;
}
}
}
return;
}
void xranLibWraper::Open(xran_ethdi_mbuf_send_fn send_cp, xran_ethdi_mbuf_send_fn send_up, void *fh_rx_callback, void *fh_rx_prach_callback, void *fh_srs_callback)
{
int32_t nSectorNum;
int i, j;
uint32_t z;
uint32_t xran_max_antenna_nr = RTE_MAX(get_num_eaxc(), get_num_eaxc_ul());
uint32_t xran_max_ant_array_elm_nr = RTE_MAX(get_num_antelmtrx(), xran_max_antenna_nr);
struct xran_buffer_list *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *pFthTxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *pFthRxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
struct xran_buffer_list *pFthRxSrsBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN];
nSectorNum = get_num_cc();
for (i = 0; i < nSectorNum; i++) {
for (j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
for (z = 0; z < XRAN_MAX_ANTENNA_NR; z++) {
pFthTxBuffer[i][z][j] = NULL;
pFthTxPrbMapBuffer[i][z][j] = NULL;
pFthRxBuffer[i][z][j] = NULL;
pFthRxPrbMapBuffer[i][z][j] = NULL;
pFthRxRachBuffer[i][z][j] = NULL;
}
for (z = 0; z < xran_max_ant_array_elm_nr; z++) {
pFthRxSrsBuffer[i][z][j] = NULL;
}
}
}
for (i = 0; i < nSectorNum; i++) {
for (j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
for (z = 0; z < xran_max_antenna_nr; z++) {
pFthTxBuffer[i][z][j] = &(m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList);
pFthTxPrbMapBuffer[i][z][j] = &(m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
pFthRxBuffer[i][z][j] = &(m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList);
pFthRxPrbMapBuffer[i][z][j] = &(m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
pFthRxRachBuffer[i][z][j] = &(m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList);
}
for (z = 0; z < xran_max_ant_array_elm_nr && xran_max_ant_array_elm_nr; z++) {
pFthRxSrsBuffer[i][z][j] = &(m_sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList);
}
}
}
if (m_nInstanceHandle[0] != NULL) {
for (i = 0; i < nSectorNum; i++) {
xran_5g_fronthault_config(
m_nInstanceHandle[0][i], pFthTxBuffer[i], pFthTxPrbMapBuffer[i], pFthRxBuffer[i], pFthRxPrbMapBuffer[i], (void (*)(void *, xran_status_t))fh_rx_callback, &pFthRxBuffer[i][0]);
xran_5g_prach_req(m_nInstanceHandle[0][i], pFthRxRachBuffer[i], (void (*)(void *, xran_status_t))fh_rx_prach_callback, &pFthRxRachBuffer[i][0]);
}
/* add SRS callback here */
}
xran_register_cb_mbuf2ring(send_cp, send_up);
}
void xranLibWraper::Close()
{
if (m_xranhandle)
xran_close(m_xranhandle);
}
int xranLibWraper::Start()
{
if (m_xranhandle)
return (xran_start(m_xranhandle));
else
return (-1);
}
int xranLibWraper::Stop()
{
if (m_xranhandle)
return (xran_stop(m_xranhandle));
else
return (-1);
}
/* Emulation of timer */
void xranLibWraper::update_tti()
{
tti_ota_cb(nullptr, get_timer_ctx());
}
void xranLibWraper::update_symbol_index()
{
xran_lib_ota_sym_idx++;
if ((xran_lib_ota_sym_idx % N_SYM_PER_SLOT) == 0) {
update_tti();
}
xran_lib_ota_sym++;
if (xran_lib_ota_sym >= N_SYM_PER_SLOT)
xran_lib_ota_sym = 0;
}
int xranLibWraper::apply_cpenable(bool flag)
{
struct xran_device_ctx *pCtx = xran_dev_get_ctx();
if (is_running())
return (-1);
if (pCtx == nullptr)
return (-1);
if (flag == true) {
m_xranInit.enableCP = 1;
pCtx->enableCP = 1;
} else {
m_xranInit.enableCP = 0;
pCtx->enableCP = 0;
}
return (0);
}
int xranLibWraper::get_slot_config(const std::string &cfgname, struct xran_frame_config *pCfg)
{
int numcfg, i;
uint32_t j;
std::vector<int> slotcfg;
numcfg = get_globalcfg<int>(cfgname, "period");
pCfg->nTddPeriod = numcfg;
for (i = 0; i < numcfg; i++) {
std::stringstream slotcfgname;
slotcfgname << "slot" << i;
std::vector<int> slotcfg = get_globalcfg_array<int>(cfgname, slotcfgname.str());
for (j = 0; j < slotcfg.size(); j++)
pCfg->sSlotConfig[i].nSymbolType[j] = slotcfg[j];
pCfg->sSlotConfig[i].reserved[0] = 0;
pCfg->sSlotConfig[i].reserved[1] = 0;
}
return (numcfg);
}
int xranLibWraper::get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, bool nSub6)
{
if (nNumerology > 3)
return (-1);
if (nSub6) {
if (nNumerology < 3) {
/* F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB */
switch (nBandwidth) {
case PHY_BW_5MHZ:
return (nNumRbsPerSymF1[nNumerology][0]);
case PHY_BW_10MHZ:
return (nNumRbsPerSymF1[nNumerology][1]);
case PHY_BW_15MHZ:
return (nNumRbsPerSymF1[nNumerology][2]);
case PHY_BW_20MHZ:
return (nNumRbsPerSymF1[nNumerology][3]);
case PHY_BW_25MHZ:
return (nNumRbsPerSymF1[nNumerology][4]);
case PHY_BW_30MHZ:
return (nNumRbsPerSymF1[nNumerology][5]);
case PHY_BW_40MHZ:
return (nNumRbsPerSymF1[nNumerology][6]);
case PHY_BW_50MHZ:
return (nNumRbsPerSymF1[nNumerology][7]);
case PHY_BW_60MHZ:
return (nNumRbsPerSymF1[nNumerology][8]);
case PHY_BW_70MHZ:
return (nNumRbsPerSymF1[nNumerology][9]);
case PHY_BW_80MHZ:
return (nNumRbsPerSymF1[nNumerology][10]);
case PHY_BW_90MHZ:
return (nNumRbsPerSymF1[nNumerology][11]);
case PHY_BW_100MHZ:
return (nNumRbsPerSymF1[nNumerology][12]);
}
}
} else { /* if(nSub6) */
if ((nNumerology >= 2) && (nNumerology <= 3)) {
nNumerology -= 2;
/* F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB */
switch (nBandwidth) {
case PHY_BW_50MHZ:
return (nNumRbsPerSymF2[nNumerology][0]);
break;
case PHY_BW_100MHZ:
return (nNumRbsPerSymF2[nNumerology][1]);
break;
case PHY_BW_200MHZ:
return (nNumRbsPerSymF2[nNumerology][2]);
break;
case PHY_BW_400MHZ:
return (nNumRbsPerSymF2[nNumerology][3]);
break;
}
}
}
return (-1);
}
void *xranLibWraper::get_xranhandle()
{
return (m_xranhandle);
}
void *xranLibWraper::get_timer_ctx()
{
return ((void *)&m_timer_ctx[0]);
}
int xranLibWraper::get_symbol_index()
{
return (xran_lib_ota_sym);
}
int xranLibWraper::get_ota_tti()
{
return (xran_lib_ota_tti);
}
int xranLibWraper::get_symbol_offset(int32_t offSym, int32_t otaSym, int32_t numSymTotal, enum xran_in_period *pInPeriod)
{
int32_t sym;
// Suppose the offset is usually small
if (unlikely(offSym > otaSym)) {
sym = numSymTotal - offSym + otaSym;
*pInPeriod = XRAN_IN_PREV_PERIOD;
} else {
sym = otaSym - offSym;
if (unlikely(sym >= numSymTotal)) {
sym -= numSymTotal;
*pInPeriod = XRAN_IN_NEXT_PERIOD;
} else {
*pInPeriod = XRAN_IN_CURR_PERIOD;
}
}
return sym;
}
int xranLibWraper::get_SFN_at_sec_start()
{
return (xran_SFN_at_Sec_Start);
}
bool xranLibWraper::is_running()
{
return ((xran_get_if_state() == XRAN_RUNNING) ? true : false);
}
enum xran_category xranLibWraper::get_rucategory()
{
return (m_xranConf.ru_conf.xranCat);
}
int xranLibWraper::get_numerology()
{
return (m_xranConf.frame_conf.nNumerology);
}
int xranLibWraper::get_duplextype()
{
return (m_xranConf.frame_conf.nFrameDuplexType);
}
uint32_t xranLibWraper::get_num_cc()
{
return (m_xranConf.nCC);
}
uint32_t xranLibWraper::get_num_eaxc()
{
return (m_xranConf.neAxc);
}
uint32_t xranLibWraper::get_num_eaxc_ul()
{
return (m_xranConf.neAxcUl);
}
uint32_t xranLibWraper::get_num_dlrbs()
{
return (m_xranConf.nDLRBs);
}
uint32_t xranLibWraper::get_num_ulrbs()
{
return (m_xranConf.nULRBs);
}
uint32_t xranLibWraper::get_num_antelmtrx()
{
return (m_xranConf.nAntElmTRx);
}
bool xranLibWraper::is_cpenable()
{
return (m_xranInit.enableCP);
};
bool xranLibWraper::is_prachenable()
{
return (m_xranInit.prachEnable);
};
bool xranLibWraper::is_dynamicsection()
{
return (m_xranInit.DynamicSectionEna ? true : false);
}
bool xranLibWraper::get_sub6()
{
return (m_bSub6);
}
void xranLibWraper::get_cfg_prach(struct xran_prach_config *pCfg)
{
if (pCfg)
memcpy(pCfg, &m_xranConf.prach_conf, sizeof(struct xran_prach_config));
}
void xranLibWraper::get_cfg_frame(struct xran_frame_config *pCfg)
{
if (pCfg)
memcpy(pCfg, &m_xranConf.frame_conf, sizeof(struct xran_frame_config));
}
void xranLibWraper::get_cfg_ru(struct xran_ru_config *pCfg)
{
if (pCfg)
memcpy(pCfg, &m_xranConf.ru_conf, sizeof(struct xran_ru_config));
}
void xranLibWraper::get_cfg_fh(struct xran_fh_config *pCfg)
{
if (pCfg)
memcpy(pCfg, &m_xranConf, sizeof(struct xran_fh_config));
}
/*******************************************************************************
* The MIT License (MIT)
* Copyright 2018 JSON for Modern C++
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*
*******************************************************************************/
#ifndef XRAN_LIB_WRAP_HPP
#define XRAN_LIB_WRAP_HPP
#include <exception>
#include <random>
#include <string>
#include <utility>
#include <vector>
#include <malloc.h>
#include <stdint.h>
#include "common.hpp"
#include "xran_fh_o_du.h"
#include "xran_common.h"
#include "xran_frame_struct.h"
#define XRAN_UT_CFG_FILENAME "oran.fhi.json"
#define XRAN_UT_KEY_GLOBALCFG "GLOBAL"
#define XRAN_UT_KEY_GLOBALCFG_IO "io_cfg"
#define XRAN_UT_KEY_GLOBALCFG_EAXCID "eAxCId_cfg"
#define XRAN_UT_KEY_GLOBALCFG_PRACH "prach_cfg"
#define XRAN_UT_KEY_GLOBALCFG_RU "ru_cfg"
#define XRAN_UT_KEY_GLOBALCFG_SLOT "slotcfg_"
#define MAX_NUM_OF_XRAN_CTX (2)
#define SW_FPGA_TOTAL_BUFFER_LEN (4 * 1024 * 1024 * 1024)
#define SW_FPGA_SEGMENT_BUFFER_LEN (1 * 1024 * 1024 * 1024)
#define SW_FPGA_FH_TOTAL_BUFFER_LEN (1 * 1024 * 1024 * 1024)
#define FPGA_TO_SW_PRACH_RX_BUFFER_LEN (8192)
#define MAX_ANT_CARRIER_SUPPORTED (XRAN_MAX_SECTOR_NR * XRAN_MAX_ANTENNA_NR)
enum xran_in_period { XRAN_IN_PREV_PERIOD = 0, XRAN_IN_CURR_PERIOD, XRAN_IN_NEXT_PERIOD };
extern "C" {
extern uint32_t xran_lib_ota_tti;
extern uint32_t xran_lib_ota_sym;
extern uint32_t xran_lib_ota_sym_idx;
extern uint32_t xran_SFN_at_Sec_Start;
void sym_ota_cb(struct rte_timer *tim, void *arg);
void tti_ota_cb(struct rte_timer *tim, void *arg);
}
class xranLibWraper {
public:
typedef enum {
XRANFTHTX_OUT = 0,
XRANFTHTX_PRB_MAP_OUT,
XRANFTHTX_SEC_DESC_OUT,
XRANFTHRX_IN,
XRANFTHRX_PRB_MAP_IN,
XRANFTHTX_SEC_DESC_IN,
XRANFTHRACH_IN,
XRANSRS_IN,
MAX_SW_XRAN_INTERFACE_NUM
} SWXRANInterfaceTypeEnum;
enum nChBw {
PHY_BW_5MHZ = 5,
PHY_BW_10MHZ = 10,
PHY_BW_15MHZ = 15,
PHY_BW_20MHZ = 20,
PHY_BW_25MHZ = 25,
PHY_BW_30MHZ = 30,
PHY_BW_40MHZ = 40,
PHY_BW_50MHZ = 50,
PHY_BW_60MHZ = 60,
PHY_BW_70MHZ = 70,
PHY_BW_80MHZ = 80,
PHY_BW_90MHZ = 90,
PHY_BW_100MHZ = 100,
PHY_BW_200MHZ = 200,
PHY_BW_400MHZ = 400
};
// F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
const uint16_t nNumRbsPerSymF1[3][13] = {
// 5MHz 10MHz 15MHz 20MHz 25MHz 30MHz 40MHz 50MHz 60MHz 70MHz 80MHz 90MHz 100MHz
{25, 52, 79, 106, 133, 160, 216, 270, 0, 0, 0, 0, 0}, // Numerology 0 (15KHz)
{11, 24, 38, 51, 65, 78, 106, 133, 162, 0, 217, 245, 273}, // Numerology 1 (30KHz)
{0, 11, 18, 24, 31, 38, 51, 65, 79, 0, 107, 121, 135} // Numerology 2 (60KHz)
};
// F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
const uint16_t nNumRbsPerSymF2[2][4] = {
// 50MHz 100MHz 200MHz 400MHz
{66, 132, 264, 0}, // Numerology 2 (60KHz)
{32, 66, 132, 264} // Numerology 3 (120KHz)
};
protected:
char argv[25] = {'u', 'n', 'i', 't', 't', 'e', 's', 't', '\0'};
// char argv[25] = "unittest";
std::string m_dpdk_dev_up, m_dpdk_dev_cp, m_dpdk_bbdev;
void *m_xranhandle;
uint8_t m_du_mac[6]; // = { 0x00,0x11, 0x22, 0x33, 0x44, 0x55 }; // This is hard coded here and then it is read from the conf file
uint8_t m_ru_mac[XRAN_VF_MAX][6]; //= { 0x00,0x11, 0x22, 0x33, 0x44, 0x66 }; // This is hard coded here and then it is read from the conf file
bool m_bSub6;
uint32_t m_nSlots; // = 20;
struct xran_fh_config m_xranConf;
struct xran_fh_init m_xranInit;
struct xran_timer_ctx {
uint32_t tti_to_process;
} m_timer_ctx[MAX_NUM_OF_XRAN_CTX];
/* io struct */
BbuIoBufCtrlStruct m_sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
BbuIoBufCtrlStruct m_sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
/* Cat B */
BbuIoBufCtrlStruct m_sFHSrsRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR];
/* buffers lists */
struct xran_flat_buffer m_sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer m_sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
struct xran_flat_buffer m_sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
struct xran_flat_buffer m_sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
struct xran_flat_buffer m_sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
/* Cat B SRS buffers */
struct xran_flat_buffer m_sFHSrsRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT];
void *m_nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; // instance per sector
uint32_t m_nBufPoolIndex[XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM]; // every api owns unique buffer pool
uint32_t m_nSW_ToFpga_FTH_TxBufferLen;
uint32_t m_nFpgaToSW_FTH_RxBufferLen;
int32_t m_nSectorIndex[XRAN_MAX_SECTOR_NR];
int iq_bfw_buffer_size_dl = 0;
int iq_bfw_buffer_size_ul = 0;
/* beamforming weights for UL (O-DU) */
int16_t *p_tx_dl_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_dl_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_dl_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
/* beamforming weights for UL (O-DU) */
int16_t *p_tx_ul_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_ul_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
int32_t tx_ul_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
private:
json m_global_cfg;
template <typename T>
T get_globalcfg(const std::string &type, const std::string &parameter_name)
{
return m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name];
}
template <typename T>
std::vector<T> get_globalcfg_array(const std::string &type, const std::string &parameter_name)
{
auto array_size = m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name].size();
std::vector<T> result(array_size);
for (unsigned number = 0; number < array_size; number++)
result.at(number) = m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name][number];
return result;
}
uint16_t get_eaxcid_mask(int numbit, int shift);
int init_memory();
public:
// Class constructor
xranLibWraper();
// Class Distructor
~xranLibWraper();
int SetUp();
void TearDown();
int Init(struct xran_fh_config *pCfg = nullptr);
void Cleanup();
void Open(xran_ethdi_mbuf_send_fn send_cp, xran_ethdi_mbuf_send_fn send_up, void *fh_rx_callback, void *fh_rx_prach_callback, void *fh_srs_callback);
void Close();
int Start();
int Stop();
/* emulation of timer */
void update_tti();
void update_symbol_index();
int apply_cpenable(bool flag);
int get_slot_config(const std::string &cfgname, struct xran_frame_config *pCfg);
int get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, bool nSub6);
void *get_xranhandle();
void *get_timer_ctx();
int get_symbol_index();
int get_ota_tti();
int get_SFN_at_sec_start();
int get_symbol_offset(int32_t offSym, int32_t otaSym, int32_t numSymTotal, enum xran_in_period *pInPeriod);
bool is_running();
enum xran_category get_rucategory();
int get_numerology();
int get_duplextype();
uint32_t get_num_cc();
uint32_t get_num_eaxc();
uint32_t get_num_eaxc_ul();
uint32_t get_num_dlrbs();
uint32_t get_num_ulrbs();
uint32_t get_num_antelmtrx();
bool is_cpenable();
bool is_prachenable();
bool is_dynamicsection();
bool get_sub6();
void get_cfg_prach(struct xran_prach_config *pCfg);
void get_cfg_frame(struct xran_frame_config *pCfg);
void get_cfg_ru(struct xran_ru_config *pCfg);
void get_cfg_fh(struct xran_fh_config *pCfg);
};
/* external declaration for the instance */
extern xranLibWraper *xranlib;
#endif // XRAN_LIB_WRAP_HPP
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
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;
#sd = 0x1; // 0 false, else true
}
);
});
//nr_cellid = 12345678L;
nr_cellid = 1;
////////// Physical parameters:
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 1;
do_CSIRS = 1;
min_rxtxtime = 4;
sib1_tda = 15;
pdcch_ConfigSIB1 = (
{
controlResourceSetZero = 11;
searchSpaceZero = 0;
}
);
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 3300.24 + 134*12*30e3 = 3348.48 MHz (5G NR GSCN: 7741)
absoluteFrequencySSB = 643392;
dl_frequencyBand = 78;
# this is 3300.24 MHz
dl_absoluteFrequencyPointA = 642816;
#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; #38.101-1 Table 5.3.2-1
#
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 11;
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 = 23;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 1099;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 159;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 15;
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 = 6;
p0_NominalWithGrant = -96
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 0;
p0_nominal = -76;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 0x1;
# 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;
nrofDownlinkSlots = 3;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 1;
nrofUplinkSymbols = 4;
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 = "10.10.10.200";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "ens2f2";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "10.10.10.199/24";
GNB_INTERFACE_NAME_FOR_NGU = "ens2f2";
GNB_IPV4_ADDRESS_FOR_NGU = "10.10.10.199/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 300;
pucch_TargetSNRx10 = 200;
pusch_FailureThres = 1000;
ulsch_max_frame_inactivity = 0;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120
pucch0_dtx_threshold = 80;
pusch_dtx_threshold = 10;
max_ldpc_iterations = 6;
#thread_pool_size = 8;
tx_amp_backoff_dB = 10; #36; #6;
}
);
RUs = (
{
local_rf = "no";
nb_tx = 2;
nb_rx = 1;
att_tx = 0
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
sf_extension = 0;
eNB_instances = [0];
##beamforming 1x2 matrix: 1 layer x 2 antennas
bf_weights = [0x00007fff, 0x0000, 0x00007fff, 0x0000];
tr_preference = "raw_if4p5";
do_precoding = 0;
ru_thread_core = 8;
sl_ahead = 5;
#tp_cores = "26,18,20,22,24";
#num_tp_cores = 5;
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
rfsimulator :
{
serveraddr = "server";
serverport = "4043";
options = (); #("saviq"); or/and "chanmod"
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
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";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="medium";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
ngap_log_level ="info";
ngap_log_verbosity ="medium";
f1ap_log_level ="info";
f1ap_log_verbosity ="medium";
};
{
"GLOBAL": {
"io_cfg": {
"dpdk_dev_up": "0000:8a:0a.0",
"dpdk_dev_cp": "0000:8a:0a.1",
"bbdev_mode": "none",
"system_core": 0,
"core": 1,
"pkt_proc_core": 2,
"timing_core": 1,
"pkt_aux_core": 1,
"txq_id": 0,
"rxq_id": 0,
"dpdkBasebandFecMode": 0,
"dpdkBasebandDevice": "",
"mtu": 8870,
"o_du_macaddr": "00:11:22:33:44:66",
"o_ru_macaddr": "98:ae:71:01:64:D8",
"cp_vlan_tag": 1,
"up_vlan_tag": 2
},
"eAxCId_cfg": {
"bit_cuPortId": 12,
"bit_bandSectorId": 8,
"bit_ccId": 4,
"bit_ruPortId": 0
},
"prach_cfg": {
"scs": 1,
"freq_start": 0,
"filter_id": 3,
"config_id": 159,
"freq_offset": 0
},
"ru_cfg": {
"category": "A",
"duplex": "TDD",
"slot_config": "slotcfg_0",
"sub6": true,
"mu": 1,
"num_cc": 1,
"num_eaxc": 2,
"ant_elm_trx": 2,
"chbw_dl": 100,
"chbw_ul": 100,
"iq_width": 16,
"comp_meth": 0,
"fft_size": 4096,
"totalBfWeights": 32,
"Tadv_cp_dl": 125,
"T2a_min_cp_dl": 285,
"T2a_max_cp_dl": 429,
"T2a_min_cp_ul": 285,
"T2a_max_cp_ul": 429,
"T2a_min_up": 125,
"T2a_max_up": 428,
"Ta3_min": 130,
"Ta3_max": 170,
"T1a_min_cp_dl": 285,
"T1a_max_cp_dl": 470,
"T1a_min_cp_ul": 285,
"T1a_max_cp_ul": 429,
"T1a_min_up": 125,
"T1a_max_up": 350,
"Ta4_min": 110,
"Ta4_max": 180
},
"slotcfg_0": {
"desc": "DDDSU_6D4G4U",
"period": 5,
"slot0": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
"slot1": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
"slot2": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
"slot3": [ 0, 0, 0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1 ],
"slot4": [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
},
"slotcfg_1": {
"desc": "DDDS_1211",
"period": 4,
"slot0": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
"slot1": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
"slot2": [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
"slot3": [ 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
}
},
"u_plane_functional": [
{
"name": "U_plane",
"parameters": {
"test_type": 0,
"input": "test_vectors/u-plane_in.bin",
"input_len": 2400,
"num_of_cases": 1
},
"references": {
"output": "test_vectors/u-palne_out.bin",
"output_len": 2400
}
}
],
"C_Plane": [
{
"name": "DL_StockA",
"parameters": {
"direction": "DL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 0,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 273,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0,
"exts": [ ]
}
]
}
},
{
"name": "DL_StockB",
"parameters": {
"direction": "DL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 0,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 7,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 2,
"rb": 0,
"symInc": 0,
"startPrbc": 7,
"numPrbc": 255,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
}
]
}
},
{
"name": "DL_StockC",
"parameters": {
"direction": "DL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 0,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 4,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 2,
"rb": 0,
"symInc": 0,
"startPrbc": 8,
"numPrbc": 255,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
}
]
}
},
{
"name": "DL_StockD",
"parameters": {
"direction": "DL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 6,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 1,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 2,
"rb": 0,
"symInc": 0,
"startPrbc": 1,
"numPrbc": 4,
"reMask": 2730,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 3,
"rb": 1,
"symInc": 0,
"startPrbc": 5,
"numPrbc": 10,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 4,
"rb": 1,
"symInc": 0,
"startPrbc": 6,
"numPrbc": 9,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 5,
"rb": 0,
"symInc": 0,
"startPrbc": 24,
"numPrbc": 46,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 6,
"rb": 0,
"symInc": 0,
"startPrbc": 66,
"numPrbc": 207,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
}
]
}
},
{
"name": "DL_StockE",
"parameters": {
"direction": "DL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 5,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 7,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 2,
"rb": 0,
"symInc": 0,
"startPrbc": 7,
"numPrbc": 255,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 3,
"rb": 0,
"symInc": 1,
"startPrbc": 0,
"numPrbc": 7,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 4,
"rb": 0,
"symInc": 0,
"startPrbc": 7,
"numPrbc": 255,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
}
]
}
},
{
"name": "DL_StockF",
"parameters": {
"direction": "DL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 5,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 20,
"reMask": 2730,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 2,
"rb": 0,
"symInc": 0,
"startPrbc": 25,
"numPrbc": 15,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 3,
"rb": 0,
"symInc": 1,
"startPrbc": 40,
"numPrbc": 95,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 4,
"rb": 0,
"symInc": 0,
"startPrbc": 162,
"numPrbc": 111,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 5,
"rb": 0,
"symInc": 1,
"startPrbc": 0,
"numPrbc": 5,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 6,
"rb": 0,
"symInc": 0,
"startPrbc": 25,
"numPrbc": 15,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 7,
"rb": 0,
"symInc": 1,
"startPrbc": 40,
"numPrbc": 95,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 8,
"rb": 0,
"symInc": 0,
"startPrbc": 162,
"numPrbc": 111,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 9,
"rb": 0,
"symInc": 1,
"startPrbc": 0,
"numPrbc": 5,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 10,
"rb": 0,
"symInc": 0,
"startPrbc": 10,
"numPrbc": 30,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 11,
"rb": 0,
"symInc": 1,
"startPrbc": 40,
"numPrbc": 95,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
},
{
"sectionId": 12,
"rb": 0,
"symInc": 0,
"startPrbc": 162,
"numPrbc": 111,
"reMask": 4095,
"numSymbol": 1,
"beamId": 0
}
]
}
},
{
"name": "DL_SectionType1_SingleSection",
"parameters": {
"direction": "DL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 0,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 66,
"reMask": 4095,
"numSymbol": 14,
"beamId": 0
}
]
}
},
{
"name": "UL_SectionType1_SingleSection",
"parameters": {
"direction": "UL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 0,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 66,
"reMask": 4095,
"numSymbol": 14,
"beamId": 0
}
]
}
},
{
"name": "DL_SectionType1_MultiSection",
"parameters": {
"direction": "DL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 0,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 22,
"reMask": 4095,
"numSymbol": 14,
"beamId": 0
},
{
"sectionId": 2,
"rb": 0,
"symInc": 0,
"startPrbc": 22,
"numPrbc": 22,
"reMask": 4095,
"numSymbol": 14,
"beamId": 0
},
{
"sectionId": 3,
"rb": 0,
"symInc": 0,
"startPrbc": 44,
"numPrbc": 22,
"reMask": 4095,
"numSymbol": 14,
"beamId": 0
}
]
}
},
{
"name": "UL_SectionType1_MultiSection",
"parameters": {
"direction": "UL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 0,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 25,
"reMask": 4095,
"numSymbol": 14,
"beamId": 0
},
{
"sectionId": 2,
"rb": 0,
"symInc": 0,
"startPrbc": 25,
"numPrbc": 25,
"reMask": 4095,
"numSymbol": 14,
"beamId": 0
},
{
"sectionId": 3,
"rb": 0,
"symInc": 0,
"startPrbc": 50,
"numPrbc": 25,
"reMask": 4095,
"numSymbol": 14,
"beamId": 0
},
{
"sectionId": 4,
"rb": 0,
"symInc": 0,
"startPrbc": 75,
"numPrbc": 25,
"reMask": 4095,
"numSymbol": 14,
"beamId": 0
}
]
}
},
{
"name": "DL_SectionType1_SingleSection_Ext3",
"parameters": {
"direction": "DL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 0,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 273,
"reMask": 4095,
"numSymbol": 14,
"beamId": 0,
"exts": [ 0 ]
}
],
"extensions": [
{
"name": "ext3",
"type": 3,
"codebookIdx": 165,
"layerId": 2,
"numLayers": 2,
"txScheme": 1,
"crsReMask": 10,
"crsShift": 0,
"crsSymNum": 5,
"numAntPort": 4,
"beamIdAP1": 100,
"beamIdAP2": 200,
"beamIdAP3": 300
}
]
}
},
{
"name": "DL_SectionType1_SingleSection_ExtAll",
"parameters": {
"direction": "DL",
"section_type": 1,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 0,
"comp_method": 0,
"iq_width": 16,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 273,
"reMask": 4095,
"numSymbol": 14,
"beamId": 0,
"exts": [ 0, 1, 2, 3 ]
}
],
"extensions": [
{
"name": "ext2",
"type": 2,
"bfAzPtWidth": 7,
"bfAzPt": 10,
"bfZePtWidth": 7,
"bfZePt": 20,
"bfAz3ddWidth": 7,
"bfAz3dd": 30,
"bfZe3ddWidth": 7,
"bfZe3dd": 40,
"bfAzSI": 2,
"bfZeSI": 5
},
{
"name": "ext3",
"type": 3,
"codebookIdx": 165,
"layerId": 2,
"numLayers": 2,
"txScheme": 1,
"crsReMask": 10,
"crsShift": 0,
"crsSymNum": 5,
"numAntPort": 4,
"beamIdAP1": 100,
"beamIdAP2": 200,
"beamIdAP3": 300
},
{
"name": "ext4",
"type": 4,
"csf": 1,
"modCompScaler":1365
},
{
"name": "ext5",
"type": 5,
"num_sets": 2,
"csf": [ 1, 0 ],
"mcScaleReMask":[ 15, 7 ],
"mcScaleOffset":[ 100, 200 ]
}
]
}
},
{
"name":"UL_SectionType3_SingleSection",
"parameters": {
"direction": "UL",
"section_type": 3,
"cc_id": 0,
"ant_id": 0,
"seq_id": 0,
"frame_id": 0,
"subframe_id": 0,
"slot_id": 0,
"symbol_start": 7,
"comp_method": 0,
"iq_width": 16,
"filter_index": 3,
"time_offset": 2026,
"fft_size": 10,
"scs": 3,
"cp_length": 0,
"sections": [
{
"sectionId": 1,
"rb": 0,
"symInc": 0,
"startPrbc": 0,
"numPrbc": 12,
"reMask": 4095,
"numSymbol": 6,
"beamId": 0,
"freqOffset": -792
}
]
}
}
],
"TestChain": [
{
"name": "FDD_CATA_MU0_20_1CC_4ANT",
"parameters": {
"category": "A",
"sub6": true,
"mu": 0,
"duplex": "FDD",
"slot_config": "slotcfg_0",
"chbw_dl": 20,
"fftsize_dl": 1024,
"chbw_ul": 20,
"fftsize_ul": 1024,
"num_cc": 1,
"num_eaxc": 4,
"antelm_trx": 32,
"iq_width": 16,
"comp_meth": 0,
"totalBfWeights": 64,
"num_slots": 10,
"bfw_prefix_dl": "test_vectors/mu1_100_32/dl_bfw_ue_",
"bfw_prefix_ul": "test_vectors/mu1_100_32/ul_bfw_ue_"
}
},
{
"name": "FDD_CATA_MU0_20_1CC_8ANT",
"parameters": {
"category": "A",
"sub6": true,
"mu": 0,
"duplex": "FDD",
"slot_config": "slotcfg_0",
"chbw_dl": 20,
"fftsize_dl": 1024,
"chbw_ul": 20,
"fftsize_ul": 1024,
"num_cc": 1,
"num_eaxc": 8,
"antelm_trx": 32,
"iq_width": 16,
"comp_meth": 0,
"totalBfWeights": 64,
"num_slots": 10,
"bfw_prefix_dl": "test_vectors/mu1_100_32/dl_bfw_ue_",
"bfw_prefix_ul": "test_vectors/mu1_100_32/ul_bfw_ue_"
}
},
{
"name": "FDD_CATA_MU0_20_6CC_4ANT",
"parameters": {
"category": "A",
"sub6": true,
"mu": 0,
"duplex": "FDD",
"slot_config": "slotcfg_0",
"chbw_dl": 20,
"fftsize_dl": 1024,
"chbw_ul": 20,
"fftsize_ul": 1024,
"num_cc": 6,
"num_eaxc": 4,
"antelm_trx": 32,
"iq_width": 16,
"comp_meth": 0,
"totalBfWeights": 64,
"num_slots": 10,
"bfw_prefix_dl": "test_vectors/mu1_100_32/dl_bfw_ue_",
"bfw_prefix_ul": "test_vectors/mu1_100_32/ul_bfw_ue_"
}
},
{
"name": "FDD_CATA_MU0_20_6CC_8ANT",
"parameters": {
"category": "A",
"sub6": true,
"mu": 0,
"duplex": "FDD",
"slot_config": "slotcfg_0",
"chbw_dl": 20,
"fftsize_dl": 1024,
"chbw_ul": 20,
"fftsize_ul": 1024,
"num_cc": 6,
"num_eaxc": 8,
"antelm_trx": 32,
"iq_width": 16,
"comp_meth": 0,
"totalBfWeights": 64,
"num_slots": 10,
"bfw_prefix_dl": "test_vectors/mu1_100_32/dl_bfw_ue_",
"bfw_prefix_ul": "test_vectors/mu1_100_32/ul_bfw_ue_"
}
},
{
"name": "TDD_CATA_MU1_100_1CC_4",
"parameters": {
"category": "A",
"sub6": true,
"mu": 1,
"duplex": "TDD",
"slot_config": "slotcfg_0",
"chbw_dl": 100,
"fftsize_dl": 4096,
"chbw_ul": 100,
"fftsize_ul": 4096,
"num_cc": 1,
"num_eaxc": 4,
"antelm_trx": 32,
"iq_width": 16,
"comp_meth": 0,
"totalBfWeights": 64,
"num_slots": 10,
"bfw_prefix_dl": "test_vectors/mu1_100_32/dl_bfw_ue_",
"bfw_prefix_ul": "test_vectors/mu1_100_32/ul_bfw_ue_"
}
},
{
"name": "TDD_CATA_MU1_100_1CC_8",
"parameters": {
"category": "A",
"sub6": true,
"mu": 1,
"duplex": "TDD",
"slot_config": "slotcfg_0",
"chbw_dl": 100,
"fftsize_dl": 4096,
"chbw_ul": 100,
"fftsize_ul": 4096,
"num_cc": 1,
"num_eaxc": 8,
"antelm_trx": 32,
"iq_width": 16,
"comp_meth": 0,
"totalBfWeights": 64,
"num_slots": 10,
"bfw_prefix_dl": "test_vectors/mu1_100_32/dl_bfw_ue_",
"bfw_prefix_ul": "test_vectors/mu1_100_32/ul_bfw_ue_"
}
},
{
"name": "TDD_CATA_MU3_100_1CC_4",
"parameters": {
"category": "A",
"sub6": false,
"mu": 3,
"duplex": "TDD",
"slot_config": "slotcfg_1",
"chbw_dl": 100,
"fftsize_dl": 1024,
"chbw_ul": 100,
"fftsize_ul": 1024,
"num_cc": 1,
"num_eaxc": 4,
"antelm_trx": 32,
"iq_width": 16,
"comp_meth": 0,
"totalBfWeights": 64,
"num_slots": 10,
"bfw_prefix_dl": "test_vectors/mu1_100_32/dl_bfw_ue_",
"bfw_prefix_ul": "test_vectors/mu1_100_32/ul_bfw_ue_"
}
},
{
"name": "TDD_CATB_MU1_100_1CC_8",
"parameters": {
"category": "B",
"sub6": true,
"mu": 1,
"duplex": "TDD",
"slot_config": "slotcfg_0",
"chbw_dl": 100,
"fftsize_dl": 4096,
"chbw_ul": 100,
"fftsize_ul": 4096,
"num_cc": 1,
"num_eaxc": 8,
"antelm_trx": 32,
"iq_width": 16,
"comp_meth": 0,
"totalBfWeights": 64,
"num_slots": 10,
"bfw_prefix_dl": "test_vectors/mu1_100_32/dl_bfw_ue_",
"bfw_prefix_ul": "test_vectors/mu1_100_32/ul_bfw_ue_"
}
}
],
"init_sys_functional": [
{
"name": "xran_lib_api",
"parameters": {
"id": 0,
"dpdk_dev": [ "0000:d8:02.0", "0000:d8:02.1" ],
"bbdev_dev": "none",
"bbdev_mode": 0,
"core": 5,
"system_core": 0,
"pkt_proc_core": 6,
"pkt_aux_core": 0,
"timing_core": 7,
"port": [ 0, 1 ],
"dpdkBasebandFecMode": 0,
"dpdkBasebandDevice": "none",
"filePrefix": "wls",
"xranCat": 0,
"mtu": 9600,
"p_o_du_addr": "00:11:22:33:44:66",
"p_o_ru_addr": "00:11:22:33:44:55",
"Tadv_cp_dl": 0,
"T2a_min_cp_dl": 0,
"T2a_max_cp_dl": 0,
"T2a_min_cp_ul": 0,
"T2a_max_cp_ul": 0,
"T2a_min_up": 0,
"T2a_max_up": 0,
"Ta3_min": 0,
"Ta3_max": 0,
"T1a_min_cp_dl": 0,
"T1a_max_cp_dl": 0,
"T1a_min_cp_ul": 0,
"T1a_max_cp_ul": 0,
"T1a_min_up": 0,
"T1a_max_up": 0,
"Ta4_min": 0,
"Ta4_max": 0,
"enableCP": 1,
"prachEnable": 1,
"cp_vlan_tag": 2,
"up_vlan_tag": 1,
"debugStop": 0,
"debugStopCount": 0,
"DynamicSectionEna": 0
}
}
],
"prach_functional": [
{
"name": "Prach_test",
"parameters": {
"Numerology": 1,
"FrameDuplexType": 0,
"loglevel": 1,
"PrachConfIdx": 189,
"PrachFreqStart": 0,
"PrachFreqOffset": 0,
"PrachSubcSpacing": 1,
"frameId": 0,
"subframeId": 1,
"slotId": 0,
"beamId": 0,
"ccId": 0,
"antId": 0,
"iqWidth": 16,
"compMeth": 0,
"fftSize": 10
},
"references": {
"filterIdx": 3,
"startSymId": 0,
"startPrbc": 0,
"numPrbc": 12,
"timeOffset": 216,
"freqOffset": 0,
"x_value": 1,
"nrofPrachInSlot": 1,
"y_value": [ 0, 0 ],
"numSymbol": 2,
"occassionsInPrachSlot": 7,
"isPRACHslot": [ 1, 6 ],
"SlotNrNum": 2,
"prach_start_symbol": 0,
"prach_last_symbol": 13,
"m_params_timeOffset": 108,
"id": 0
}
}
],
"prach_performance": [
{
"name": "Prach_test",
"parameters": {
"Numerology": 1,
"FrameDuplexType": 0,
"loglevel": 1,
"PrachConfIdx": 189,
"PrachFreqStart": 0,
"PrachFreqOffset": 0,
"PrachSubcSpacing": 1,
"frameId": 0,
"subframeId": 1,
"slotId": 0,
"beamId": 0,
"ccId": 0,
"antId": 0
},
"references": {
"filterIdx": 3,
"startSymId": 0,
"startPrbc": 0,
"numPrbc": 12,
"timeOffset": 216,
"freqOffset": 0,
"x_value": 1,
"nrofPrachInSlot": 1,
"y_value": [ 0, 0 ],
"numSymbol": 2,
"occassionsInPrachSlot": 7,
"isPRACHslot": [ 1, 6 ],
"SlotNrNum": 2,
"prach_start_symbol": 0,
"prach_last_symbol": 13
}
}
],
"u_plane_perormace": [
{
"name": "U-plane",
"parameters": {
"test_type": 0,
"input": "test_vectors/u-plane_in.bin",
"input_len": 2400,
"num_of_cases": 1
},
"references": {
"output": "test_vectors/u-palne_out.bin",
"output_len": 2400
}
}
],
"bfp_functional": [
{
"name": "COMPRESS_DECOMPRESS",
"parameters": {
}
}
],
"bfp_performace": [
{
"name": "COMPRESS_DECOMPRESS",
"parameters": {
}
}
],
"bfp_performace_cp": [
{
"name": "AntElm_8_IQ_8",
"parameters": {
"AntElm": 8,
"iqWidth": 8
}
},
{
"name": "AntElm_16_IQ_8",
"parameters": {
"AntElm": 16,
"iqWidth": 8
}
},
{
"name": "AntElm_32_IQ_8",
"parameters": {
"AntElm": 32,
"iqWidth": 8
}
},
{
"name": "AntElm_64_IQ_8",
"parameters": {
"AntElm": 64,
"iqWidth": 8
}
},
{
"name": "AntElm_8_IQ_9",
"parameters": {
"AntElm": 8,
"iqWidth": 9
}
},
{
"name": "AntElm_16_IQ_9",
"parameters": {
"AntElm": 16,
"iqWidth": 9
}
},
{
"name": "AntElm_32_IQ_9",
"parameters": {
"AntElm": 32,
"iqWidth": 9
}
},
{
"name": "AntElm_64_IQ_9",
"parameters": {
"AntElm": 64,
"iqWidth": 9
}
},
{
"name": "AntElm_8_IQ_10",
"parameters": {
"AntElm": 8,
"iqWidth": 10
}
},
{
"name": "AntElm_16_IQ_10",
"parameters": {
"AntElm": 16,
"iqWidth": 10
}
},
{
"name": "AntElm_32_IQ_10",
"parameters": {
"AntElm": 32,
"iqWidth": 10
}
},
{
"name": "AntElm_64_IQ_10",
"parameters": {
"AntElm": 64,
"iqWidth": 10
}
},
{
"name": "AntElm_8_IQ_12",
"parameters": {
"AntElm": 8,
"iqWidth": 12
}
},
{
"name": "AntElm_16_IQ_12",
"parameters": {
"AntElm": 16,
"iqWidth": 12
}
},
{
"name": "AntElm_32_IQ_12",
"parameters": {
"AntElm": 32,
"iqWidth": 12
}
},
{
"name": "AntElm_64_IQ_12",
"parameters": {
"AntElm": 64,
"iqWidth": 12
}
}
],
"bfp_performace_ex": [
{
"name": "RB_16_IQ_8",
"parameters": {
"nRBsize": 16,
"iqWidth": 8
}
},
{
"name": "RB_18_IQ_8",
"parameters": {
"nRBsize": 18,
"iqWidth": 8
}
},
{
"name": "RB_32_IQ_8",
"parameters": {
"nRBsize": 32,
"iqWidth": 8
}
},
{
"name": "RB_36_IQ_8",
"parameters": {
"nRBsize": 36,
"iqWidth": 8
}
},
{
"name": "RB_48_IQ_8",
"parameters": {
"nRBsize": 48,
"iqWidth": 8
}
},
{
"name": "RB_70_IQ_8",
"parameters": {
"nRBsize": 70,
"iqWidth": 8
}
},
{
"name": "RB_113_IQ_8",
"parameters": {
"nRBsize": 113,
"iqWidth": 8
}
},
{
"name": "RB_273_IQ_8",
"parameters": {
"nRBsize": 273,
"iqWidth": 8
}
},
{
"name": "RB_6_IQ_9",
"parameters": {
"nRBsize": 6,
"iqWidth": 9
}
},
{
"name": "RB_12_IQ_9",
"parameters": {
"nRBsize": 12,
"iqWidth": 9
}
},
{
"name": "RB_16_IQ_9",
"parameters": {
"nRBsize": 16,
"iqWidth": 9
}
},
{
"name": "RB_18_IQ_9",
"parameters": {
"nRBsize": 18,
"iqWidth": 9
}
},
{
"name": "RB_24_IQ_9",
"parameters": {
"nRBsize": 24,
"iqWidth": 9
}
},
{
"name": "RB_30_IQ_9",
"parameters": {
"nRBsize": 30,
"iqWidth": 9
}
},
{
"name": "RB_32_IQ_9",
"parameters": {
"nRBsize": 32,
"iqWidth": 9
}
},
{
"name": "RB_36_IQ_9",
"parameters": {
"nRBsize": 36,
"iqWidth": 9
}
},
{
"name": "RB_42_IQ_9",
"parameters": {
"nRBsize": 42,
"iqWidth": 9
}
},
{
"name": "RB_48_IQ_9",
"parameters": {
"nRBsize": 48,
"iqWidth": 9
}
},
{
"name": "RB_54_IQ_9",
"parameters": {
"nRBsize": 54,
"iqWidth": 9
}
},
{
"name": "RB_60_IQ_9",
"parameters": {
"nRBsize": 60,
"iqWidth": 9
}
},
{
"name": "RB_66_IQ_9",
"parameters": {
"nRBsize": 66,
"iqWidth": 9
}
},
{
"name": "RB_70_IQ_9",
"parameters": {
"nRBsize": 70,
"iqWidth": 9
}
},
{
"name": "RB_72_IQ_9",
"parameters": {
"nRBsize": 72,
"iqWidth": 9
}
},
{
"name": "RB_78_IQ_9",
"parameters": {
"nRBsize": 78,
"iqWidth": 9
}
},
{
"name": "RB_84_IQ_9",
"parameters": {
"nRBsize": 84,
"iqWidth": 9
}
},
{
"name": "RB_90_IQ_9",
"parameters": {
"nRBsize": 90,
"iqWidth": 9
}
},
{
"name": "RB_96_IQ_9",
"parameters": {
"nRBsize": 96,
"iqWidth": 9
}
},
{
"name": "RB_102_IQ_9",
"parameters": {
"nRBsize": 102,
"iqWidth": 9
}
},
{
"name": "RB_108_IQ_9",
"parameters": {
"nRBsize": 108,
"iqWidth": 9
}
},
{
"name": "RB_113_IQ_9",
"parameters": {
"nRBsize": 113,
"iqWidth": 9
}
},
{
"name": "RB_114_IQ_9",
"parameters": {
"nRBsize": 114,
"iqWidth": 9
}
},
{
"name": "RB_120_IQ_9",
"parameters": {
"nRBsize": 120,
"iqWidth": 9
}
},
{
"name": "RB_126_IQ_9",
"parameters": {
"nRBsize": 126,
"iqWidth": 9
}
},
{
"name": "RB_132_IQ_9",
"parameters": {
"nRBsize": 132,
"iqWidth": 9
}
},
{
"name": "RB_138_IQ_9",
"parameters": {
"nRBsize": 138,
"iqWidth": 9
}
},
{
"name": "RB_144_IQ_9",
"parameters": {
"nRBsize": 144,
"iqWidth": 9
}
},
{
"name": "RB_150_IQ_9",
"parameters": {
"nRBsize": 150,
"iqWidth": 9
}
},
{
"name": "RB_156_IQ_9",
"parameters": {
"nRBsize": 156,
"iqWidth": 9
}
},
{
"name": "RB_162_IQ_9",
"parameters": {
"nRBsize": 162,
"iqWidth": 9
}
},
{
"name": "RB_168_IQ_9",
"parameters": {
"nRBsize": 168,
"iqWidth": 9
}
},
{
"name": "RB_174_IQ_9",
"parameters": {
"nRBsize": 174,
"iqWidth": 9
}
},
{
"name": "RB_180_IQ_9",
"parameters": {
"nRBsize": 180,
"iqWidth": 9
}
},
{
"name": "RB_186_IQ_9",
"parameters": {
"nRBsize": 186,
"iqWidth": 9
}
},
{
"name": "RB_192_IQ_9",
"parameters": {
"nRBsize": 192,
"iqWidth": 9
}
},
{
"name": "RB_198_IQ_9",
"parameters": {
"nRBsize": 198,
"iqWidth": 9
}
},
{
"name": "RB_204_IQ_9",
"parameters": {
"nRBsize": 204,
"iqWidth": 9
}
},
{
"name": "RB_210_IQ_9",
"parameters": {
"nRBsize": 210,
"iqWidth": 9
}
},
{
"name": "RB_216_IQ_9",
"parameters": {
"nRBsize": 216,
"iqWidth": 9
}
},
{
"name": "RB_222_IQ_9",
"parameters": {
"nRBsize": 222,
"iqWidth": 9
}
},
{
"name": "RB_228_IQ_9",
"parameters": {
"nRBsize": 228,
"iqWidth": 9
}
},
{
"name": "RB_234_IQ_9",
"parameters": {
"nRBsize": 234,
"iqWidth": 9
}
},
{
"name": "RB_240_IQ_9",
"parameters": {
"nRBsize": 240,
"iqWidth": 9
}
},
{
"name": "RB_246_IQ_9",
"parameters": {
"nRBsize": 246,
"iqWidth": 9
}
},
{
"name": "RB_252_IQ_9",
"parameters": {
"nRBsize": 252,
"iqWidth": 9
}
},
{
"name": "RB_258_IQ_9",
"parameters": {
"nRBsize": 258,
"iqWidth": 9
}
},
{
"name": "RB_264_IQ_9",
"parameters": {
"nRBsize": 264,
"iqWidth": 9
}
},
{
"name": "RB_270_IQ_9",
"parameters": {
"nRBsize": 270,
"iqWidth": 9
}
},
{
"name": "RB_273_IQ_9",
"parameters": {
"nRBsize": 273,
"iqWidth": 9
}
},
{
"name": "RB_16_IQ_10",
"parameters": {
"nRBsize": 16,
"iqWidth": 10
}
},
{
"name": "RB_18_IQ_10",
"parameters": {
"nRBsize": 18,
"iqWidth": 10
}
},
{
"name": "RB_32_IQ_10",
"parameters": {
"nRBsize": 32,
"iqWidth": 10
}
},
{
"name": "RB_36_IQ_10",
"parameters": {
"nRBsize": 36,
"iqWidth": 10
}
},
{
"name": "RB_48_IQ_10",
"parameters": {
"nRBsize": 48,
"iqWidth": 10
}
},
{
"name": "RB_70_IQ_10",
"parameters": {
"nRBsize": 70,
"iqWidth": 10
}
},
{
"name": "RB_113_IQ_10",
"parameters": {
"nRBsize": 113,
"iqWidth": 10
}
},
{
"name": "RB_273_IQ_10",
"parameters": {
"nRBsize": 273,
"iqWidth": 10
}
},
{
"name": "RB_16_IQ_12",
"parameters": {
"nRBsize": 16,
"iqWidth": 12
}
},
{
"name": "RB_18_IQ_12",
"parameters": {
"nRBsize": 18,
"iqWidth": 12
}
},
{
"name": "RB_32_IQ_12",
"parameters": {
"nRBsize": 32,
"iqWidth": 12
}
},
{
"name": "RB_36_IQ_12",
"parameters": {
"nRBsize": 36,
"iqWidth": 12
}
},
{
"name": "RB_48_IQ_12",
"parameters": {
"nRBsize": 48,
"iqWidth": 12
}
},
{
"name": "RB_70_IQ_12",
"parameters": {
"nRBsize": 70,
"iqWidth": 12
}
},
{
"name": "RB_113_IQ_12",
"parameters": {
"nRBsize": 113,
"iqWidth": 12
}
},
{
"name": "RB_273_IQ_12",
"parameters": {
"nRBsize": 273,
"iqWidth": 12
}
},
{
"name": "RB_16_IQ_14",
"parameters": {
"nRBsize": 16,
"iqWidth": 14
}
},
{
"name": "RB_18_IQ_14",
"parameters": {
"nRBsize": 18,
"iqWidth": 14
}
},
{
"name": "RB_32_IQ_14",
"parameters": {
"nRBsize": 32,
"iqWidth": 14
}
},
{
"name": "RB_36_IQ_14",
"parameters": {
"nRBsize": 36,
"iqWidth": 14
}
},
{
"name": "RB_48_IQ_14",
"parameters": {
"nRBsize": 48,
"iqWidth": 14
}
},
{
"name": "RB_70_IQ_14",
"parameters": {
"nRBsize": 70,
"iqWidth": 14
}
},
{
"name": "RB_113_IQ_14",
"parameters": {
"nRBsize": 113,
"iqWidth": 14
}
},
{
"name": "RB_273_IQ_14",
"parameters": {
"nRBsize": 273,
"iqWidth": 14
}
}
]
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment