Compare commits

...

3 Commits

Author SHA1 Message Date
Bartosz Podrygajlo
dad3cd7942 CI test for fd_rfsim 2025-11-05 16:28:35 +01:00
Bartosz Podrygajlo
a4cdfed421 FD RFSimulator adaptation layer
A new radio library for use with the gNB. It performs the same tasks as an O-RU
and is meant for testing O-DU functionalities. It acts as an RFSim server with
a frequency domain interface.
2025-11-05 08:13:16 +01:00
Bartosz Podrygajlo
e943867da2 Add a function which loads the specified radio library 2025-11-05 08:07:41 +01:00
14 changed files with 1436 additions and 4 deletions

View File

@@ -0,0 +1,144 @@
<!--
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
-->
<testCaseList>
<htmlTabRef>rfsim-fd-5gnr</htmlTabRef>
<htmlTabName>Monolithic SA TDD gNB + FD RFSIM</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
111111
800813
000001
000002
000003
020001
020002
030001
030002
100001
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<images>oai-gnb-asan oai-nr-ue-asan</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G CoreNetwork</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_fd</yaml_path>
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000002">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G gNB+UE RF sim SA</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_fd</yaml_path>
<services>oai-gnb oai-nr-ue</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000003">
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_ue</id>
<nodes>cacofonix</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_ue</id>
<nodes>cacofonix</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020002">
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>cacofonix</nodes>
<svr_id>rfsim5g_ue</svr_id>
<svr_node>cacofonix</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="030001">
<class>Iperf</class>
<desc>Iperf (DL/10Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 10M -t 20 -R</iperf_args>
<id>rfsim5g_ue</id>
<nodes>cacofonix</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>cacofonix</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="030002">
<class>Iperf</class>
<desc>Iperf (UL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 20</iperf_args>
<id>rfsim5g_ue</id>
<nodes>cacofonix</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>cacofonix</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="100001">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_fd</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<d_retx_th>1,0,0,0</d_retx_th>
<u_retx_th>1,0,0,0</u_retx_th>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<images>oai-gnb-asan oai-nr-ue-asan</images>
</testCase>
</testCaseList>

View File

@@ -0,0 +1,161 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
environment:
- TZ=Europe/Paris
- MYSQL_DATABASE=oai_db
- MYSQL_USER=test
- MYSQL_PASSWORD=test
- MYSQL_ROOT_PASSWORD=linux
healthcheck:
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
interval: 10s
timeout: 5s
start_period: 10s
start_interval: 500ms
retries: 30
networks:
public_net:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-amf/etc/config.yaml
depends_on:
- mysql
networks:
public_net:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-smf/etc/config.yaml
depends_on:
- oai-amf
networks:
public_net:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-upf/etc/config.yaml
depends_on:
- oai-smf
cap_add:
- NET_ADMIN
- SYS_ADMIN
cap_drop:
- ALL
privileged: true
networks:
public_net:
ipv4_address: 192.168.71.134
interface_name: eth0
traffic_net:
ipv4_address: 192.168.72.134
interface_name: eth1
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:focal
init: true
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
depends_on:
- oai-upf
networks:
traffic_net:
ipv4_address: 192.168.72.135
healthcheck:
test: /bin/bash -c "ping -c 2 192.168.72.134"
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
start_interval: 500ms
oai-gnb:
image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop}
container_name: rfsim5g-oai-gnb
cap_drop:
- ALL
cap_add:
- SYS_NICE
environment:
USE_ADDITIONAL_OPTIONS: --log_config.global_log_options level,nocolor,time --rfsimulator.serveraddr server --gNBs.[0].min_rxtxtime 6
ASAN_OPTIONS: detect_leaks=0
depends_on:
- oai-ext-dn
networks:
public_net:
ipv4_address: 192.168.71.140
volumes:
- ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.106prb.fhi72.2x2-fd-rfsim.conf:/opt/oai-gnb/etc/gnb.conf
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
start_period: 10s
start_interval: 500ms
interval: 10s
timeout: 5s
retries: 5
oai-nr-ue:
image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop}
container_name: rfsim5g-oai-nr-ue
cap_drop:
- ALL
cap_add:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
- SYS_NICE
environment:
USE_ADDITIONAL_OPTIONS: -C 4049760000 -r 106 --numerology 1 --ssb 516 --band 77 --rfsim --uicc0.imsi 208990100001100 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
depends_on:
- oai-gnb
networks:
public_net:
ipv4_address: 192.168.71.150
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
start_period: 10s
start_interval: 500ms
interval: 10s
timeout: 5s
retries: 5
networks:
public_net:
driver: bridge
name: rfsim5g-oai-public-net
ipam:
config:
- subnet: 192.168.71.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-public"
traffic_net:
driver: bridge
name: rfsim5g-oai-traffic-net
ipam:
config:
- subnet: 192.168.72.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-traffic"

View File

@@ -41,7 +41,7 @@ BUILD_DIR=ran_build
DISABLE_HARDWARE_DEPENDENCY="False"
CMAKE_BUILD_TYPE="RelWithDebInfo"
CMAKE_CMD="$CMAKE"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_cuda ldpc_aal ldpc_xdma websrv oai_iqplayer imscope imscope_record"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_cuda ldpc_aal ldpc_xdma websrv oai_iqplayer imscope imscope_record fd_rfsim"
TARGET_LIST=""
BUILD_TOOL_OPT="-j$(nproc)"

View File

@@ -46,7 +46,7 @@ RUN \
mkdir -p log && \
./build_oai -c --ninja \
--eNB --gNB --RU --UE --nrUE \
--build-lib "telnetsrv enbscope uescope nrscope" \
--build-lib "telnetsrv enbscope uescope nrscope fd_rfsim" \
-w USRP -t Ethernet \
--build-e2 --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \
--noavx512 \

View File

@@ -95,6 +95,8 @@ COPY --from=gnb-build \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_rrc.so \
/oai-ran/cmake_targets/ran_build/build/libtelnetsrv_o1.so \
/oai-ran/cmake_targets/ran_build/build/libvrtsim.so \
/oai-ran/cmake_targets/ran_build/build/libfd_rfsim.so \
/oai-ran/cmake_targets/ran_build/build/liboai_transpro.so \
/usr/local/lib/
# Now we are copying from builder-image the UHD files.

View File

@@ -561,7 +561,7 @@ void fh_if4p5_north_out(RU_t *ru) {
stop_meas(&ru->tx_fhaul);
}
static void rx_rf(RU_t *ru, int *frame, int *slot)
void rx_rf(RU_t *ru, int *frame, int *slot)
{
RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;

View File

@@ -47,3 +47,8 @@ add_boolean_option(OAI_RF_EMULATOR ON "Activate OAI's RF emulator" OFF)
if(OAI_RF_EMULATOR)
add_subdirectory(emulator)
endif()
add_boolean_option(OAI_FD_RFSIM ON "Activate OAI's FD RFsim adapter driver" OFF)
if(OAI_FD_RFSIM)
add_subdirectory(fd_rfsim)
endif()

View File

@@ -175,6 +175,19 @@ int openair0_transport_load(openair0_device *device,
return rc;
}
int openair0_load(openair0_device *device, char *name, openair0_config_t *openair0_cfg, eth_params_t *eth_params)
{
loader_shlibfunc_t shlib_fdesc[1];
int ret = 0;
shlib_fdesc[0].fname = eth_params == NULL ? "device_init" : "transport_init";
ret = load_module_shlib(name, shlib_fdesc, 1, NULL);
AssertFatal((ret >= 0), "Library %s couldn't be loaded\n", name);
return ((devfunc_t)shlib_fdesc[0].fptr)(device, openair0_cfg, eth_params);
}
static void writerEnqueue(re_order_t *ctx, openair0_timestamp timestamp, void **txp, int nsamps, int nbAnt, int flags)
{
pthread_mutex_lock(&ctx->mutex_store);

View File

@@ -659,7 +659,7 @@ const char *get_devname(int devtype);
int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg);
/*! \brief Initialize transport protocol . It returns 0 if OK */
int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
int openair0_load(openair0_device *device, char *name, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
/*! \brief Get current timestamp of USRP
* \param device the hardware to use

View File

@@ -0,0 +1,8 @@
add_library(fd_rfsim MODULE fd_rfsim.c)
target_link_libraries(fd_rfsim PRIVATE atomic UTIL)
set_target_properties(fd_rfsim PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
if(NOT OAI_FHI72)
add_custom_command(TARGET fd_rfsim POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink libfd_rfsim.so liboai_transpro.so
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
endif()

29
radio/fd_rfsim/README.md Normal file
View File

@@ -0,0 +1,29 @@
# FD RFsimulator Adapter
## Overview
This library provides a frequency domain adaptation layer for the OAI RFsimulator,
enabling integration with OAI O-DU configuration files. It facilitates testing and
development of 5G NR O-DU and UE components in a simulated radio environment without
real time requirements.
## Usage
### Build
```
cmake --build . --target fd_rfsim
```
Example config provided in `gnb.sa.band77.106prb.fhi72.4x4-fd-rfsim.conf`
### Run
Run gNB
```
sudo ./nr-softmodem -O ../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.106prb.fhi72.4x4-fd-rfsim.conf --rfsimulator.serveraddr server
```
Run UE
```
sudo ./nr-uesoftmodem -C 4049760000 -r 106 --numerology 1 --ssb 516 --band 77 --rfsim
```

521
radio/fd_rfsim/fd_rfsim.c Normal file
View File

@@ -0,0 +1,521 @@
/*
* 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 "platform_types.h"
#include <stdio.h>
#include <string.h>
#include "common_lib.h"
#include "radio/ETHERNET/ethernet_lib.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "openair1/PHY/defs_gNB.h"
#include "../fhi_72/oran-params.h"
#include <stdatomic.h>
#include "common/utils/threadPool/notified_fifo.h"
#include "PHY/MODULATION/modulation_common.h"
#include "openair1/PHY/TOOLS/phy_scope_interface.h"
#include "openair1/PHY/MODULATION/nr_modulation.h"
#include "PHY/INIT/nr_phy_init.h"
#include "SCHED_NR/sched_nr.h"
#include "common/utils/threadPool/pthread_utils.h"
#include "openair1/PHY/NR_TRANSPORT/nr_transport_proto.h"
typedef struct {
openair0_timestamp timestamp;
int slot;
int frame;
} fd_rfsim_timestamp;
typedef struct {
bool is_started;
rru_config_msg_type_t last_msg;
bool capabilities_sent;
openair0_config_t openair0_cfg;
notifiedFIFO_t sync_fifo;
RU_t ru;
pthread_mutex_t mutex;
} fd_rfsim_state_t;
extern void nr_feptx(void *arg);
static int trx_start(openair0_device *device)
{
printf("Starting fd_rfsim\n");
fd_rfsim_state_t *s = (fd_rfsim_state_t *)device->priv;
if (s->ru.rfdevice.trx_start_func) {
if (s->ru.rfdevice.trx_start_func(&s->ru.rfdevice) < 0) {
LOG_E(HW, "Failed to start subdevice\n");
return -1;
}
}
s->is_started = true;
return 0;
}
static void trx_end(openair0_device *device)
{
fd_rfsim_state_t *s = (fd_rfsim_state_t *)device->priv;
if (s->ru.rfdevice.trx_end_func) {
s->ru.rfdevice.trx_end_func(&s->ru.rfdevice);
}
s->is_started = false;
}
static int trx_stop(openair0_device *device)
{
fd_rfsim_state_t *s = (fd_rfsim_state_t *)device->priv;
if (s->ru.rfdevice.trx_stop_func) {
if (s->ru.rfdevice.trx_stop_func(&s->ru.rfdevice) < 0) {
LOG_E(HW, "Failed to stop subdevice\n");
return -1;
}
}
s->is_started = false;
return 0;
}
static int trx_set_freq(openair0_device *device, openair0_config_t *openair0_cfg)
{
fd_rfsim_state_t *s = (fd_rfsim_state_t *)device->priv;
if (!s->is_started) {
LOG_E(HW, "Device not started, cannot set frequency\n");
return -1;
}
if (s->ru.rfdevice.trx_set_freq_func) {
if (s->ru.rfdevice.trx_set_freq_func(&s->ru.rfdevice, openair0_cfg) < 0) {
LOG_E(HW, "Failed to set frequency on subdevice\n");
return -1;
}
}
return 0;
}
static int trx_set_gains(openair0_device *device, openair0_config_t *openair0_cfg)
{
fd_rfsim_state_t *s = (fd_rfsim_state_t *)device->priv;
if (!s->is_started) {
LOG_E(HW, "Device not started, cannot set gains\n");
return -1;
}
if (s->ru.rfdevice.trx_set_gains_func) {
if (s->ru.rfdevice.trx_set_gains_func(&s->ru.rfdevice, openair0_cfg) < 0) {
LOG_E(HW, "Failed to set gains on subdevice\n");
return -1;
}
}
return 0;
}
static int trx_reset_stats(openair0_device *device)
{
fd_rfsim_state_t *s = (fd_rfsim_state_t *)device->priv;
if (!s->is_started) {
LOG_E(HW, "Device not started, cannot reset stats\n");
return -1;
}
if (s->ru.rfdevice.trx_reset_stats_func) {
return s->ru.rfdevice.trx_reset_stats_func(&s->ru.rfdevice);
}
return 0;
}
int ethernet_tune(openair0_device *device, unsigned int option, int value)
{
return 0;
}
static int trx_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags)
{
return 0;
}
static int trx_read_raw(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc)
{
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];
}
static int trx_ctlsend(openair0_device *device, void *msg, ssize_t msg_len)
{
RRU_CONFIG_msg_t *rru_config_msg = msg;
printf("rru_config_msg->type %d [%s]\n", rru_config_msg->type, msg_type(rru_config_msg->type));
return msg_len;
}
static int trx_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len)
{
RRU_CONFIG_msg_t *rru_config_msg = msg;
fd_rfsim_state_t *s = (fd_rfsim_state_t *)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;
}
extern void rx_rf(RU_t *ru, int *frame, int *slot);
void nr_fep_tp(RU_t *ru, int slot);
static void fh_if4p5_south_in(RU_t *ru, int *frame, int *slot)
{
fd_rfsim_state_t *s = (fd_rfsim_state_t *)ru->ifdevice.priv;
LOG_D(HW, "fd_rfsim: fh_if4p5_south_in: frame %d, slot %d\n", *frame, *slot);
// O-DU expects
// rxDataF here: ru_info.rxdataF = ru->common.rxdataF;
/// PRACH data here: ru_info.prach_buf = ru->prach_rxsigF[0]; // index: [prach_oca][ant_id]
s->ru.common.rxdataF = ru->common.rxdataF;
NR_DL_FRAME_PARMS *fp = s->ru.nr_frame_parms;
start_meas(&s->ru.rx_fhaul);
rx_rf(&s->ru, frame, slot);
int rx_slot_type = nr_slot_select(&s->ru.config, *frame, *slot);
if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {
prach_item_t *prach_id = find_nr_prach(&ru->gNB_list[0]->prach_list, *frame, *slot, SEARCH_EXIST);
if (prach_id) {
rx_nr_prach_ru(prach_id, s->ru.common.rxdata, fp, s->ru.N_TA_offset);
}
nr_fep_tp(&s->ru, *slot);
if (!ru->gNB_list[0]->phase_comp) {
int soffset = (*slot & 3) * fp->symbols_per_slot * fp->ofdm_symbol_size;
for (int aa = 0; aa < fp->nb_antennas_rx; aa++) {
const uint max_symb = fp->Ncp == EXTENDED ? 12 : 14;
for (int sym = 0; sym < max_symb; sym++)
apply_nr_rotation_symbol_RX(fp,
(c16_t *)s->ru.common.rxdataF[aa] + soffset + sym * fp->ofdm_symbol_size,
fp->symbol_rotation[1],
fp->N_RB_UL,
*slot,
sym);
}
}
}
RU_proc_t *proc = &ru->proc;
int slots_per_frame = fp->slots_per_frame;
proc->tti_rx = *slot;
proc->frame_rx = *frame;
proc->tti_tx = (*slot + ru->sl_ahead) % slots_per_frame;
proc->frame_tx = (*slot > (slots_per_frame - 1 - ru->sl_ahead)) ? (*frame + 1) & 1023 : *frame;
proc->first_rx = 0;
stop_meas(&s->ru.rx_fhaul);
}
extern void tx_rf(RU_t *ru, int frame, int slot, uint64_t timestamp);
extern void nr_feptx0(RU_t *ru, int tti_tx, int first_symbol, int num_symbols, int aa);
static void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
{
fd_rfsim_state_t *state = (fd_rfsim_state_t *)ru->ifdevice.priv;
RU_t *ru_lower = &state->ru;
ru_lower->common.txdataF_BF = ru->common.txdataF_BF;
start_meas(&ru_lower->tx_fhaul);
// FD data is available in ru->common.txdataF_BF.
NR_DL_FRAME_PARMS *fp = ru_lower->nr_frame_parms;
for (int i = 0; i < ru->nb_tx; i++) {
if (!ru->gNB_list[0]->phase_comp) {
apply_nr_rotation_TX(fp,
(c16_t *)ru->common.txdataF_BF[i],
fp->symbol_rotation[0],
slot,
fp->N_RB_DL,
0,
fp->Ncp == EXTENDED ? 12 : 14);
}
nr_feptx0(ru_lower, slot, 0, fp->Ncp == EXTENDED ? 12 : 14, i);
}
LOG_D(HW, "fd_rfsim: fh_if4p5_south_out: frame %d, slot %d, timestamp %lu\n", frame, slot, timestamp);
// Assume this function called in order
static int frame_tx_unwrap = 0;
static int last_frame = 0;
if (frame < last_frame) {
frame_tx_unwrap += 1024;
}
last_frame = frame;
uint64_t timestamp_tx = (frame + frame_tx_unwrap) * fp->samples_per_subframe * 10 + fp->get_samples_slot_timestamp(slot, fp, 0);
tx_rf(ru_lower, frame, slot, timestamp_tx);
// ru->proc = ru_lower->proc; // Copy the RU proc structure back
stop_meas(&ru_lower->tx_fhaul);
}
static void *get_internal_parameter(char *name)
{
printf("ORAN: %s\n", __FUNCTION__);
if (!strcmp(name, "fh_if4p5_south_in"))
return (void *)fh_if4p5_south_in;
if (!strcmp(name, "fh_if4p5_south_out"))
return (void *)fh_if4p5_south_out;
return NULL;
}
int get_tdd_period(uint8_t nb_periods_per_frame)
{
int tdd_period = 0;
switch (nb_periods_per_frame) {
case 20:
tdd_period = 0; // 10ms/0p5ms
break;
case 16:
tdd_period = 1; // 10ms/0p625ms
break;
case 10:
tdd_period = 2; // 10ms/1ms
break;
case 8:
tdd_period = 3; // 10ms/1p25ms
break;
case 5:
tdd_period = 4; // 10ms/2ms
break;
case 4:
tdd_period = 5; // 10ms/2p5ms
break;
case 2:
tdd_period = 6; // 10ms/5ms
break;
case 1:
tdd_period = 7; // 10ms/10ms
break;
default:
AssertFatal(1 == 0, "Undefined nb_periods_per_frame %d\n", nb_periods_per_frame);
}
return tdd_period;
}
typedef struct {
int scs;
int freq_range;
int nr_band;
int ofdm_offset_divisor;
uint64_t dl_CarrierFreq;
uint64_t ul_CarrierFreq;
int num_rb_dl;
int num_rb_ul;
int num_rx_ant;
int num_tx_ant;
} oru_config;
static void configure_ru_t_for_oru(RU_t *ru, oru_config *oru_cfg)
{
memset(ru, 0, sizeof(*ru));
ru->num_gNB = 1;
ru->nr_frame_parms = calloc_or_fail(1, sizeof(*ru->nr_frame_parms));
ru->proc.first_rx = 1;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
fp->freq_range = oru_cfg->freq_range;
fp->nr_band = oru_cfg->nr_band;
fp->ofdm_offset_divisor = oru_cfg->ofdm_offset_divisor;
fp->dl_CarrierFreq = oru_cfg->dl_CarrierFreq;
fp->ul_CarrierFreq = oru_cfg->ul_CarrierFreq;
nfapi_nr_config_request_scf_t *cfg = &ru->config;
memset(cfg, 0, sizeof(*cfg));
cfg->cell_config.frame_duplex_type.value = TDD;
cfg->ssb_config.scs_common.value = oru_cfg->scs;
cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value = oru_cfg->num_rb_dl;
cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value = oru_cfg->num_rb_ul;
cfg->carrier_config.num_rx_ant.value = oru_cfg->num_rx_ant;
cfg->carrier_config.num_tx_ant.value = oru_cfg->num_tx_ant;
cfg->prach_config.prach_sub_c_spacing.value = oru_cfg->scs;
nr_init_frame_parms(&ru->config, fp);
init_symbol_rotation(fp);
init_timeshift_rotation(fp);
nr_dump_frame_parms(fp);
ru->if_south = LOCAL_RF;
ru->function = NGFI_RRU_IF5;
ru->nb_tx = oru_cfg->num_tx_ant;
ru->nb_rx = oru_cfg->num_rx_ant;
nr_phy_init_RU(ru);
ru->N_TA_offset = set_default_nta_offset(fp->freq_range, fp->samples_per_subframe);
}
static bool configure_fd_rfsim(openair0_device *device, openair0_config_t *openair0_config)
{
fd_rfsim_state_t *state = calloc_or_fail(1, sizeof(*state));
mutexinit(state->mutex);
state->is_started = false;
state->last_msg = (rru_config_msg_type_t)-1;
state->capabilities_sent = false;
device->priv = state;
RU_t *ru_lower = &state->ru;
oru_config oru_cfg = {
.scs = 1,
.freq_range = FR1,
.nr_band = openair0_config->nr_band,
.ofdm_offset_divisor = 8, // Default value
.dl_CarrierFreq = openair0_config->tx_freq[0],
.ul_CarrierFreq = openair0_config->rx_freq[0],
.num_rb_dl = openair0_config->num_rb_dl,
.num_rb_ul = openair0_config->num_rb_dl,
.num_rx_ant = openair0_config->rx_num_channels,
.num_tx_ant = openair0_config->tx_num_channels,
};
configure_ru_t_for_oru(ru_lower, &oru_cfg);
// Setup TDD table
ru_lower->config.tdd_table.tdd_period.value = get_tdd_period(openair0_config->split7.n_tdd_period);
NR_DL_FRAME_PARMS *fp = ru_lower->nr_frame_parms;
ru_lower->config.tdd_table.max_tdd_periodicity_list = calloc_or_fail(fp->slots_per_frame, sizeof(nfapi_nr_max_tdd_periodicity_t));
for (int i = 0; i < fp->slots_per_frame; i++) {
ru_lower->config.tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
calloc_or_fail(14, sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
for (int j = 0; j < 14; j++) {
ru_lower->config.tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[j].slot_config.value =
openair0_config->split7.slot_dirs[i % openair0_config->split7.n_tdd_period].sym_dir[j];
}
}
// Allocate some threads to the threadpool
ru_lower->threadPool = calloc_or_fail(1, sizeof(*ru_lower->threadPool));
initFloatingCoresTpool(10, ru_lower->threadPool, false, "RU_lower");
// Force load RFSimulator as the RF device
memcpy(&ru_lower->openair0_cfg, openair0_config, sizeof(*openair0_config));
int ret = openair0_load(&ru_lower->rfdevice, "rfsimulator", &ru_lower->openair0_cfg, NULL);
AssertFatal(ret == 0, "Failed to load openair0 device\n");
// These are fhi_72 specific parameters, currently unused.
// verify oran section is present: we don't have a list but the below returns
// numelt > 0 if the block is there
paramlist_def_t pl = {0};
strncpy(pl.listname, CONFIG_STRING_ORAN, sizeof(pl.listname) - 1);
config_getlist(config_get_if(), &pl, NULL, 0, /* prefix */ NULL);
if (pl.numelt == 0) {
printf("Configuration section \"%s\" not present: cannot initialize fd_rfsim!\n", CONFIG_STRING_ORAN);
return false;
}
paramdef_t fhip[] = ORAN_GLOBALPARAMS_DESC;
checkedparam_t fhip_CheckParams[] = ORAN_GLOBALPARAMS_CHECK_DESC;
static_assert(sizeofArray(fhip) == sizeofArray(fhip_CheckParams), "fhip and fhip_CheckParams should have the same size");
int nump = sizeofArray(fhip);
config_set_checkfunctions(fhip, fhip_CheckParams, nump);
ret = config_get(config_get_if(), fhip, nump, CONFIG_STRING_ORAN);
if (ret <= 0) {
printf("problem reading section \"%s\"\n", CONFIG_STRING_ORAN);
return false;
}
paramdef_t FHconfigs[] = ORAN_FH_DESC;
paramlist_def_t FH_ConfigList = {CONFIG_STRING_ORAN_FH};
char aprefix[MAX_OPTNAME_SIZE] = {0};
sprintf(aprefix, "%s", CONFIG_STRING_ORAN);
const int nfh = sizeofArray(FHconfigs);
config_getlist(config_get_if(), &FH_ConfigList, FHconfigs, nfh, aprefix);
return true;
}
__attribute__((__visibility__("default"))) int transport_init(openair0_device *device,
openair0_config_t *openair0_cfg,
eth_params_t *eth_params)
{
bool ret = configure_fd_rfsim(device, openair0_cfg);
AssertFatal(ret, "Failed to configure fd_rfsim");
device->Mod_id = 0;
device->transp_type = ETHERNET_TP;
device->trx_start_func = trx_start;
device->trx_reset_stats_func = trx_reset_stats;
device->trx_end_func = trx_end;
device->trx_stop_func = trx_stop;
device->trx_set_freq_func = trx_set_freq;
device->trx_set_gains_func = trx_set_gains;
device->trx_write_func = trx_write_raw;
device->trx_read_func = trx_read_raw;
device->trx_ctlsend_func = trx_ctlsend;
device->trx_ctlrecv_func = trx_ctlrecv;
device->get_internal_parameter = get_internal_parameter;
device->openair0_cfg = openair0_cfg;
return 0;
}

View File

@@ -0,0 +1,275 @@
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; }) });
nr_cellid = 1;
////////// Physical parameters:
pdsch_AntennaPorts_XP = 2;
pdsch_AntennaPorts_N1 = 1;
maxMIMO_layers = 1;
pusch_AntennaPorts = 2;
do_CSIRS = 0;
do_SRS = 0;
sib1_tda = 15;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# n_TimingAdvanceOffset = 0;
# downlinkConfigCommon
#frequencyInfoDL
# center frequency = 4049.76 MHz
# selected SSB frequency = 4049.76 MHz
absoluteFrequencySSB = 669984;
dl_frequencyBand = 77;
# frequency point A = 4030.68 MHz
dl_absoluteFrequencyPointA = 668712;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
initialDLBWPlocationAndBandwidth = 28875; #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 = 77;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 23;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# 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 = 0;
preambleReceivedTargetPower = -100;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 7;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 2;
#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 = 4;
#one (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,
# this is the offset between the last PRACH preamble power and the Msg3 PUSCH, 2 times the field value in dB
msg3_DeltaPreamble = 2;
p0_NominalWithGrant = -100;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 0;
p0_nominal = -96;
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 = 0;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ({ ipv4 = "192.168.70.132"; });
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
# dl_bler_target_upper = .35;
# dl_bler_target_lower = .15;
ul_bler_target_upper = .35;
ul_bler_target_lower = .15;
pusch_FailureThres = 10;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 110;
pucch0_dtx_threshold = 80;
pusch_dtx_threshold = 50;
# thread_pool_size = 8;
tx_amp_backoff_dB = 36;
L1_rx_thread_core = 8;
L1_tx_thread_core = 10;
phase_compensation = 0; # needs to match O-RU configuration
}
);
RUs = (
{
local_rf = "no";
nb_tx = 2;
nb_rx = 2;
att_tx = 0;
att_rx = 0;
bands = [77];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
sf_extension = 0;
eNB_instances = [0];
ru_thread_core = 9;
sl_ahead = 5;
tr_preference = "raw_if4p5"; # important: activate FHI7.2
do_precoding = 0; # needs to match O-RU configuration
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level = "info";
hw_log_level = "info";
phy_log_level = "info";
mac_log_level = "info";
rlc_log_level = "info";
pdcp_log_level = "info";
rrc_log_level = "info";
ngap_log_level = "info";
f1ap_log_level = "info";
};
fhi_72 = {
dpdk_devices = ("0000:c1:11.0", "0000:c1:11.1"); # one VF can be used as well
system_core = 0;
io_core = 1;
worker_cores = (2);
ru_addr = ("98:ae:71:04:83:e3", "98:ae:71:04:83:e3");
mtu = 9600;
fh_config = ({
T1a_cp_dl = (285, 470);
T1a_cp_ul = (285, 429);
T1a_up = (125, 350);
Ta4 = (110, 180);
ru_config = {
iq_width = 9;
iq_width_prach = 9;
};
});
};

View File

@@ -0,0 +1,274 @@
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; }) });
nr_cellid = 1;
////////// Physical parameters:
pdsch_AntennaPorts_XP = 2;
pdsch_AntennaPorts_N1 = 2;
maxMIMO_layers = 2;
pusch_AntennaPorts = 4;
do_CSIRS = 1;
do_SRS = 0;
sib1_tda = 15;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# n_TimingAdvanceOffset = 0;
# downlinkConfigCommon
#frequencyInfoDL
# center frequency = 4049.76 MHz
# selected SSB frequency = 4049.76 MHz
absoluteFrequencySSB = 669984;
dl_frequencyBand = 77;
# frequency point A = 4030.68 MHz
dl_absoluteFrequencyPointA = 668712;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
initialDLBWPlocationAndBandwidth = 28875; #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 = 77;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 23;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# 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 = 0;
preambleReceivedTargetPower = -100;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 7;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 2;
#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 = 4;
#one (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,
# this is the offset between the last PRACH preamble power and the Msg3 PUSCH, 2 times the field value in dB
msg3_DeltaPreamble = 2;
p0_NominalWithGrant = -100;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 0;
p0_nominal = -96;
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 = 0;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ({ ipv4 = "192.168.70.132"; });
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24";
GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
# dl_bler_target_upper = .35;
# dl_bler_target_lower = .15;
ul_bler_target_upper = .35;
ul_bler_target_lower = .15;
pusch_FailureThres = 100;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 110;
pucch0_dtx_threshold = 80;
pusch_dtx_threshold = -100;
# thread_pool_size = 8;
tx_amp_backoff_dB = 36;
L1_rx_thread_core = 8;
L1_tx_thread_core = 10;
phase_compensation = 0; # needs to match O-RU configuration
}
);
RUs = (
{
local_rf = "no";
nb_tx = 4;
nb_rx = 4;
att_tx = 0;
att_rx = 0;
bands = [77];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
sf_extension = 0;
eNB_instances = [0];
ru_thread_core = 9;
sl_ahead = 5;
tr_preference = "raw_if4p5"; # important: activate FHI7.2
do_precoding = 0; # needs to match O-RU configuration
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level = "info";
hw_log_level = "info";
phy_log_level = "info";
mac_log_level = "info";
rlc_log_level = "info";
pdcp_log_level = "info";
rrc_log_level = "info";
ngap_log_level = "info";
f1ap_log_level = "info";
};
fhi_72 = {
dpdk_devices = ("0000:c1:11.0", "0000:c1:11.1"); # one VF can be used as well
system_core = 0;
io_core = 1;
worker_cores = (2);
ru_addr = ("98:ae:71:04:83:e3", "98:ae:71:04:83:e3");
mtu = 9600;
fh_config = ({
T1a_cp_dl = (285, 470);
T1a_cp_ul = (285, 429);
T1a_up = (125, 350);
Ta4 = (110, 180);
ru_config = {
iq_width = 9;
iq_width_prach = 9;
};
});
};