Merge remote-tracking branch 'origin/develop' into develop-SRS-feedback
# Conflicts: # openair1/SCHED_NR/phy_procedures_nr_gNB.c # openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
This commit is contained in:
@@ -21,10 +21,10 @@
|
||||
|
||||
# Author: laurent THOMAS, Lionel GAUTHIER
|
||||
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
cmake_minimum_required (VERSION 3.5)
|
||||
project (OpenAirInterface LANGUAGES C CXX)
|
||||
|
||||
include("macros.cmake")
|
||||
include("cmake_targets/macros.cmake")
|
||||
|
||||
# System packages that are required
|
||||
# We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/
|
||||
@@ -1541,7 +1541,6 @@ set(PHY_SRC
|
||||
|
||||
set(PHY_SRC_RU
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/drs_modulation.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_demodulation.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
|
||||
@@ -3194,3 +3193,5 @@ ADD_CUSTOM_TARGET(oarf
|
||||
|
||||
include (${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_CMakeLists.txt)
|
||||
include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt)
|
||||
|
||||
add_subdirectory(openair2)
|
||||
@@ -2404,7 +2404,7 @@ class OaiCiTest():
|
||||
if launchFromTrfContainer:
|
||||
SSH.command('docker exec -it prod-trf-gen /bin/bash -c "killall --signal SIGKILL iperf"', '\$', 5)
|
||||
else:
|
||||
SSH.command('killall --signal SIGKILL iperf', EPC.UserName, 5)
|
||||
SSH.command('killall --signal SIGKILL iperf', '\$', 5)
|
||||
SSH.close()
|
||||
else:
|
||||
cmd = 'killall --signal SIGKILL iperf'
|
||||
@@ -3894,8 +3894,8 @@ class OaiCiTest():
|
||||
logging.debug('UHD Version is: ' + UhdVersion)
|
||||
HTML.UhdVersion[idx]=UhdVersion
|
||||
else:
|
||||
SSH.command('uhd_config_info --version', '\$', 5)
|
||||
result = re.search('UHD (?P<uhd_version>[a-zA-Z0-9\.\-]+)', SSH.getBefore())
|
||||
SSH.command('uhd_config_info --abi-version', '\$', 5)
|
||||
result = re.search('ABI version string: (?P<uhd_version>[a-zA-Z0-9\.\-]+)', SSH.getBefore())
|
||||
if result is not None:
|
||||
UhdVersion = result.group('uhd_version')
|
||||
logging.debug('UHD Version is: ' + UhdVersion)
|
||||
|
||||
@@ -198,8 +198,8 @@ RUs = (
|
||||
local_rf = "yes"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
att_tx = 6
|
||||
att_rx = 6;
|
||||
bands = [38];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 115;
|
||||
|
||||
@@ -198,8 +198,8 @@ RUs = (
|
||||
local_rf = "yes"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
att_tx = 6
|
||||
att_rx = 6;
|
||||
bands = [38];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 125;
|
||||
|
||||
@@ -198,8 +198,8 @@ RUs = (
|
||||
local_rf = "yes"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
att_tx = 6
|
||||
att_rx = 6;
|
||||
bands = [38];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 120;
|
||||
|
||||
@@ -196,8 +196,8 @@ RUs = (
|
||||
local_rf = "yes"
|
||||
nb_tx = 2
|
||||
nb_rx = 2
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
att_tx = 6
|
||||
att_rx = 6;
|
||||
bands = [38];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 110;
|
||||
|
||||
@@ -7,7 +7,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -209,8 +209,8 @@ RUs = (
|
||||
tr_preference = "udp_if4p5"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
att_tx = 6
|
||||
att_rx = 6;
|
||||
eNB_instances = [0];
|
||||
}
|
||||
);
|
||||
|
||||
@@ -209,8 +209,8 @@ RUs = (
|
||||
tr_preference = "udp_if4p5"
|
||||
nb_tx = 1
|
||||
nb_rx = 1
|
||||
att_tx = 0
|
||||
att_rx = 0;
|
||||
att_tx = 6
|
||||
att_rx = 6;
|
||||
eNB_instances = [0];
|
||||
}
|
||||
);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#this is a configuration file
|
||||
#used to build real time processing statistics
|
||||
#for 5G NR phy test (gNB terminate)
|
||||
Title : Processing Time (us)
|
||||
ColNames :
|
||||
- Metric
|
||||
- Average; Max; Count
|
||||
- Average vs Reference Deviation (Reference Value; Acceptability Threshold)
|
||||
Ref :
|
||||
feprx : 48.0
|
||||
feptx_prec : 16.0
|
||||
feptx_ofdm : 35.0
|
||||
feptx_total : 59.0
|
||||
L1 Tx processing : 210.0
|
||||
DLSCH encoding : 129.0
|
||||
L1 Rx processing : 287.0
|
||||
PUSCH inner-receiver : 166.0
|
||||
PUSCH decoding : 176.0
|
||||
Schedule Response : 42.0
|
||||
DL & UL scheduling timing : 13.0
|
||||
UL Indication : 55.0
|
||||
Threshold :
|
||||
feprx : 1.25
|
||||
feptx_prec : 1.25
|
||||
feptx_ofdm : 1.25
|
||||
feptx_total : 1.25
|
||||
L1 Tx processing : 1.25
|
||||
DLSCH encoding : 1.25
|
||||
L1 Rx processing : 1.25
|
||||
PUSCH inner-receiver : 1.25
|
||||
PUSCH decoding : 1.25
|
||||
Schedule Response : 1.25
|
||||
DL & UL scheduling timing : 1.25
|
||||
UL Indication : 1.25
|
||||
@@ -7,18 +7,18 @@ ColNames :
|
||||
- Average; Max; Count
|
||||
- Average vs Reference Deviation (Reference Value; Acceptability Threshold)
|
||||
Ref :
|
||||
feprx : 60.0
|
||||
feptx_prec : 8.0
|
||||
feptx_ofdm : 50.0
|
||||
feptx_total : 75.0
|
||||
L1 Tx processing : 300.0
|
||||
DLSCH encoding : 230.0
|
||||
L1 Rx processing : 175.0
|
||||
PUSCH inner-receiver : 100.0
|
||||
#PUSCH decoding : 180.0
|
||||
PUSCH decoding : 240.0
|
||||
DL & UL scheduling timing : 37.0
|
||||
UL Indication : 38.0
|
||||
feprx : 53.0
|
||||
feptx_prec : 20.0
|
||||
feptx_ofdm : 37.0
|
||||
feptx_total : 62.0
|
||||
L1 Tx processing : 170.0
|
||||
DLSCH encoding : 118.0
|
||||
L1 Rx processing : 223.0
|
||||
PUSCH inner-receiver : 107.0
|
||||
PUSCH decoding : 170.0
|
||||
Schedule Response : 15.0
|
||||
DL & UL scheduling timing : 10.0
|
||||
UL Indication : 27.0
|
||||
Threshold :
|
||||
feprx : 1.25
|
||||
feptx_prec : 1.25
|
||||
@@ -29,5 +29,6 @@ Threshold :
|
||||
L1 Rx processing : 1.25
|
||||
PUSCH inner-receiver : 1.25
|
||||
PUSCH decoding : 1.25
|
||||
Schedule Response : 1.25
|
||||
DL & UL scheduling timing : 1.25
|
||||
UL Indication : 1.25
|
||||
|
||||
@@ -379,7 +379,7 @@ VM_TEMPLATE=ci-
|
||||
|
||||
# look for ASN1 release in cmake directives
|
||||
# It will be the release used when building
|
||||
ASN1VEROPT=( `grep "set (RRC_ASN1_VERSION" cmake_targets/CMakeLists.txt` )
|
||||
ASN1VEROPT=( `grep "set (RRC_ASN1_VERSION" CMakeLists.txt` )
|
||||
ASN1VER=${ASN1VEROPT[2]//\"}
|
||||
ASN1VER=${ASN1VER//)}
|
||||
unset ASN1VEROPT
|
||||
|
||||
@@ -1217,7 +1217,7 @@ function start_rf_sim_nr_ue {
|
||||
then
|
||||
echo "echo \"./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --sa --log_config.global_log_options level,nocolor,time\" > ./my-nr-softmodem-run.sh " >> $1
|
||||
else # -eq 3 SA test 24PRB
|
||||
echo "echo \"./nr-uesoftmodem -r 24 -s 24 --numerology 1 --band 78 -C 3604320000 --rfsim --sa --log_config.global_log_options level,nocolor,time\" > ./my-nr-softmodem-run.sh " >> $1
|
||||
echo "echo \"./nr-uesoftmodem -r 24 --ssb 24 --numerology 1 --band 78 -C 3604320000 --rfsim --sa --log_config.global_log_options level,nocolor,time\" > ./my-nr-softmodem-run.sh " >> $1
|
||||
fi
|
||||
fi
|
||||
echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1
|
||||
|
||||
@@ -111,16 +111,16 @@
|
||||
|
||||
<testCase id="040651">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (10MHz - UL/20Mbps/UDP)(30 sec)(balanced profile)</desc>
|
||||
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
|
||||
<desc>iperf (10MHz - UL/18Mbps/UDP)(30 sec)(balanced profile)</desc>
|
||||
<iperf_args>-u -b 18M -t 30 -i 1 -R</iperf_args>
|
||||
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
|
||||
<iperf_profile>balanced</iperf_profile>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040652">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
|
||||
<desc>iperf (10MHz - UL/18Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 18M -t 30 -i 1 -R</iperf_args>
|
||||
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
|
||||
<iperf_profile>single-ue</iperf_profile>
|
||||
</testCase>
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>gNB-PHY-Test</htmlTabRef>
|
||||
<htmlTabName>Run-gNB-PHY-Test</htmlTabName>
|
||||
<htmlTabRef>gNB-PHY-Test-40</htmlTabRef>
|
||||
<htmlTabName>Timing phytest 40 MHz</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
@@ -33,7 +33,8 @@
|
||||
<testCase id="090101">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize gNB USRP</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test -q -U 787200 -T 106 -t 28 -D 130175 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test -q -U 787200 -T 106 -t 23 -D 130175 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
|
||||
<rt_stats_cfg>datalog_rt_stats.default.yaml</rt_stats_cfg>
|
||||
<air_interface>NR</air_interface>
|
||||
<USRP_IPAddress>192.168.20.2</USRP_IPAddress>
|
||||
</testCase>
|
||||
@@ -41,7 +42,7 @@
|
||||
<testCase id="000001">
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>300</idle_sleep_time_in_sec>
|
||||
<idle_sleep_time_in_sec>60</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<!--
|
||||
|
||||
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>gNB-PHY-Test-60</htmlTabRef>
|
||||
<htmlTabName>Timing phytest 60 MHz</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
190101 000001 190109
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="190101">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize gNB USRP</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test --gNBs.[0].servingCellConfigCommon.[0].dl_carrierBandwidth 162 --gNBs.[0].servingCellConfigCommon.[0].ul_carrierBandwidth 162 -q -U 787200 -T 162 -t 23 -D 130175 -m 23 -M 162 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
|
||||
<rt_stats_cfg>datalog_rt_stats.1x1.60.yaml</rt_stats_cfg>
|
||||
<air_interface>NR</air_interface>
|
||||
<USRP_IPAddress>192.168.20.2</USRP_IPAddress>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000001">
|
||||
<class>IdleSleep</class>
|
||||
<desc>Sleep</desc>
|
||||
<idle_sleep_time_in_sec>60</idle_sleep_time_in_sec>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="190109">
|
||||
<class>Terminate_eNB</class>
|
||||
<desc>Terminate gNB</desc>
|
||||
<air_interface>NR</air_interface>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
@@ -270,7 +270,7 @@ services:
|
||||
OPC: 'C42449363BBAD02B66D16BC975D77CC1'
|
||||
DNN: oai
|
||||
NSSAI_SST: 1
|
||||
USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --band 66 -C 2169080000 --CO -400000000 -s 396 --nokrnmod --log_config.global_log_options level,nocolor,time
|
||||
USE_ADDITIONAL_OPTIONS: -E --sa --rfsim -r 106 --numerology 1 --band 66 -C 2169080000 --CO -400000000 --ssb 396 --nokrnmod --log_config.global_log_options level,nocolor,time
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
|
||||
+5
-77
@@ -126,10 +126,6 @@ Options:
|
||||
Adds a debgging facility to the binary files: GUI with major internal synchronization events
|
||||
-x | --xforms
|
||||
Will compile with software oscilloscope features
|
||||
--HWLAT
|
||||
Makes test program for haw latency tests
|
||||
--HWLAT_TEST
|
||||
Compiles a hw latency test program
|
||||
--verbose-ci
|
||||
Compile with verbose instructions in CI Docker env
|
||||
--verbose-compile
|
||||
@@ -345,14 +341,6 @@ function main() {
|
||||
EXE_ARGUMENTS="$EXE_ARGUMENTS -d"
|
||||
echo_info "Will generate the software oscilloscope features"
|
||||
shift;;
|
||||
--HWLAT)
|
||||
HWLAT=1
|
||||
echo_info "Will compile hw latency test program"
|
||||
shift;;
|
||||
--HWLAT_TEST)
|
||||
HWLAT_TEST=1
|
||||
echo_info "Will compile hw latency test program"
|
||||
shift;;
|
||||
--verbose-ci)
|
||||
VERBOSE_CI=1
|
||||
echo_info "Will compile with verbose instructions in CI Docker env"
|
||||
@@ -502,12 +490,6 @@ function main() {
|
||||
echo_info "No transport protocol has been selected (TP set to $TP)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$HWLAT" = "1" ] ; then
|
||||
if [ "$HW" = "None" ] ; then
|
||||
echo_info "No radio head has been selected (HW set to $HW)"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo_info "RF HW set to $HW"
|
||||
# If the user doesn't specify the Linux scheduler to use, we set a value
|
||||
@@ -632,9 +614,11 @@ function main() {
|
||||
cd $DIR/$BUILD_DIR/build
|
||||
if [[ ${#CMAKE_C_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_C_FLAGS=\"${CMAKE_C_FLAGS[*]}\""; fi
|
||||
if [[ ${#CMAKE_CXX_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_CXX_FLAGS=\"${CMAKE_CXX_FLAGS[*]}\""; fi
|
||||
CMAKE_CMD="$CMAKE_CMD -DNOAVX512=\"${NOAVX512[*]}\""
|
||||
# for historical reasons we build in a subdirectory cmake_targets/XYZ/build,
|
||||
# e.g., cmake_targets/ran_build/build, hence the ../../..
|
||||
CMAKE_CMD="$CMAKE_CMD -DNOAVX512=\"${NOAVX512[*]}\" ../../.."
|
||||
echo_info "running $CMAKE_CMD"
|
||||
eval $CMAKE_CMD ../..
|
||||
eval $CMAKE_CMD
|
||||
|
||||
for f in $execlist ; do
|
||||
echo_info "Compiling $f..."
|
||||
@@ -775,67 +759,11 @@ function main() {
|
||||
lib${oklib}.so $dbin/lib${oklib}.so
|
||||
done
|
||||
fi
|
||||
|
||||
#####################
|
||||
# HWLAT compilation #
|
||||
#####################
|
||||
if [ "$HWLAT" = "1" ] ; then
|
||||
|
||||
hwlat_exec=lte-hwlat
|
||||
hwlat_build_dir=lte-hwlat
|
||||
|
||||
echo_info "Compiling $hwlat_exec ..."
|
||||
|
||||
[ "$CLEAN" = "1" ] && rm -rf $DIR/lte-hwlat/build
|
||||
mkdir -p $DIR/$hwlat_build_dir/build
|
||||
cmake_file=$DIR/$hwlat_build_dir/CMakeLists.txt
|
||||
echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file
|
||||
echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file
|
||||
echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file
|
||||
echo 'set ( PACKAGE_NAME "\"lte-hwlat\"")' >> $cmake_file
|
||||
echo "set ( DEADLINE_SCHEDULER \"${DEADLINE_SCHEDULER_FLAG_USER}\" )" >> $cmake_file
|
||||
echo "set ( CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )" >> $cmake_file
|
||||
echo "set ( HWLAT \"${HWLAT}\" )" >> $cmake_file
|
||||
echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
|
||||
cd $DIR/$hwlat_build_dir/build
|
||||
cmake ..
|
||||
compilations \
|
||||
lte-hwlat lte-hwlat \
|
||||
lte-hwlat $dbin/lte-hwlat
|
||||
fi
|
||||
|
||||
##########################
|
||||
# HWLAT_TEST compilation #
|
||||
##########################
|
||||
if [ "$HWLAT_TEST" = "1" ] ; then
|
||||
|
||||
hwlat_test_exec=lte-hwlat-test
|
||||
hwlat_test_build_dir=lte-hwlat-test
|
||||
|
||||
echo_info "Compiling $hwlat_test_exec ..."
|
||||
|
||||
[ "$CLEAN" = "1" ] && rm -rf $DIR/lte-hwlat-test/build
|
||||
mkdir -p $DIR/$hwlat_test_build_dir/build
|
||||
cmake_file=$DIR/$hwlat_test_build_dir/CMakeLists.txt
|
||||
echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file
|
||||
echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file
|
||||
echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file
|
||||
echo 'set ( PACKAGE_NAME "\"lte-hwlat-test\"")' >> $cmake_file
|
||||
echo "set ( DEADLINE_SCHEDULER \"${DEADLINE_SCHEDULER_FLAG_USER}\" )" >> $cmake_file
|
||||
echo "set ( CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )" >> $cmake_file
|
||||
echo "set ( HWLAT \"${HWLAT}\" )" >> $cmake_file
|
||||
echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
|
||||
cd $DIR/$hwlat_test_build_dir/build
|
||||
cmake ..
|
||||
compilations \
|
||||
lte-hwlat-test lte-hwlat-test \
|
||||
lte-hwlat-test $dbin/lte-hwlat-test
|
||||
fi
|
||||
|
||||
####################################################
|
||||
# Build RF device and transport protocol libraries #
|
||||
####################################################
|
||||
if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$RU" = "1" -o "$nrUE" = "1" -o "$HWLAT" = "1" ] ; then
|
||||
if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$RU" = "1" -o "$nrUE" = "1" ] ; then
|
||||
|
||||
# build RF device libraries
|
||||
if [ "$HW" != "None" ] ; then
|
||||
|
||||
@@ -77,7 +77,7 @@ endmacro(add_list_string_option)
|
||||
function(make_version VERSION_VALUE)
|
||||
math(EXPR RESULT "0")
|
||||
foreach (ARG ${ARGN})
|
||||
math(EXPR RESULT "${RESULT} * 16 + ${ARG}")
|
||||
math(EXPR RESULT "${RESULT} * 256 + ${ARG}")
|
||||
endforeach()
|
||||
set(${VERSION_VALUE} "${RESULT}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -346,11 +346,34 @@ install_usrp_uhd_driver_from_source(){
|
||||
rm -rf /tmp/uhd
|
||||
git clone https://github.com/EttusResearch/uhd.git
|
||||
cd uhd
|
||||
# For our legacy TDD eNB running with a B2xx RF board
|
||||
# the following patch has to be applied
|
||||
if [[ -v UHD_VERSION ]]; then
|
||||
git checkout tags/v${UHD_VERSION}
|
||||
# We recommend to use not older than 3.15.0.0
|
||||
if [[ "$UHD_VERSION" == "3.15.0.0" ]]; then
|
||||
# Tested that patch for the following versions:
|
||||
# - 3.15.0.0
|
||||
git apply $OPENAIR_DIR/cmake_targets/tools/uhd-3.15-tdd-patch.diff
|
||||
ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch"
|
||||
else
|
||||
# Tested that patch for the following versions:
|
||||
# - 4.0.0.0
|
||||
# - 4.1.0.0
|
||||
# - 4.1.0.5
|
||||
# - 4.2.0.0
|
||||
# - 4.2.0.1
|
||||
# - 4.3.0.0-rc1
|
||||
git apply $OPENAIR_DIR/cmake_targets/tools/uhd-4.x-tdd-patch.diff
|
||||
ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch"
|
||||
fi
|
||||
else
|
||||
git checkout tags/v4.0.0.0
|
||||
git apply $OPENAIR_DIR/cmake_targets/tools/uhd-4.x-tdd-patch.diff
|
||||
ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch"
|
||||
fi
|
||||
# Printing out the results of the patch to make sure it was properly applied
|
||||
git diff
|
||||
mkdir -p host/build
|
||||
cd host/build || true
|
||||
$CMAKE ../ -GNinja
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
|
||||
index 1be8c263b..f64546914 100644
|
||||
--- a/host/lib/usrp/b200/b200_impl.cpp
|
||||
+++ b/host/lib/usrp/b200/b200_impl.cpp
|
||||
@@ -1269,10 +1269,10 @@ void b200_impl::update_atrs(void)
|
||||
if (enb_rx and not enb_tx) fd = rxonly;
|
||||
if (not enb_rx and enb_tx) fd = txonly;
|
||||
gpio_atr_3000::sptr atr = perif.atr;
|
||||
- atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF);
|
||||
- atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly);
|
||||
- atr->set_atr_reg(ATR_REG_TX_ONLY, txonly);
|
||||
- atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd);
|
||||
+ atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd | (1<<7));
|
||||
}
|
||||
if (_radio_perifs.size() > _fe2 and _radio_perifs[_fe2].atr)
|
||||
{
|
||||
@@ -1287,10 +1287,10 @@ void b200_impl::update_atrs(void)
|
||||
if (enb_rx and not enb_tx) fd = rxonly;
|
||||
if (not enb_rx and enb_tx) fd = txonly;
|
||||
gpio_atr_3000::sptr atr = perif.atr;
|
||||
- atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF);
|
||||
- atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly);
|
||||
- atr->set_atr_reg(ATR_REG_TX_ONLY, txonly);
|
||||
- atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd);
|
||||
+ atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd | (1<<7));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
|
||||
index 6de161e87..432af5784 100644
|
||||
--- a/host/lib/usrp/b200/b200_impl.cpp
|
||||
+++ b/host/lib/usrp/b200/b200_impl.cpp
|
||||
@@ -1410,10 +1410,10 @@ void b200_impl::update_atrs(void)
|
||||
if (not enb_rx and enb_tx)
|
||||
fd = txonly;
|
||||
gpio_atr_3000::sptr atr = perif.atr;
|
||||
- atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF);
|
||||
- atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly);
|
||||
- atr->set_atr_reg(ATR_REG_TX_ONLY, txonly);
|
||||
- atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd);
|
||||
+ atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd | (1<<7));
|
||||
}
|
||||
if (_radio_perifs.size() > _fe2 and _radio_perifs[_fe2].atr) {
|
||||
radio_perifs_t& perif = _radio_perifs[_fe2];
|
||||
@@ -1431,10 +1431,10 @@ void b200_impl::update_atrs(void)
|
||||
if (not enb_rx and enb_tx)
|
||||
fd = txonly;
|
||||
gpio_atr_3000::sptr atr = perif.atr;
|
||||
- atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF);
|
||||
- atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly);
|
||||
- atr->set_atr_reg(ATR_REG_TX_ONLY, txonly);
|
||||
- atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd);
|
||||
+ atr->set_atr_reg(ATR_REG_IDLE, STATE_OFF | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_RX_ONLY, rxonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_TX_ONLY, txonly | (1<<7));
|
||||
+ atr->set_atr_reg(ATR_REG_FULL_DUPLEX, fd | (1<<7));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
|
||||
* Formats the full shared library path, using the `modname` argument and the loader `shlibpath` and `shlibversion`configuration parameters.
|
||||
* loads the shared library, using the dlopen system call
|
||||
* looks for `< modname >_autoinit` symbol, using the `dlsym` system call and possibly call the corresponding function.
|
||||
* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set in the `PACKAGE_VERSION` macro defined in the [oai CMakeLists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt#L218), around line 218. The second argument points to the shared library version which should be set by the `< modname >_checkbuildver` function.
|
||||
* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set in the `PACKAGE_VERSION` macro defined in the [oai CMakeLists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/CMakeLists.txt#L218), around line 218. The second argument points to the shared library version which should be set by the `< modname >_checkbuildver` function.
|
||||
* If the farray pointer is null, looks for `< modname >_getfarray` symbol, calls the corresponding function when the symbol is found. `< modname >_getfarray` takes one argument, a pointer to a `loader_shlibfunc_t` array, and returns the number of items in this array, as defined by the `getfarrayfunc_t` type. The `loader_shlibfunc_t` array returned by the shared library must be fully filled (both `fname` and `fptr` fields).
|
||||
* looks for the `numf` function symbols listed in the `farray[i].fname` arguments and set the corresponding `farray[i].fptr`function pointers
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ extern "C" {
|
||||
* @brief the macros that describe the maximum length of LOG
|
||||
* @{*/
|
||||
|
||||
#define MAX_LOG_TOTAL 1500 /*!< \brief the maximum length of a log */
|
||||
#define MAX_LOG_TOTAL 16384 /*!< \brief the maximum length of a log */
|
||||
/* @}*/
|
||||
|
||||
/** @defgroup _log_level Message levels defined by LOG
|
||||
@@ -219,6 +219,7 @@ typedef enum {
|
||||
SPGW,
|
||||
S1AP,
|
||||
F1AP,
|
||||
E1AP,
|
||||
SCTP,
|
||||
HW,
|
||||
OSA,
|
||||
|
||||
@@ -1235,6 +1235,27 @@ ID = LEGACY_F1AP_ERROR
|
||||
GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_ERROR:LEGACY
|
||||
FORMAT = string,log
|
||||
|
||||
ID = LEGACY_E1AP_TRACE
|
||||
DESC = E1AP TRACE LEVEL
|
||||
GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_TRACE:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_E1AP_DEBUG
|
||||
DESC = E1AP DEBUG LEVEL
|
||||
GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_DEBUG:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_E1AP_INFO
|
||||
DESC = E1AP INFO LEVEL
|
||||
GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_INFO:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_E1AP_WARNING
|
||||
DESC = E1AP WARNING LEVEL
|
||||
GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_WARNING:LEGACY
|
||||
FORMAT = string,log
|
||||
ID = LEGACY_E1AP_ERROR
|
||||
DESC = E1AP ERROR LEVEL
|
||||
GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_ERROR:LEGACY
|
||||
FORMAT = string,log
|
||||
|
||||
#################
|
||||
#### UE LOGS ####
|
||||
#################
|
||||
|
||||
@@ -339,6 +339,8 @@ void *rrc_enb_process_msg(void *);
|
||||
TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)\
|
||||
TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_CUCP_E1, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_CUUP_E1, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_RRC_UE_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_RRC_GNB_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_RRC_NSA_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
|
||||
@@ -50,11 +50,6 @@
|
||||
{"dlsch_turbo_encod_prep", &(phyvars->dlsch_turbo_encoding_preperation_stats),0,1},\
|
||||
{"dlsch_turbo_encod_segm", &(phyvars->dlsch_turbo_encoding_segmentation_stats),0,1},\
|
||||
{"dlsch_turbo_encod", &(phyvars->dlsch_turbo_encoding_stats),0,1},\
|
||||
{"dlsch_turbo_encod_waiting", &(phyvars->dlsch_turbo_encoding_waiting_stats),0,1},\
|
||||
{"dlsch_turbo_encod_signal", &(phyvars->dlsch_turbo_encoding_signal_stats),0,1},\
|
||||
{"dlsch_turbo_encod_main", &(phyvars->dlsch_turbo_encoding_main_stats),0,1},\
|
||||
{"dlsch_turbo_encod_wakeup0", &(phyvars->dlsch_turbo_encoding_wakeup_stats0),0,1},\
|
||||
{"dlsch_turbo_encod_wakeup1", &(phyvars->dlsch_turbo_encoding_wakeup_stats1),0,1},\
|
||||
{"dlsch_interleaving", &(phyvars->dlsch_interleaving_stats),0,1},\
|
||||
{"rx_dft", &(phyvars->rx_dft_stats),0,1},\
|
||||
{"ulsch_channel_estimation", &(phyvars->ulsch_channel_estimation_stats),0,1},\
|
||||
|
||||
@@ -85,21 +85,21 @@ void print_meas(time_stats_t *ts,
|
||||
first_time=1;
|
||||
|
||||
if ((total_exec_time == NULL) || (sf_exec_time== NULL))
|
||||
fprintf(stderr, "%25s %25s %25s %25s %25s %6f\n","Name","Total","Per Trials", "Num Trials","CPU_F_GHz", cpu_freq_GHz);
|
||||
fprintf(stderr, "%30s %25s %25s %25s %25s %6f\n","Name","Total","Per Trials", "Num Trials","CPU_F_GHz", cpu_freq_GHz);
|
||||
else
|
||||
fprintf(stderr, "%25s %25s %25s %20s %15s %6f\n","Name","Total","Average/Frame","Trials", "CPU_F_GHz", cpu_freq_GHz);
|
||||
fprintf(stderr, "%30s %25s %25s %20s %15s %6f\n","Name","Total","Average/Frame","Trials", "CPU_F_GHz", cpu_freq_GHz);
|
||||
}
|
||||
|
||||
if (ts->trials>0) {
|
||||
//printf("%20s: total: %10.3f ms, average: %10.3f us (%10d trials)\n", name, ts->diff/cpu_freq_GHz/1000000.0, ts->diff/ts->trials/cpu_freq_GHz/1000.0, ts->trials);
|
||||
if ((total_exec_time == NULL) || (sf_exec_time== NULL)) {
|
||||
fprintf(stderr, "%25s: %15.3f us; %15d; %15.3f us;\n",
|
||||
fprintf(stderr, "%30s: %15.3f us; %15d; %15.3f us;\n",
|
||||
name,
|
||||
(ts->diff/ts->trials/cpu_freq_GHz/1000.0),
|
||||
ts->trials,
|
||||
ts->max/cpu_freq_GHz/1000.0);
|
||||
} else {
|
||||
fprintf(stderr, "%25s: %15.3f ms (%5.2f%%); %15.3f us (%5.2f%%); %15d;\n",
|
||||
fprintf(stderr, "%30s: %15.3f ms (%5.2f%%); %15.3f us (%5.2f%%); %15d;\n",
|
||||
name,
|
||||
(ts->diff/cpu_freq_GHz/1000000.0),
|
||||
((ts->diff/cpu_freq_GHz/1000000.0)/(total_exec_time->diff/cpu_freq_GHz/1000000.0))*100, // percentage
|
||||
|
||||
+18
-45
@@ -39,7 +39,7 @@ Running the [build_oai](../cmake_targets/build_oai) script also generates some
|
||||
- `rb_tool`: radio bearer utility
|
||||
- `genids` T Tracer utility, used at build time to generate T_IDs.h include file. This binary is located in the [T Tracer source file directory](../common/utils/T) .
|
||||
|
||||
The build system for OAI uses [cmake](https://cmake.org/) which is a tool to generate makefiles. The `build_oai` script is a wrapper using cmake, make and standard linux shell commands to ease the oai build and use . The file describing how to build the executables from source files is the [CMakeLists.txt](../cmake_targets/CMakeLists.txt), it is used as input by cmake to generate the makefiles.
|
||||
The build system for OAI uses [cmake](https://cmake.org/) which is a tool to generate makefiles. The `build_oai` script is a wrapper using cmake, make and standard linux shell commands to ease the oai build and use . The file describing how to build the executables from source files is the [CMakeLists.txt](../CMakeLists.txt), it is used as input by cmake to generate the makefiles.
|
||||
|
||||
The oai softmodem supports many use cases, and new ones are regularly added. Most of them are accessible using the configuration file or the command line options and continuous effort is done to avoid introducing build options as it makes tests and usage more complicated than run-time options. The following functionalities, originally requiring a specific build are now accessible by configuration or command line options:
|
||||
|
||||
@@ -88,12 +88,19 @@ You can build any oai softmodem executable separately, you may not need all of t
|
||||
|
||||
After completing the build, the binaries are available in the `cmake_targets/ran_build/build` directory. A copy is also available in the `target/bin` directory, with all binaries suffixed by the 3GPP release number, today .Rel15.
|
||||
|
||||
When installing the pre-requisites, especially the `UHD` driver, you can now specify if you want to install from source or not.
|
||||
## Installing UHD from source
|
||||
|
||||
Previously for Ubuntu distributions, when installing the pre-requisites, most of the packages are installed from PPA.
|
||||
|
||||
Especially the `UHD` driver, but you could not easily manage the version of `libuhd` that will be installed.
|
||||
|
||||
Now, when installing the pre-requisites, especially the `UHD` driver, you can now specify if you want to install from source or not.
|
||||
|
||||
- For `fedora`-based OS, it was already the case all the time. But now you can specify which version to install.
|
||||
- For `ubuntu` OS, the Ettus PPA currently installs the following versions:
|
||||
* `Ubuntu16.04`: --> version `3.15.0.0`
|
||||
* `Ubuntu18.04`: --> version `4.1.0.0`
|
||||
- For `ubuntu` OS, you can still install from the Ettus PPA or select a version to install from source.
|
||||
* In case of PPA installation, you do nothing special, the script will install the latest version available on the PPA.
|
||||
- `./build_oai -I -w USRP`
|
||||
* In case of a installation from source, you do as followed:
|
||||
|
||||
```bash
|
||||
export BUILD_UHD_FROM_SOURCE=True
|
||||
@@ -103,49 +110,15 @@ export UHD_VERSION=3.15.0.0
|
||||
|
||||
The `UHD_VERSION` env variable `SHALL` be a valid tag (minus `v`) from the `https://github.com/EttusResearch/uhd.git` repository.
|
||||
|
||||
## Issue when building `nasmeh` module ##
|
||||
**CAUTION: Note that if you are using the OAI eNB in TDD mode with B2xx boards, a patch is mandatory.**
|
||||
|
||||
A lot of users and contributors have faced the issue: `nasmesh` module does not build.
|
||||
Starting this commit, the patch is applied automatically in our automated builds.
|
||||
|
||||
The reason is that the linux headers are not properly installed. For example:
|
||||
See:
|
||||
|
||||
```bash
|
||||
$ uname -r
|
||||
4.4.0-145-lowlatency
|
||||
$ dpkg --list | grep 4.4.0-145-lowlatency | grep headers
|
||||
ii linux-headers-4.4.0-145-lowlatency 4.4.0-145.171
|
||||
```
|
||||
|
||||
In my example it is properly installed.
|
||||
|
||||
Check on your environment:
|
||||
|
||||
```bash
|
||||
$ uname -r
|
||||
your-version
|
||||
$ dpkg --list | grep your-version | grep headers
|
||||
$
|
||||
```
|
||||
|
||||
Install it:
|
||||
|
||||
```bash
|
||||
$ sudo apt-get install --yes linux-headers-your-version
|
||||
```
|
||||
|
||||
On CentOS or RedHat Entreprise Linux:
|
||||
|
||||
```bash
|
||||
$ uname -r
|
||||
3.10.0-1062.9.1.rt56.1033.el7.x86_64
|
||||
$ yum list installed | grep kernel | grep devel
|
||||
kernel-devel.x86_64 3.10.0-1062.9.1.el7 @rhel-7-server-rpms
|
||||
kernel-rt-devel.x86_64 3.10.0-1062.9.1.rt56.1033.el7
|
||||
```
|
||||
|
||||
If your kernel is generic, install `kernel-devel` package: `sudo yum install kernel-devel`
|
||||
|
||||
In most case, your kernel is real-time. Install `kernel-rt-devel` package: `sudo yum install kernel-rt-devel`
|
||||
* `cmake_targets/tools/uhd-3.15-tdd-patch.diff`
|
||||
* `cmake_targets/tools/uhd-4.x-tdd-patch.diff`
|
||||
* `cmake_targets/tools/build_helper` --> function `install_usrp_uhd_driver_from_source`
|
||||
|
||||
# Building Optional Binaries
|
||||
|
||||
|
||||
+3
-3
@@ -169,15 +169,15 @@ gNB on machine 1:
|
||||
|
||||
UE on machine 2:
|
||||
|
||||
`sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 -s 516 --sa`
|
||||
`sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --sa`
|
||||
|
||||
With the RF simulator (on the same machine):
|
||||
|
||||
`sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --rfsim --sa`
|
||||
|
||||
`sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 -s 516 --rfsim --sa`
|
||||
`sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --rfsim --sa`
|
||||
|
||||
where `-r` sets the transmission bandwidth configuration in terms of RBs, `-C` sets the downlink carrier frequency and `-s` sets the SSB start subcarrier.
|
||||
where `-r` sets the transmission bandwidth configuration in terms of RBs, `-C` sets the downlink carrier frequency and `--ssb` sets the SSB start subcarrier.
|
||||
|
||||
Additionally, at UE side `--uecap_file` option can be used to pass the UE Capabilities input file (path location + filename), e.g. `--uecap_file ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap.xml`
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ static int DEFBANDS[] = {7};
|
||||
static int DEFENBS[] = {0};
|
||||
static int DEFBFW[] = {0x00007fff};
|
||||
|
||||
static int DEFRUTPCORES[] = {2,4,6,8};
|
||||
THREAD_STRUCT thread_struct;
|
||||
|
||||
pthread_cond_t sync_cond;
|
||||
|
||||
+20
-2
@@ -38,6 +38,7 @@
|
||||
#include "assertions.h"
|
||||
#include <common/utils/LOG/log.h>
|
||||
#include <common/utils/system.h>
|
||||
#include "rt_profiling.h"
|
||||
|
||||
#include "PHY/types.h"
|
||||
|
||||
@@ -59,7 +60,6 @@
|
||||
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||
|
||||
#include "PHY/LTE_TRANSPORT/if4_tools.h"
|
||||
#include "PHY/LTE_TRANSPORT/if5_tools.h"
|
||||
|
||||
#include "PHY/phy_extern.h"
|
||||
|
||||
@@ -115,10 +115,17 @@ void tx_func(void *param) {
|
||||
int frame_tx = info->frame;
|
||||
int slot_tx = info->slot;
|
||||
|
||||
int absslot_tx = info->timestamp_tx/info->gNB->frame_parms.get_samples_per_slot(slot_tx,&info->gNB->frame_parms);
|
||||
int absslot_rx = absslot_tx-info->gNB->RU_list[0]->sl_ahead;
|
||||
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.start_L1_TX[rt_prof_idx]);
|
||||
phy_procedures_gNB_TX(info,
|
||||
frame_tx,
|
||||
slot_tx,
|
||||
1);
|
||||
clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.return_L1_TX[rt_prof_idx]);
|
||||
|
||||
}
|
||||
|
||||
void rx_func(void *param) {
|
||||
@@ -130,6 +137,11 @@ void rx_func(void *param) {
|
||||
int slot_tx = info->slot_tx;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
|
||||
int absslot_tx = info->timestamp_tx/gNB->frame_parms.get_samples_per_slot(slot_rx,&gNB->frame_parms);
|
||||
int absslot_rx = absslot_tx - gNB->RU_list[0]->sl_ahead;
|
||||
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.start_L1_RX[rt_prof_idx]);
|
||||
start_meas(&softmodem_stats_rxtx_sf);
|
||||
|
||||
// *******************************************************************
|
||||
@@ -228,6 +240,7 @@ void rx_func(void *param) {
|
||||
|
||||
stop_meas( &softmodem_stats_rxtx_sf );
|
||||
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
|
||||
clock_gettime(CLOCK_MONOTONIC,&info->gNB->rt_L1_profiling.return_L1_RX[rt_prof_idx]);
|
||||
|
||||
// Call the scheduler
|
||||
start_meas(&gNB->ul_indication_stats);
|
||||
@@ -383,6 +396,8 @@ void *tx_reorder_thread(void* param) {
|
||||
AssertFatal(resL1Reserve != NULL, "pullTpool() did not return start message in %s\n", __func__);
|
||||
int next_tx_slot=((processingData_L1tx_t *)NotifiedFifoData(resL1Reserve))->slot;
|
||||
|
||||
LOG_I(PHY,"tx_reorder_thread started\n");
|
||||
|
||||
while (!oai_exit) {
|
||||
notifiedFIFO_elt_t *resL1;
|
||||
if (resL1Reserve) {
|
||||
@@ -419,6 +434,7 @@ void *tx_reorder_thread(void* param) {
|
||||
pushNotifiedFIFO(&gNB->L1_tx_free, resL1);
|
||||
if (resL1==resL1Reserve)
|
||||
resL1Reserve=NULL;
|
||||
LOG_D(PHY,"gNB: %d.%d : calling RU TX function\n",syncMsgL1->frame,syncMsgL1->slot);
|
||||
ru_tx_func((void*)&syncMsgRU);
|
||||
}
|
||||
return(NULL);
|
||||
@@ -457,7 +473,9 @@ void init_gNB_Tpool(int inst) {
|
||||
if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT))
|
||||
threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW);
|
||||
|
||||
threadCreate(&proc->pthread_tx_reorder, tx_reorder_thread, (void *)gNB, "thread_tx_reorder", -1, OAI_PRIORITY_RT_MAX);
|
||||
LOG_I(PHY,"Creating thread for TX reordering and dispatching to RU\n");
|
||||
threadCreate(&proc->pthread_tx_reorder, tx_reorder_thread, (void *)gNB, "thread_tx_reorder",
|
||||
gNB->RU_list[0] ? gNB->RU_list[0]->tpcores[1] : -1, OAI_PRIORITY_RT_MAX);
|
||||
|
||||
}
|
||||
|
||||
|
||||
+125
-72
@@ -35,12 +35,12 @@
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/system.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "rt_profiling.h"
|
||||
|
||||
#include "../../ARCH/COMMON/common_lib.h"
|
||||
#include "../../ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
|
||||
|
||||
#include "PHY/LTE_TRANSPORT/if4_tools.h"
|
||||
#include "PHY/LTE_TRANSPORT/if5_tools.h"
|
||||
|
||||
#include "PHY/types.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
@@ -59,11 +59,12 @@
|
||||
unsigned short config_frames[4] = {2,9,11,13};
|
||||
#endif
|
||||
|
||||
|
||||
/* these variables have to be defined before including ENB_APP/enb_paramdef.h and GNB_APP/gnb_paramdef.h */
|
||||
static int DEFBANDS[] = {7};
|
||||
static int DEFENBS[] = {0};
|
||||
static int DEFBFW[] = {0x00007fff};
|
||||
|
||||
static int DEFRUTPCORES[] = {-1,-1,-1,-1};
|
||||
//static int DEFNRBANDS[] = {7};
|
||||
//static int DEFGNBS[] = {0};
|
||||
|
||||
@@ -276,8 +277,21 @@ int connect_rau(RU_t *ru) {
|
||||
// southbound IF5 fronthaul for 16-bit OAI format
|
||||
void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) {
|
||||
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
|
||||
int offset = ru->nr_frame_parms->get_samples_slot_timestamp(slot,ru->nr_frame_parms,0);
|
||||
void *buffs[ru->nb_tx];
|
||||
for (int aid=0;aid<ru->nb_tx;aid++) buffs[aid] = (void*)&ru->common.txdata[aid][offset];
|
||||
struct timespec txmeas;
|
||||
clock_gettime(CLOCK_MONOTONIC, &txmeas);
|
||||
LOG_D(PHY,"IF5 TX %d.%d, TS %llu, buffs[0] %p, buffs[1] %p ener0 %f dB, tx start %d\n",frame,slot,(unsigned long long)timestamp,buffs[0],buffs[1],
|
||||
10*log10((double)signal_energy(buffs[0],ru->nr_frame_parms->get_samples_per_slot(slot,ru->nr_frame_parms))),(int)txmeas.tv_nsec);
|
||||
ru->ifdevice.trx_write_func2(&ru->ifdevice,
|
||||
timestamp,
|
||||
buffs,
|
||||
0,
|
||||
ru->nr_frame_parms->get_samples_per_slot(slot,ru->nr_frame_parms),
|
||||
0,
|
||||
ru->nb_tx);
|
||||
|
||||
send_IF5(ru, timestamp, slot, &ru->seqno, IF5_RRH_GW_DL);
|
||||
}
|
||||
|
||||
// southbound IF4p5 fronthaul
|
||||
@@ -297,19 +311,19 @@ void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) {
|
||||
|
||||
// Synchronous if5 from south
|
||||
|
||||
uint64_t ts_rx[20];
|
||||
void fh_if5_south_in(RU_t *ru,
|
||||
int *frame,
|
||||
int *tti) {
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
recv_IF5(ru, &proc->timestamp_rx, *tti, IF5_RRH_GW_UL);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 );
|
||||
start_meas(&ru->rx_fhaul);
|
||||
|
||||
ru->ifdevice.trx_read_func2(&ru->ifdevice,&proc->timestamp_rx,NULL,fp->get_samples_per_slot(*tti,fp));
|
||||
if (proc->first_rx == 1) ru->ts_offset = proc->timestamp_rx;
|
||||
proc->frame_rx = ((proc->timestamp_rx-ru->ts_offset) / (fp->samples_per_subframe*10))&1023;
|
||||
proc->tti_rx = fp->get_slot_from_timestamp(proc->timestamp_rx-ru->ts_offset,fp);
|
||||
//(idx_sf * fp->slots_per_subframe + (int)round((float)(proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame);
|
||||
ts_rx[*tti] = proc->timestamp_rx;
|
||||
LOG_D(PHY,"IF5 %d.%d => RX %d.%d first_rx %d\n",*frame,*tti,proc->frame_rx,proc->tti_rx,proc->first_rx);
|
||||
|
||||
|
||||
if (proc->first_rx == 0) {
|
||||
if (proc->tti_rx != *tti) {
|
||||
@@ -327,7 +341,15 @@ void fh_if5_south_in(RU_t *ru,
|
||||
*tti = proc->tti_rx;
|
||||
}
|
||||
|
||||
stop_meas(&ru->rx_fhaul);
|
||||
struct timespec rxmeas;
|
||||
clock_gettime(CLOCK_MONOTONIC, &rxmeas);
|
||||
double fhtime = ru->rx_fhaul.p_time/(cpu_freq_GHz*1000.0);
|
||||
if (fhtime > 800) LOG_W(PHY,"IF5 %d.%d => RX %d.%d first_rx %d: time %f, rxstart %d\n",*frame,*tti,proc->frame_rx,proc->tti_rx,proc->first_rx,ru->rx_fhaul.p_time/(cpu_freq_GHz*1000.0),(int)rxmeas.tv_nsec);
|
||||
else LOG_D(PHY,"IF5 %d.%d => RX %d.%d first_rx %d: time %f, rxstart %d\n",*frame,*tti,proc->frame_rx,proc->tti_rx,proc->first_rx,ru->rx_fhaul.p_time/(cpu_freq_GHz*1000.0),(int)rxmeas.tv_nsec);
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 );
|
||||
|
||||
}
|
||||
|
||||
// Synchronous if4p5 from south
|
||||
@@ -476,7 +498,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
int tti_tx,frame_tx;
|
||||
openair0_timestamp timestamp_tx;
|
||||
recv_IF5(ru, ×tamp_tx, *slot, IF5_RRH_GW_DL);
|
||||
AssertFatal(1==0,"Shouldn't get here\n");
|
||||
// printf("Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx);
|
||||
frame_tx = (timestamp_tx / (fp->samples_per_subframe*10))&1023;
|
||||
uint32_t idx_sf = timestamp_tx / fp->samples_per_subframe;
|
||||
@@ -553,11 +575,9 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
|
||||
}
|
||||
|
||||
void fh_if5_north_out(RU_t *ru) {
|
||||
RU_proc_t *proc=&ru->proc;
|
||||
uint8_t seqno=0;
|
||||
/// **** send_IF5 of rxdata to BBU **** ///
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
|
||||
send_IF5(ru, proc->timestamp_rx, proc->tti_rx, &seqno, IF5_RRH_GW_UL);
|
||||
AssertFatal(1==0,"Shouldn't get here\n");
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 );
|
||||
}
|
||||
|
||||
@@ -827,6 +847,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
|
||||
cfg->num_rb_dl=N_RB;
|
||||
cfg->tx_num_channels=ru->nb_tx;
|
||||
cfg->rx_num_channels=ru->nb_rx;
|
||||
LOG_I(PHY,"Setting RF config for N_RB %d, NB_RX %d, NB_TX %d\n",cfg->num_rb_dl,cfg->rx_num_channels,cfg->tx_num_channels);
|
||||
|
||||
for (i=0; i<ru->nb_tx; i++) {
|
||||
if (ru->if_frequency == 0) {
|
||||
@@ -957,17 +978,17 @@ void *ru_stats_thread(void *param) {
|
||||
sleep(1);
|
||||
|
||||
if (opp_enabled == 1) {
|
||||
if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL);
|
||||
if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx (all ports)",NULL,NULL);
|
||||
|
||||
if (ru->feptx_ofdm) {
|
||||
print_meas(&ru->precoding_stats,"feptx_prec",NULL,NULL);
|
||||
print_meas(&ru->precoding_stats,(ru->half_slot_parallelization==0)?"feptx_prec (per port)":"feptx_prec (per port, half_slot)",NULL,NULL);
|
||||
print_meas(&ru->ofdm_mod_stats,(ru->half_slot_parallelization==0)?"feptx_ofdm (per port)":"feptx_ofdm (per port, half_slot)",NULL,NULL);
|
||||
print_meas(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL);
|
||||
print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL);
|
||||
print_meas(&ru->ofdm_total_stats,"feptx_total",NULL,NULL);
|
||||
}
|
||||
|
||||
print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL);
|
||||
print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL);
|
||||
if (ru->if_south == REMOTE_IF5) print_meas(&ru->ifdevice.tx_fhaul,"tx_fhaul (IF5)",NULL,NULL);
|
||||
else print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL);
|
||||
|
||||
if (ru->fh_north_out) {
|
||||
print_meas(&ru->compression,"compression",NULL,NULL);
|
||||
@@ -987,7 +1008,13 @@ void ru_tx_func(void *param) {
|
||||
int slot_tx = info->slot_tx;
|
||||
int print_frame = 8;
|
||||
char filename[40];
|
||||
|
||||
|
||||
// note that this will break for 60/120 kHz, to be handled
|
||||
int absslot_tx = info->timestamp_tx/fp->get_samples_per_slot(slot_tx,fp);
|
||||
int absslot_rx = absslot_tx-ru->sl_ahead;
|
||||
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
|
||||
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.start_RU_TX[rt_prof_idx]);
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,slot_tx);
|
||||
|
||||
@@ -1030,6 +1057,11 @@ void ru_tx_func(void *param) {
|
||||
}//for (i=0; i<ru->nb_tx; i++)
|
||||
}//if(frame_tx == print_frame)
|
||||
}//else emulate_rf
|
||||
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_TX[rt_prof_idx]);
|
||||
struct timespec *t0=&ru->rt_ru_profiling.start_RU_TX[rt_prof_idx];
|
||||
struct timespec *t1=&ru->rt_ru_profiling.return_RU_TX[rt_prof_idx];
|
||||
|
||||
LOG_D(PHY,"rt_prof_idx %d : RU_TX time %d\n",rt_prof_idx,(int)(1e9 * (t1->tv_sec - t0->tv_sec) + (t1->tv_nsec-t0->tv_nsec)));
|
||||
}
|
||||
|
||||
void *ru_thread( void *param ) {
|
||||
@@ -1054,9 +1086,9 @@ void *ru_thread( void *param ) {
|
||||
memcpy((void *)&ru->config,(void *)&RC.gNB[0]->gNB_config,sizeof(ru->config));
|
||||
|
||||
if(emulate_rf) {
|
||||
fill_rf_config(ru,ru->rf_config_file);
|
||||
nr_init_frame_parms(&ru->config, fp);
|
||||
nr_dump_frame_parms(fp);
|
||||
fill_rf_config(ru,ru->rf_config_file);
|
||||
nr_phy_init_RU(ru);
|
||||
|
||||
if (setup_RU_buffers(ru)!=0) {
|
||||
@@ -1071,7 +1103,7 @@ void *ru_thread( void *param ) {
|
||||
|
||||
// Start IF device if any
|
||||
if (ru->nr_start_if) {
|
||||
LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx);
|
||||
LOG_I(PHY,"Starting IF interface for RU %d, nb_rx %d\n",ru->idx,ru->nb_rx);
|
||||
AssertFatal(ru->nr_start_if(ru,NULL) == 0, "Could not start the IF device\n");
|
||||
|
||||
if (ru->has_ctrl_prt > 0) {
|
||||
@@ -1111,7 +1143,7 @@ void *ru_thread( void *param ) {
|
||||
else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
|
||||
} else LOG_I(PHY,"RU %d no rf device\n",ru->idx);
|
||||
|
||||
LOG_I(PHY,"RU %d RF started\n",ru->idx);
|
||||
LOG_I(PHY,"RU %d RF started opp_enabled %d\n",ru->idx,opp_enabled);
|
||||
// start trx write thread
|
||||
if(usrp_tx_thread == 1) {
|
||||
if (ru->start_write_thread) {
|
||||
@@ -1166,6 +1198,7 @@ void *ru_thread( void *param ) {
|
||||
if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot);
|
||||
else AssertFatal(1==0, "No fronthaul interface at south port");
|
||||
|
||||
|
||||
if (initial_wait == 1 && proc->frame_rx < 300 && ru->fh_south_in == rx_rf) {
|
||||
if (proc->frame_rx>0 && ((proc->frame_rx % 100) == 0) && proc->tti_rx==0) {
|
||||
LOG_I(PHY,"delay processing to let RX stream settle, frame %d (trials %d)\n",proc->frame_rx,ru->rx_fhaul.trials);
|
||||
@@ -1178,13 +1211,20 @@ void *ru_thread( void *param ) {
|
||||
initial_wait=0;
|
||||
opp_enabled = opp_enabled0;
|
||||
}
|
||||
if (initial_wait == 0 && ru->rx_fhaul.trials > 1000) reset_meas(&ru->rx_fhaul);
|
||||
if (initial_wait == 0 && ru->rx_fhaul.trials > 1000) {
|
||||
reset_meas(&ru->rx_fhaul);
|
||||
/*if (ru->if_south == REMOTE_IF5) reset_meas(&ru->ifdevice.tx_fhaul);
|
||||
else*/ reset_meas(&ru->tx_fhaul);
|
||||
}
|
||||
proc->timestamp_tx = proc->timestamp_rx;
|
||||
int sl=proc->tti_tx;
|
||||
for (int slidx=0;slidx<ru->sl_ahead;slidx++)
|
||||
proc->timestamp_tx += fp->get_samples_per_slot((sl+slidx)%fp->slots_per_frame,fp);
|
||||
proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame-1-(ru->sl_ahead))) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
|
||||
proc->tti_tx = (proc->tti_rx + ru->sl_ahead)%fp->slots_per_frame;
|
||||
int absslot_rx = proc->timestamp_rx/fp->get_samples_per_slot(proc->tti_rx,fp);
|
||||
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
|
||||
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_south_in[rt_prof_idx]);
|
||||
LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0]:[RX:%d%d TX(SFN):%d]\n",
|
||||
frame,slot,
|
||||
proc->frame_rx,proc->tti_rx,
|
||||
@@ -1200,15 +1240,9 @@ void *ru_thread( void *param ) {
|
||||
if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
|
||||
if (ru->feprx) {
|
||||
ru->feprx(ru,proc->tti_rx);
|
||||
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_feprx[rt_prof_idx]);
|
||||
//LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1);
|
||||
LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx);
|
||||
/*
|
||||
LOG_D(PHY,"Copying rxdataF from RU to gNB\n");
|
||||
|
||||
for (int aa=0; aa<ru->nb_rx; aa++)
|
||||
memcpy((void *)RC.gNB[0]->common_vars.rxdataF[aa],
|
||||
(void *)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
|
||||
*/
|
||||
if (IS_SOFTMODEM_DOSCOPE && RC.gNB[0]->scopeData)
|
||||
((scopeData_t *)RC.gNB[0]->scopeData)->slotFunc(ru->common.rxdataF[0],proc->tti_rx, RC.gNB[0]->scopeData);
|
||||
|
||||
@@ -1216,24 +1250,12 @@ void *ru_thread( void *param ) {
|
||||
int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
|
||||
uint8_t prachStartSymbol,N_dur;
|
||||
if (prach_id>=0) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 );
|
||||
|
||||
T(T_GNB_PHY_PRACH_INPUT_SIGNAL, T_INT(proc->frame_rx), T_INT(proc->tti_rx), T_INT(0),
|
||||
T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx-1,fp,0)]/*-ru->N_TA_offset*/, fp->get_samples_per_slot(proc->tti_rx,fp)*4*2));
|
||||
N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt);
|
||||
|
||||
/*
|
||||
get_nr_prach_info_from_index(ru->config.prach_config.prach_ConfigurationIndex.value,
|
||||
proc->frame_rx,proc->tti_rx,
|
||||
ru->config.carrier_config.dl_frequency.value,
|
||||
fp->numerology_index,
|
||||
fp->frame_type,
|
||||
&format,
|
||||
&start_symbol,
|
||||
&N_t_slot,
|
||||
&N_dur,
|
||||
&RA_sfn_index,
|
||||
&N_RA_slot,
|
||||
&config_period);
|
||||
*/
|
||||
for (int prach_oc = 0; prach_oc<ru->prach_list[prach_id].num_prach_ocas; prach_oc++) {
|
||||
prachStartSymbol = ru->prach_list[prach_id].prachStartSymbol+prach_oc*N_dur;
|
||||
//comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}.
|
||||
@@ -1244,11 +1266,16 @@ void *ru_thread( void *param ) {
|
||||
prach_oc,
|
||||
proc->frame_rx,proc->tti_rx);
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_prachrx[rt_prof_idx]);
|
||||
free_nr_ru_prach_entry(ru,prach_id);
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );
|
||||
} // end if (prach_id > 0)
|
||||
} // end if (ru->feprx)
|
||||
else {
|
||||
memset(&ru->rt_ru_profiling.return_RU_feprx[rt_prof_idx],0,sizeof(struct timespec));
|
||||
memset(&ru->rt_ru_profiling.return_RU_prachrx[rt_prof_idx],0,sizeof(struct timespec));
|
||||
}
|
||||
}
|
||||
} // end if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
|
||||
|
||||
// At this point, all information for subframe has been received on FH interface
|
||||
res = pullTpool(&gNB->resp_L1, &gNB->threadPool);
|
||||
@@ -1283,6 +1310,9 @@ int start_streaming(RU_t *ru) {
|
||||
}
|
||||
|
||||
int nr_start_if(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB) {
|
||||
for (int i=0;i<ru->nb_rx;i++) ru->openair0_cfg.rxbase[i] = ru->common.rxdata[i];
|
||||
ru->openair0_cfg.rxsize = ru->nr_frame_parms->samples_per_subframe*10;
|
||||
reset_meas(&ru->ifdevice.tx_fhaul);
|
||||
return(ru->ifdevice.trx_start_func(&ru->ifdevice));
|
||||
}
|
||||
|
||||
@@ -1312,21 +1342,18 @@ void init_RU_proc(RU_t *ru) {
|
||||
proc->frame_offset = 0;
|
||||
proc->num_slaves = 0;
|
||||
proc->frame_tx_unwrap = 0;
|
||||
proc->feptx_mask = 0;
|
||||
|
||||
for (i=0; i<10; i++) proc->symbol_mask[i]=0;
|
||||
|
||||
pthread_mutex_init( &proc->mutex_emulateRF,NULL);
|
||||
pthread_cond_init( &proc->cond_emulateRF, NULL);
|
||||
threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "thread_FH", -1, OAI_PRIORITY_RT_MAX );
|
||||
threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "ru_thread", ru->tpcores[0], OAI_PRIORITY_RT_MAX );
|
||||
|
||||
if(emulate_rf)
|
||||
threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT );
|
||||
|
||||
if (opp_enabled == 1)
|
||||
threadCreate( &ru->ru_stats_thread, ru_stats_thread, (void *)ru,"ru_stats", -1, OAI_PRIORITY_RT );
|
||||
if (get_thread_worker_conf() == WORKER_ENABLE) {
|
||||
if (ru->feprx) nr_init_feprx_thread(ru);
|
||||
|
||||
if (ru->feptx_ofdm) nr_init_feptx_thread(ru);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1340,17 +1367,16 @@ void kill_NR_RU_proc(int inst) {
|
||||
* mutex_fep/cond_fep. Thus, we unlocked above for pthread_FH above and do
|
||||
* the same for FEP thread below again (using broadcast() to ensure both
|
||||
* threads get the signal). This one will also destroy the mutex and cond. */
|
||||
pthread_mutex_lock(&proc->mutex_fep);
|
||||
proc->instance_cnt_fep = 0;
|
||||
pthread_cond_broadcast(&proc->cond_fep);
|
||||
pthread_mutex_unlock( &proc->mutex_fep );
|
||||
pthread_mutex_lock(&proc->mutex_fep[0]);
|
||||
proc->instance_cnt_fep[0] = 0;
|
||||
pthread_cond_broadcast(&proc->cond_fep[0]);
|
||||
pthread_mutex_unlock( &proc->mutex_fep[0] );
|
||||
pthread_join(proc->pthread_FH, NULL);
|
||||
|
||||
if (ru->feprx)
|
||||
nr_kill_feprx_thread(ru);
|
||||
|
||||
if (ru->feptx_ofdm)
|
||||
nr_kill_feptx_thread(ru);
|
||||
if (opp_enabled) {
|
||||
LOG_D(PHY, "Joining ru_stats_thread\n");
|
||||
pthread_join(ru->ru_stats_thread, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) {
|
||||
@@ -1554,8 +1580,8 @@ void set_function_spec_param(RU_t *ru) {
|
||||
ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception
|
||||
ru->fh_south_out = tx_rf; // send output to RF
|
||||
ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously
|
||||
ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs
|
||||
ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft only (no precoding in RRU)
|
||||
ru->feprx = nr_fep_tp; // this is frequency-shift + DFTs
|
||||
ru->feptx_ofdm = nr_feptx_tp; // this is fep with idft only (no precoding in RRU)
|
||||
ru->feptx_prec = NULL;
|
||||
ru->nr_start_if = nr_start_if; // need to start the if interface for if4p5
|
||||
ru->ifdevice.host_type = RRU_HOST;
|
||||
@@ -1575,9 +1601,9 @@ void set_function_spec_param(RU_t *ru) {
|
||||
malloc_IF4p5_buffer(ru);
|
||||
} else if (ru->function == gNodeB_3GPP) {
|
||||
ru->do_prach = 0; // no prach processing in RU
|
||||
ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs
|
||||
ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft and precoding
|
||||
ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // this is fep with idft and precoding
|
||||
ru->feprx = nr_fep_tp; // this is frequency-shift + DFTs
|
||||
ru->feptx_ofdm = nr_feptx_tp; // this is fep with idft and precoding
|
||||
ru->feptx_prec = NULL;
|
||||
ru->fh_north_in = NULL; // no incoming fronthaul from north
|
||||
ru->fh_north_out = NULL; // no outgoing fronthaul to north
|
||||
ru->nr_start_if = NULL; // no if interface
|
||||
@@ -1606,11 +1632,12 @@ void set_function_spec_param(RU_t *ru) {
|
||||
|
||||
case REMOTE_IF5: // the remote unit is IF5 RRU
|
||||
ru->do_prach = 0;
|
||||
ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // this is frequency-shift + DFTs
|
||||
ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // need to do transmit Precoding + IDFTs
|
||||
ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // need to do transmit Precoding + IDFTs
|
||||
ru->txfh_in_fep = 0;
|
||||
ru->feprx = nr_fep_tp; // this is frequency-shift + DFTs
|
||||
ru->feptx_prec = NULL; // need to do transmit Precoding + IDFTs
|
||||
ru->feptx_ofdm = nr_feptx_tp; // need to do transmit Precoding + IDFTs
|
||||
ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception
|
||||
ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission
|
||||
ru->fh_south_out = (ru->txfh_in_fep>0) ? NULL : fh_if5_south_out; // synchronous IF5 transmission
|
||||
ru->fh_south_asynch_in = NULL; // no asynchronous UL
|
||||
ru->start_rf = ru->eth_params.transp_preference == ETH_UDP_IF5_ECPRI_MODE ? start_streaming : NULL;
|
||||
ru->stop_rf = NULL;
|
||||
@@ -1619,6 +1646,8 @@ void set_function_spec_param(RU_t *ru) {
|
||||
ru->ifdevice.host_type = RAU_HOST;
|
||||
ru->ifdevice.eth_params = &ru->eth_params;
|
||||
ru->ifdevice.configure_rru = configure_ru;
|
||||
|
||||
printf("starting transport : rx_num_antennas %d, tx_num_antennas %d\n",ru->openair0_cfg.rx_num_channels,ru->openair0_cfg.tx_num_channels);
|
||||
ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params);
|
||||
printf("openair0_transport_init returns %d for ru_id %u\n", ret, ru->idx);
|
||||
|
||||
@@ -1632,7 +1661,7 @@ void set_function_spec_param(RU_t *ru) {
|
||||
case REMOTE_IF4p5:
|
||||
ru->do_prach = 0;
|
||||
ru->feprx = NULL; // DFTs
|
||||
ru->feptx_prec = nr_feptx_prec; // Precoding operation
|
||||
ru->feptx_prec = NULL; // Precoding operation
|
||||
ru->feptx_ofdm = NULL; // no OFDM mod
|
||||
ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception
|
||||
ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission
|
||||
@@ -1709,7 +1738,6 @@ void init_NR_RU(char *rf_config_file) {
|
||||
ru->gNB_list[0] = RC.gNB[0];
|
||||
ru->num_gNB=1;
|
||||
//
|
||||
// DJP - feptx_prec() / feptx_ofdm() parses the gNB_list (based on num_gNB) and copies the txdata_F to txdata in RU
|
||||
//
|
||||
} else {
|
||||
LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__);
|
||||
@@ -1739,11 +1767,29 @@ void init_NR_RU(char *rf_config_file) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ru->openair0_cfg.rx_num_channels = ru->nb_rx;
|
||||
ru->openair0_cfg.tx_num_channels = ru->nb_tx;
|
||||
//LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],NB_timing[ru->if_timing],ru->function);
|
||||
set_function_spec_param(ru);
|
||||
LOG_I(PHY,"Starting ru_thread %d\n",ru_id);
|
||||
init_RU_proc(ru);
|
||||
int threadCnt = ru->num_tpcores;
|
||||
if (threadCnt < 2) LOG_E(PHY,"Number of threads for gNB should be more than 1. Allocated only %d\n",threadCnt);
|
||||
else LOG_I(PHY,"RU Thread pool size %d\n",threadCnt);
|
||||
char pool[80];
|
||||
int s_offset = sprintf(pool,"%d",ru->tpcores[0]);
|
||||
for (int icpu=1; icpu<threadCnt; icpu++) {
|
||||
s_offset+=sprintf(pool+s_offset,",%d",ru->tpcores[icpu]);
|
||||
}
|
||||
LOG_I(PHY,"RU thread-pool core string %s\n",pool);
|
||||
ru->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
|
||||
initTpool(pool, ru->threadPool, cpumeas(CPUMEAS_GETSTATE));
|
||||
// FEP RX result FIFO
|
||||
ru->respfeprx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(ru->respfeprx);
|
||||
// FEP TX result FIFO
|
||||
ru->respfeptx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(ru->respfeptx);
|
||||
} // for ru_id
|
||||
|
||||
// sleep(1);
|
||||
@@ -1918,6 +1964,13 @@ static void NRRCconfig_RU(void) {
|
||||
RC.ru[j]->openair0_cfg.nr_band = RC.ru[j]->band[0];
|
||||
RC.ru[j]->openair0_cfg.nr_scs_for_raster = *(RUParamList.paramarray[j][RU_NR_SCS_FOR_RASTER].iptr);
|
||||
printf("[RU %d] Setting nr_flag %d, nr_band %d, nr_scs_for_raster %d\n",j,RC.ru[j]->openair0_cfg.nr_flag,RC.ru[j]->openair0_cfg.nr_band,RC.ru[j]->openair0_cfg.nr_scs_for_raster);
|
||||
RC.ru[j]->openair0_cfg.rxfh_cores[0] = *(RUParamList.paramarray[j][RU_RXFH_CORE_ID].iptr);
|
||||
RC.ru[j]->openair0_cfg.txfh_cores[0] = *(RUParamList.paramarray[j][RU_TXFH_CORE_ID].iptr);
|
||||
RC.ru[j]->num_tpcores = *(RUParamList.paramarray[j][RU_NUM_TP_CORES].iptr);
|
||||
RC.ru[j]->half_slot_parallelization = *(RUParamList.paramarray[j][RU_HALF_SLOT_PARALLELIZATION].iptr);
|
||||
printf("[RU %d] Setting half-slot parallelization to %d\n",j,RC.ru[j]->half_slot_parallelization);
|
||||
AssertFatal(RC.ru[j]->num_tpcores <= RUParamList.paramarray[j][RU_TP_CORES].numelt, "Number of TP cores should be <=16\n");
|
||||
for (i=0; i<RC.ru[j]->num_tpcores; i++) RC.ru[j]->tpcores[i] = RUParamList.paramarray[j][RU_TP_CORES].iptr[i];
|
||||
if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) {
|
||||
RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt;
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
{"D" , CONFIG_HLP_DLBM_PHYTEST,0, u64ptr:&dlsch_slot_bitmap, defintval:0, TYPE_UINT64, 0}, \
|
||||
{"U" , CONFIG_HLP_ULBM_PHYTEST,0, u64ptr:&ulsch_slot_bitmap, defintval:0, TYPE_UINT64, 0}, \
|
||||
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
|
||||
{"ldpc-offload-enable", CONFIG_HLP_LDPC_OFFLOAD, 0, iptr:&ldpc_offload_flag, defstrval:0, TYPE_INT, 0}, \
|
||||
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, strptr:&uecap_file, defstrval:"./uecap.xml", TYPE_STRING, 0}, \
|
||||
{"ldpc-offload-enable", CONFIG_HLP_LDPC_OFFLOAD, 0, iptr:&ldpc_offload_flag, defstrval:0, TYPE_INT, 0}, \
|
||||
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, strptr:&uecap_file, defstrval:"./uecap.xml", TYPE_STRING, 0}, \
|
||||
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
{"A" , CONFIG_HLP_TADV, 0, iptr:&(UE->timing_advance), defintval:0, TYPE_INT, 0}, \
|
||||
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, u8ptr:&(fp->threequarter_fs), defintval:0, TYPE_UINT8, 0}, \
|
||||
{"r" , CONFIG_HLP_PRB_SA, 0, iptr:&(fp->N_RB_DL), defintval:106, TYPE_UINT, 0}, \
|
||||
{"s" , CONFIG_HLP_SSC, 0, u16ptr:&(fp->ssb_start_subcarrier), defintval:516, TYPE_UINT16,0}, \
|
||||
{"ssb", CONFIG_HLP_SSC, 0, u16ptr:&(fp->ssb_start_subcarrier), defintval:516, TYPE_UINT16,0}, \
|
||||
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
|
||||
{"if_freq" , CONFIG_HLP_IF_FREQ, 0, u64ptr:&(UE->if_freq), defuintval:0, TYPE_UINT64,0}, \
|
||||
{"if_freq_off" , CONFIG_HLP_IF_FREQ_OFF, 0, iptr:&(UE->if_freq_off), defuintval:0, TYPE_INT, 0}, \
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file time_profiling.h
|
||||
* \brief Definitions for proflling real-time scheduling
|
||||
* \author
|
||||
* \date 2022
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifndef TIME_PROFILING_H
|
||||
#define TIME_PROFILING_H
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// depth of trace in slots
|
||||
#define RT_PROF_DEPTH 100
|
||||
typedef struct {
|
||||
int absslot_rx[RT_PROF_DEPTH];
|
||||
struct timespec return_RU_south_in[RT_PROF_DEPTH];
|
||||
struct timespec return_RU_feprx[RT_PROF_DEPTH];
|
||||
struct timespec return_RU_prachrx[RT_PROF_DEPTH];
|
||||
struct timespec return_RU_pushL1[RT_PROF_DEPTH];
|
||||
struct timespec start_RU_TX[RT_PROF_DEPTH];
|
||||
struct timespec return_RU_TX[RT_PROF_DEPTH];
|
||||
} rt_ru_profiling_t;
|
||||
|
||||
typedef struct {
|
||||
int absslot_ux[RT_PROF_DEPTH];
|
||||
struct timespec start_L1_RX[RT_PROF_DEPTH];
|
||||
struct timespec return_L1_RX[RT_PROF_DEPTH];
|
||||
struct timespec start_L1_TX[RT_PROF_DEPTH];
|
||||
struct timespec return_L1_TX[RT_PROF_DEPTH];
|
||||
struct timespec return_L1_prachrx[RT_PROF_DEPTH];
|
||||
struct timespec return_L1_puschL1[RT_PROF_DEPTH];
|
||||
} rt_L1_profiling_t;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -245,43 +245,6 @@ void *te_thread(void *param) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
int dlsch_encoding_all(PHY_VARS_eNB *eNB,
|
||||
L1_rxtx_proc_t *proc,
|
||||
unsigned char *a,
|
||||
uint8_t num_pdcch_symbols,
|
||||
LTE_eNB_DLSCH_t *dlsch,
|
||||
int frame,
|
||||
uint8_t subframe,
|
||||
time_stats_t *rm_stats,
|
||||
time_stats_t *te_stats,
|
||||
time_stats_t *te_wait_stats,
|
||||
time_stats_t *te_main_stats,
|
||||
time_stats_t *te_wakeup_stats0,
|
||||
time_stats_t *te_wakeup_stats1,
|
||||
time_stats_t *i_stats) {
|
||||
uint8_t harq_pid = dlsch->harq_ids[frame%2][subframe];
|
||||
if(harq_pid >= dlsch->Mdlharq) {
|
||||
LOG_E(PHY,"dlsch_encoding_all illegal harq_pid %d\n", harq_pid);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
LOG_D(PHY,"B %d, harq_pid %d\n",
|
||||
dlsch->harq_processes[harq_pid]->B,
|
||||
dlsch->harq_ids[frame%2][subframe]);
|
||||
|
||||
return dlsch_encoding(eNB,
|
||||
proc,
|
||||
a,
|
||||
num_pdcch_symbols,
|
||||
dlsch,
|
||||
frame,
|
||||
subframe,
|
||||
rm_stats,
|
||||
te_stats,
|
||||
i_stats);
|
||||
|
||||
}
|
||||
|
||||
static void TPencode(void * arg) {
|
||||
turboEncode_t * rdata=(turboEncode_t *) arg;
|
||||
unsigned char harq_pid = rdata->harq_pid;
|
||||
@@ -358,8 +321,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
|
||||
num_pdcch_symbols,
|
||||
frame,subframe,beamforming_mode);
|
||||
|
||||
proc->nbEncode=0;
|
||||
|
||||
int nbEncode = 0;
|
||||
|
||||
// if (hadlsch->Ndi == 1) { // this is a new packet
|
||||
if (hadlsch->round == 0) { // this is a new packet
|
||||
@@ -386,11 +348,13 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
|
||||
&hadlsch->F)<0)
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
notifiedFIFO_t respEncode;
|
||||
initNotifiedFIFO(&respEncode);
|
||||
for (int r=0, r_offset=0; r<hadlsch->C; r++) {
|
||||
|
||||
union turboReqUnion id= {.s={dlsch->rnti,frame,subframe,r,0}};
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, proc->respEncode, TPencode);
|
||||
notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, &respEncode, TPencode);
|
||||
turboEncode_t * rdata=(turboEncode_t *) NotifiedFifoData(req);
|
||||
rdata->input=hadlsch->c[r];
|
||||
rdata->Kr_bytes= ( r<hadlsch->Cminus ? hadlsch->Kminus : hadlsch->Kplus) >>3;
|
||||
@@ -404,15 +368,10 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
|
||||
rdata->round=hadlsch->round;
|
||||
rdata->r_offset=r_offset;
|
||||
rdata->G=G;
|
||||
|
||||
if ( proc->threadPool->activated ) {
|
||||
pushTpool(proc->threadPool,req);
|
||||
proc->nbEncode++;
|
||||
} else {
|
||||
TPencode(rdata);
|
||||
delNotifiedFIFO_elt(req);
|
||||
}
|
||||
|
||||
|
||||
pushTpool(proc->threadPool, req);
|
||||
nbEncode++;
|
||||
|
||||
int Qm=hadlsch->Qm;
|
||||
int C=hadlsch->C;
|
||||
int Nl=hadlsch->Nl;
|
||||
@@ -423,6 +382,14 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
|
||||
else
|
||||
r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
|
||||
}
|
||||
// Wait all other threads finish to process
|
||||
while (nbEncode) {
|
||||
notifiedFIFO_elt_t *res = pullTpool(&respEncode, proc->threadPool);
|
||||
if (res == NULL)
|
||||
break; // Tpool has been stopped
|
||||
delNotifiedFIFO_elt(res);
|
||||
nbEncode--;
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
|
||||
return(0);
|
||||
}
|
||||
@@ -462,8 +429,6 @@ int dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB,
|
||||
num_pdcch_symbols,
|
||||
frame,subframe,beamforming_mode);
|
||||
|
||||
proc->nbEncode=0;
|
||||
|
||||
// if (hadlsch->Ndi == 1) { // this is a new packet
|
||||
if (hadlsch->round == 0) { // this is a new packet
|
||||
// Add 24-bit crc (polynomial A) to payload
|
||||
@@ -489,11 +454,13 @@ int dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB,
|
||||
&hadlsch->F)<0)
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int nbEncode = 0;
|
||||
notifiedFIFO_t respEncode;
|
||||
initNotifiedFIFO(&respEncode);
|
||||
for (int r=0, r_offset=0; r<hadlsch->C; r++) {
|
||||
|
||||
union turboReqUnion id= {.s={dlsch->rnti,frame,subframe,r,0}};
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, proc->respEncode, TPencode);
|
||||
notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(turboEncode_t), id.p, &respEncode, TPencode);
|
||||
turboEncode_t * rdata=(turboEncode_t *) NotifiedFifoData(req);
|
||||
rdata->input=hadlsch->c[r];
|
||||
rdata->Kr_bytes= ( r<hadlsch->Cminus ? hadlsch->Kminus : hadlsch->Kplus) >>3;
|
||||
@@ -507,15 +474,10 @@ int dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB,
|
||||
rdata->round=hadlsch->round;
|
||||
rdata->r_offset=r_offset;
|
||||
rdata->G=G;
|
||||
|
||||
if ( proc->threadPool->activated ) {
|
||||
pushTpool(proc->threadPool,req);
|
||||
proc->nbEncode++;
|
||||
} else {
|
||||
TPencode(rdata);
|
||||
delNotifiedFIFO_elt(req);
|
||||
}
|
||||
|
||||
|
||||
pushTpool(proc->threadPool, req);
|
||||
nbEncode++;
|
||||
|
||||
int Qm=hadlsch->Qm;
|
||||
int C=hadlsch->C;
|
||||
int Nl=hadlsch->Nl;
|
||||
@@ -526,7 +488,14 @@ int dlsch_encoding_fembms_pmch(PHY_VARS_eNB *eNB,
|
||||
else
|
||||
r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C));
|
||||
}
|
||||
|
||||
// Wait all other threads finish to process
|
||||
while (nbEncode) {
|
||||
notifiedFIFO_elt_t *res = pullTpool(&respEncode, proc->threadPool);
|
||||
if (res == NULL)
|
||||
break; // Tpool has been stopped
|
||||
delNotifiedFIFO_elt(res);
|
||||
nbEncode--;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -72,21 +72,6 @@ void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch);
|
||||
|
||||
LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
|
||||
|
||||
int dlsch_encoding_all(PHY_VARS_eNB *eNB,
|
||||
L1_rxtx_proc_t *proc,
|
||||
unsigned char *a,
|
||||
uint8_t num_pdcch_symbols,
|
||||
LTE_eNB_DLSCH_t *dlsch,
|
||||
int frame,
|
||||
uint8_t subframe,
|
||||
time_stats_t *rm_stats,
|
||||
time_stats_t *te_stats,
|
||||
time_stats_t *te_wait_stats,
|
||||
time_stats_t *te_main_stats,
|
||||
time_stats_t *te_wakeup_stats0,
|
||||
time_stats_t *te_wakeup_stats1,
|
||||
time_stats_t *i_stats);
|
||||
|
||||
/** \fn dlsch_encoding(PHY_VARS_eNB *eNB,
|
||||
uint8_t *input_buffer,
|
||||
LTE_DL_FRAME_PARMS *frame_parms,
|
||||
@@ -543,15 +528,6 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
|
||||
L1_rxtx_proc_t *proc,
|
||||
uint8_t UE_id);
|
||||
|
||||
|
||||
int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,
|
||||
|
||||
L1_rxtx_proc_t *proc,
|
||||
int UE_id,
|
||||
int harq_pid,
|
||||
int llr8_flag);
|
||||
|
||||
|
||||
/*!
|
||||
\brief Decoding of PUSCH/ACK/RI/ACK from 36-212.
|
||||
@param phy_vars_eNB Pointer to eNB top-level descriptor
|
||||
@@ -570,19 +546,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB,
|
||||
uint8_t Nbundled,
|
||||
uint8_t llr8_flag);
|
||||
|
||||
/*!
|
||||
\brief Decoding of ULSCH data component from 36-212. This one spawns 1 worker thread in parallel,half of the segments in each thread.
|
||||
@param phy_vars_eNB Pointer to eNB top-level descriptor
|
||||
@param UE_id ID of UE transmitting this PUSCH
|
||||
@param harq_pid HARQ process ID
|
||||
@param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
|
||||
@returns 0 on success
|
||||
*/
|
||||
int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,
|
||||
int UE_id,
|
||||
int harq_pid,
|
||||
int llr8_flag);
|
||||
|
||||
/*!
|
||||
\brief Decoding of ULSCH data component from 36-212. This one is single thread.
|
||||
@param phy_vars_eNB Pointer to eNB top-level descriptor
|
||||
|
||||
@@ -367,11 +367,6 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc,
|
||||
return(ret);
|
||||
}
|
||||
|
||||
int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
|
||||
int UE_id,int harq_pid,int llr8_flag) {
|
||||
return ulsch_decoding_data(eNB,proc,UE_id,harq_pid,llr8_flag);
|
||||
}
|
||||
|
||||
static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline));
|
||||
static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) {
|
||||
int n;
|
||||
@@ -1116,7 +1111,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,
|
||||
|
||||
LOG_D(PHY,"frame %d subframe %d O_ACK:%d o_ACK[]=%d:%d:%d:%d\n",frame,subframe,ulsch_harq->O_ACK,ulsch_harq->o_ACK[0],ulsch_harq->o_ACK[1],ulsch_harq->o_ACK[2],ulsch_harq->o_ACK[3]);
|
||||
// Do ULSCH Decoding for data portion
|
||||
ret = ulsch_decoding_data_all(eNB,proc, UE_id,harq_pid,llr8_flag);
|
||||
ret = ulsch_decoding_data(eNB, proc, UE_id, harq_pid, llr8_flag);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
|
||||
a_segments = a_segments/273 +1;
|
||||
}
|
||||
|
||||
LOG_I(PHY,"Allocating %d segments (MAX %d, N_PRB %d)\n",a_segments,MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER,N_RB);
|
||||
uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
|
||||
NR_gNB_DLSCH_t *dlsch = malloc16(sizeof(NR_gNB_DLSCH_t));
|
||||
AssertFatal(dlsch, "cannot allocate dlsch\n");
|
||||
|
||||
@@ -410,7 +410,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
uci_stats->pucch0_thres = gNB->pucch0_thres; /* + (10*max_n0);*/
|
||||
bool no_conf=false;
|
||||
if (nr_sequences>1) {
|
||||
if (/*xrtmag_dBtimes10 < (30+xrtmag_next_dBtimes10) ||*/ SNRtimes10 < uci_stats->pucch0_thres) {
|
||||
if (/*xrtmag_dBtimes10 < (30+xrtmag_next_dBtimes10) ||*/ SNRtimes10 < gNB->pucch0_thres) {
|
||||
no_conf=true;
|
||||
LOG_D(PHY,"%d.%d PUCCH bad confidence: %d threshold, %d, %d, %d\n",
|
||||
frame, slot,
|
||||
|
||||
@@ -1599,19 +1599,20 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
|
||||
// Extraction functions
|
||||
//==============================================================================================
|
||||
|
||||
unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
int **dl_ch_estimates,
|
||||
int **rxdataF_ext,
|
||||
int **dl_ch_estimates_ext,
|
||||
unsigned char symbol,
|
||||
uint8_t pilots,
|
||||
uint8_t config_type,
|
||||
unsigned short start_rb,
|
||||
unsigned short nb_rb_pdsch,
|
||||
uint8_t n_dmrs_cdm_groups,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos,
|
||||
int chest_time_type)
|
||||
void nr_dlsch_extract_rbs(int **rxdataF,
|
||||
int **dl_ch_estimates,
|
||||
int **rxdataF_ext,
|
||||
int **dl_ch_estimates_ext,
|
||||
unsigned char symbol,
|
||||
uint8_t pilots,
|
||||
uint8_t config_type,
|
||||
unsigned short start_rb,
|
||||
unsigned short nb_rb_pdsch,
|
||||
uint8_t n_dmrs_cdm_groups,
|
||||
uint8_t Nl,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos,
|
||||
int chest_time_type)
|
||||
{
|
||||
if (config_type == NFAPI_NR_DMRS_TYPE1) {
|
||||
AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2,
|
||||
@@ -1631,178 +1632,91 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
|
||||
for (unsigned char aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
|
||||
int32_t *dl_ch0 = &dl_ch_estimates[aarx][validDmrsEst * frame_parms->ofdm_symbol_size];
|
||||
int32_t *dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol * nb_rb_pdsch * NR_NB_SC_PER_RB];
|
||||
int32_t *rxF_ext = &rxdataF_ext[aarx][symbol * nb_rb_pdsch * NR_NB_SC_PER_RB];
|
||||
int32_t *rxF = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
|
||||
int32_t *rxF_ext = &rxdataF_ext[aarx][symbol * nb_rb_pdsch * NR_NB_SC_PER_RB];
|
||||
int32_t *rxF = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
|
||||
|
||||
if (pilots == 0) { //data symbol only
|
||||
if (start_re + nb_rb_pdsch * NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) {
|
||||
memcpy((void*)rxF_ext, (void*)&rxF[start_re], nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t));
|
||||
} else {
|
||||
int neg_length = frame_parms->ofdm_symbol_size - start_re;
|
||||
int pos_length = nb_rb_pdsch * NR_NB_SC_PER_RB - neg_length;
|
||||
for (unsigned char aatx = 0; aatx < Nl; aatx++) {
|
||||
|
||||
memcpy((void*)rxF_ext, (void*)&rxF[start_re], neg_length * sizeof(int32_t));
|
||||
memcpy((void*)&rxF_ext[neg_length], (void*)rxF, pos_length * sizeof(int32_t));
|
||||
int32_t *dl_ch0 = &dl_ch_estimates[(aatx*frame_parms->nb_antennas_rx)+aarx][validDmrsEst * frame_parms->ofdm_symbol_size];
|
||||
int32_t *dl_ch0_ext = &dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol * nb_rb_pdsch * NR_NB_SC_PER_RB];
|
||||
|
||||
if (pilots == 0) { //data symbol only
|
||||
if (aatx == 0) {
|
||||
if (start_re + nb_rb_pdsch * NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) {
|
||||
memcpy(rxF_ext, &rxF[start_re], nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t));
|
||||
} else {
|
||||
int neg_length = frame_parms->ofdm_symbol_size - start_re;
|
||||
int pos_length = nb_rb_pdsch * NR_NB_SC_PER_RB - neg_length;
|
||||
|
||||
memcpy(rxF_ext, &rxF[start_re], neg_length * sizeof(int32_t));
|
||||
memcpy(&rxF_ext[neg_length], rxF, pos_length * sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
memcpy(dl_ch0_ext, dl_ch0, nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t));
|
||||
}
|
||||
memcpy((void*)dl_ch0_ext, (void*)dl_ch0, nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t));
|
||||
}
|
||||
else if (config_type == NFAPI_NR_DMRS_TYPE1){
|
||||
if (n_dmrs_cdm_groups == 1) { //data is multiplexed
|
||||
unsigned short k = start_re;
|
||||
for (unsigned short j = 0; j < 6*nb_rb_pdsch; j += 3) {
|
||||
rxF_ext[j] = rxF[k+1];
|
||||
rxF_ext[j+1] = rxF[k+3];
|
||||
rxF_ext[j+2] = rxF[k+5];
|
||||
dl_ch0_ext[j] = dl_ch0[1];
|
||||
dl_ch0_ext[j+1] = dl_ch0[3];
|
||||
dl_ch0_ext[j+2] = dl_ch0[5];
|
||||
dl_ch0 += 6;
|
||||
k += 6;
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
else if (config_type == NFAPI_NR_DMRS_TYPE1){
|
||||
if (n_dmrs_cdm_groups == 1) { //data is multiplexed
|
||||
if (aatx == 0) {
|
||||
unsigned short k = start_re;
|
||||
for (unsigned short j = 0; j < 6*nb_rb_pdsch; j += 3) {
|
||||
rxF_ext[j] = rxF[k+1];
|
||||
rxF_ext[j+1] = rxF[k+3];
|
||||
rxF_ext[j+2] = rxF[k+5];
|
||||
k += 6;
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
for (unsigned short j = 0; j < 6*nb_rb_pdsch; j += 3) {
|
||||
dl_ch0_ext[j] = dl_ch0[1];
|
||||
dl_ch0_ext[j+1] = dl_ch0[3];
|
||||
dl_ch0_ext[j+2] = dl_ch0[5];
|
||||
dl_ch0 += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {//NFAPI_NR_DMRS_TYPE2
|
||||
if (n_dmrs_cdm_groups == 1) { //data is multiplexed
|
||||
unsigned short k = start_re;
|
||||
for (unsigned short j = 0; j < 8*nb_rb_pdsch; j += 4) {
|
||||
rxF_ext[j] = rxF[k+2];
|
||||
rxF_ext[j+1] = rxF[k+3];
|
||||
rxF_ext[j+2] = rxF[k+4];
|
||||
rxF_ext[j+3] = rxF[k+5];
|
||||
dl_ch0_ext[j] = dl_ch0[2];
|
||||
dl_ch0_ext[j+1] = dl_ch0[3];
|
||||
dl_ch0_ext[j+2] = dl_ch0[4];
|
||||
dl_ch0_ext[j+3] = dl_ch0[5];
|
||||
dl_ch0 += 6;
|
||||
k += 6;
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
else {//NFAPI_NR_DMRS_TYPE2
|
||||
if (n_dmrs_cdm_groups == 1) { //data is multiplexed
|
||||
if (aatx == 0) {
|
||||
unsigned short k = start_re;
|
||||
for (unsigned short j = 0; j < 8*nb_rb_pdsch; j += 4) {
|
||||
rxF_ext[j] = rxF[k+2];
|
||||
rxF_ext[j+1] = rxF[k+3];
|
||||
rxF_ext[j+2] = rxF[k+4];
|
||||
rxF_ext[j+3] = rxF[k+5];
|
||||
k += 6;
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
for (unsigned short j = 0; j < 8*nb_rb_pdsch; j += 4) {
|
||||
dl_ch0_ext[j] = dl_ch0[2];
|
||||
dl_ch0_ext[j+1] = dl_ch0[3];
|
||||
dl_ch0_ext[j+2] = dl_ch0[4];
|
||||
dl_ch0_ext[j+3] = dl_ch0[5];
|
||||
dl_ch0 += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (n_dmrs_cdm_groups == 2) { //data is multiplexed
|
||||
unsigned short k = start_re;
|
||||
for (unsigned short j = 0; j < 4*nb_rb_pdsch; j += 2) {
|
||||
rxF_ext[j] = rxF[k+4];
|
||||
rxF_ext[j+1] = rxF[k+5];
|
||||
dl_ch0_ext[j] = dl_ch0[4];
|
||||
dl_ch0_ext[j+1] = dl_ch0[5];
|
||||
dl_ch0 += 6;
|
||||
k += 6;
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
else if (n_dmrs_cdm_groups == 2) { //data is multiplexed
|
||||
if (aatx == 0) {
|
||||
unsigned short k = start_re;
|
||||
for (unsigned short j = 0; j < 4*nb_rb_pdsch; j += 2) {
|
||||
rxF_ext[j] = rxF[k+4];
|
||||
rxF_ext[j+1] = rxF[k+5];
|
||||
k += 6;
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
for (unsigned short j = 0; j < 4*nb_rb_pdsch; j += 2) {
|
||||
dl_ch0_ext[j] = dl_ch0[4];
|
||||
dl_ch0_ext[j+1] = dl_ch0[5];
|
||||
dl_ch0 += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nb_rb_pdsch;
|
||||
}
|
||||
|
||||
void nr_dlsch_extract_rbs(int **rxdataF,
|
||||
int **dl_ch_estimates,
|
||||
int **rxdataF_ext,
|
||||
int **dl_ch_estimates_ext,
|
||||
unsigned char symbol,
|
||||
uint8_t pilots,
|
||||
uint8_t config_type,
|
||||
unsigned short start_rb,
|
||||
unsigned short nb_rb_pdsch,
|
||||
uint8_t n_dmrs_cdm_groups,
|
||||
uint8_t Nl,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos,
|
||||
int chest_time_type)
|
||||
{
|
||||
|
||||
unsigned short k,rb;
|
||||
unsigned char nushift,j,i,aarx,aatx;
|
||||
int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
|
||||
int8_t validDmrsEst = 0; //store last DMRS Symbol index
|
||||
|
||||
if (config_type==NFAPI_NR_DMRS_TYPE1) {
|
||||
AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2,
|
||||
"n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups);
|
||||
nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1
|
||||
} else {
|
||||
AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3,
|
||||
"n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups);
|
||||
nushift = (n_dmrs_cdm_groups -1)<<1;//delta in Table 7.4.1.1.2-2
|
||||
}
|
||||
|
||||
if (chest_time_type == 0)
|
||||
validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol);
|
||||
else
|
||||
validDmrsEst = get_next_dmrs_symbol_in_slot(dlDmrsSymbPos,0,14); // get first dmrs symbol index
|
||||
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
|
||||
k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb;
|
||||
if (k>=frame_parms->ofdm_symbol_size)
|
||||
k = k-frame_parms->ofdm_symbol_size;
|
||||
|
||||
rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)];
|
||||
rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))];
|
||||
|
||||
for (aatx=0; aatx<Nl; aatx++) {
|
||||
|
||||
dl_ch0 = &dl_ch_estimates[(aatx*frame_parms->nb_antennas_rx)+aarx][(validDmrsEst*(frame_parms->ofdm_symbol_size))];
|
||||
dl_ch0_ext = &dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*(nb_rb_pdsch*NR_NB_SC_PER_RB)];
|
||||
|
||||
for (rb = 0; rb < nb_rb_pdsch; rb++)
|
||||
{
|
||||
if (pilots==0) {//data symbol only
|
||||
if (aatx==0) {//Extract Rx signal only
|
||||
memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext));
|
||||
rxF_ext+=12;
|
||||
}
|
||||
memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext));//Extract Channel Estimate
|
||||
dl_ch0_ext+=12;
|
||||
}
|
||||
else {//the symbol contains DMRS
|
||||
j=0;
|
||||
if (config_type==NFAPI_NR_DMRS_TYPE1) {
|
||||
if (nushift == 0) {//data is multiplexed
|
||||
for (i = (1-nushift); i<12; i+=2) {
|
||||
if (aatx==0) rxF_ext[j]=rxF[i];
|
||||
dl_ch0_ext[j]=dl_ch0[i];
|
||||
j++;
|
||||
}
|
||||
dl_ch0_ext+=6;
|
||||
if (aatx==0) rxF_ext+=6;
|
||||
}
|
||||
}
|
||||
else {//NFAPI_NR_DMRS_TYPE2
|
||||
for (i = (2+nushift); i<6; i++) {
|
||||
if (aatx==0) rxF_ext[j]=rxF[i];
|
||||
dl_ch0_ext[j]=dl_ch0[i];
|
||||
j++;
|
||||
}
|
||||
for (i = (8+nushift); i<12; i++) {
|
||||
if (aatx==0) rxF_ext[j]=rxF[i];
|
||||
dl_ch0_ext[j]=dl_ch0[i];
|
||||
j++;
|
||||
}
|
||||
dl_ch0_ext+= j;
|
||||
if (aatx==0) rxF_ext+= j;
|
||||
}
|
||||
}
|
||||
|
||||
dl_ch0+=12;
|
||||
if (aatx==0) {
|
||||
rxF+=12;
|
||||
k+=12;
|
||||
if (k>=frame_parms->ofdm_symbol_size) {
|
||||
k=k-(frame_parms->ofdm_symbol_size);
|
||||
rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))];
|
||||
}
|
||||
}
|
||||
}//rb
|
||||
}//aatx
|
||||
}//aarx
|
||||
}
|
||||
|
||||
void nr_dlsch_detection_mrc(int **rxdataF_comp,
|
||||
@@ -2439,9 +2353,9 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw,
|
||||
switch (Nl) {
|
||||
case 1:
|
||||
if (codeword_TB1 == -1)
|
||||
memcpy((void*)llr_cw[0], (void*)llr_layers[0], (length)*sizeof(int16_t));
|
||||
memcpy(llr_cw[0], llr_layers[0], (length)*sizeof(int16_t));
|
||||
else if (codeword_TB0 == -1)
|
||||
memcpy((void*)llr_cw[1], (void*)llr_layers[0], (length)*sizeof(int16_t));
|
||||
memcpy(llr_cw[1], llr_layers[0], (length)*sizeof(int16_t));
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@@ -680,39 +680,7 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms,
|
||||
unsigned short nb_rb,
|
||||
unsigned char dual_stream_UE);
|
||||
|
||||
/** \fn dlsch_extract_rbs_single(int32_t **rxdataF,
|
||||
int32_t **dl_ch_estimates,
|
||||
int32_t **rxdataF_ext,
|
||||
int32_t **dl_ch_estimates_ext,
|
||||
uint32_t *rb_alloc,
|
||||
uint8_t symbol,
|
||||
NR_DL_FRAME_PARMS *frame_parms)
|
||||
\brief This function extracts the received resource blocks, both channel estimates and data symbols,
|
||||
for the current allocation and for single antenna eNB transmission.
|
||||
@param rxdataF Raw FFT output of received signal
|
||||
@param dl_ch_estimates Channel estimates of current slot
|
||||
@param rxdataF_ext FFT output for RBs in this allocation
|
||||
@param dl_ch_estimates_ext Channel estimates for RBs in this allocation
|
||||
@param rb_alloc RB allocation vector
|
||||
@param symbol Symbol to extract
|
||||
@param n_dmrs_cdm_groups
|
||||
@param frame_parms Pointer to frame descriptor
|
||||
*/
|
||||
unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
int **dl_ch_estimates,
|
||||
int **rxdataF_ext,
|
||||
int **dl_ch_estimates_ext,
|
||||
unsigned char symbol,
|
||||
uint8_t pilots,
|
||||
uint8_t config_type,
|
||||
unsigned short start_rb,
|
||||
unsigned short nb_rb_pdsch,
|
||||
uint8_t n_dmrs_cdm_groups,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos,
|
||||
int chest_time_type);
|
||||
|
||||
/** \fn dlsch_extract_rbs_multiple(int32_t **rxdataF,
|
||||
/** \fn dlsch_extract_rbs(int32_t **rxdataF,
|
||||
int32_t **dl_ch_estimates,
|
||||
int32_t **rxdataF_ext,
|
||||
int32_t **dl_ch_estimates_ext,
|
||||
@@ -737,19 +705,19 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
@param frame_parms Pointer to frame descriptor
|
||||
*/
|
||||
void nr_dlsch_extract_rbs(int **rxdataF,
|
||||
int **dl_ch_estimates,
|
||||
int **rxdataF_ext,
|
||||
int **dl_ch_estimates_ext,
|
||||
unsigned char symbol,
|
||||
uint8_t pilots,
|
||||
uint8_t config_type,
|
||||
unsigned short start_rb,
|
||||
unsigned short nb_rb_pdsch,
|
||||
uint8_t n_dmrs_cdm_groups,
|
||||
uint8_t Nl,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos,
|
||||
int chest_time_type);
|
||||
int **dl_ch_estimates,
|
||||
int **rxdataF_ext,
|
||||
int **dl_ch_estimates_ext,
|
||||
unsigned char symbol,
|
||||
uint8_t pilots,
|
||||
uint8_t config_type,
|
||||
unsigned short start_rb,
|
||||
unsigned short nb_rb_pdsch,
|
||||
uint8_t n_dmrs_cdm_groups,
|
||||
uint8_t Nl,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos,
|
||||
int chest_time_type);
|
||||
|
||||
/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
|
||||
int32_t **dl_bf_ch_estimates,
|
||||
|
||||
@@ -495,15 +495,34 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
uint8_t pmi=pusch_pdu->Tpmi;
|
||||
|
||||
if (pmi == 0) {//unitary Precoding
|
||||
if(ap< pusch_pdu->nrOfLayers)
|
||||
memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
|
||||
(void*)&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
|
||||
NR_NB_SC_PER_RB*sizeof(int32_t));
|
||||
else
|
||||
memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
|
||||
0,
|
||||
NR_NB_SC_PER_RB*sizeof(int32_t));
|
||||
|
||||
if (k + NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { // RB does not cross DC
|
||||
if (ap<pusch_pdu->nrOfLayers)
|
||||
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
|
||||
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
|
||||
NR_NB_SC_PER_RB*sizeof(int32_t));
|
||||
else
|
||||
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
|
||||
0,
|
||||
NR_NB_SC_PER_RB*sizeof(int32_t));
|
||||
} else { // RB does cross DC
|
||||
int neg_length = frame_parms->ofdm_symbol_size - k;
|
||||
int pos_length = NR_NB_SC_PER_RB - neg_length;
|
||||
if (ap<pusch_pdu->nrOfLayers) {
|
||||
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
|
||||
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
|
||||
neg_length*sizeof(int32_t));
|
||||
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size],
|
||||
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size)],
|
||||
pos_length*sizeof(int32_t));
|
||||
} else {
|
||||
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
|
||||
0,
|
||||
neg_length*sizeof(int32_t));
|
||||
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size],
|
||||
0,
|
||||
pos_length*sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
k += NR_NB_SC_PER_RB;
|
||||
if (k >= frame_parms->ofdm_symbol_size) {
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
+43
-27
@@ -39,6 +39,8 @@
|
||||
#include "time_meas.h"
|
||||
#include "defs_common.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include <common/utils/threadPool/thread-pool.h>
|
||||
#include <executables/rt_profiling.h>
|
||||
|
||||
#define MAX_BANDS_PER_RRU 4
|
||||
#define MAX_RRU_CONFIG_SIZE 1024
|
||||
@@ -168,25 +170,21 @@ typedef struct RU_prec_t_s{
|
||||
int index;
|
||||
} RU_prec_t;
|
||||
|
||||
typedef struct RU_feptx_t_s{
|
||||
/// \internal This variable is protected by \ref mutex_feptx_prec
|
||||
int instance_cnt_feptx;
|
||||
/// pthread struct for RU TX FEP PREC worker thread
|
||||
pthread_t pthread_feptx;
|
||||
/// pthread attributes for worker feptx prec thread
|
||||
pthread_attr_t attr_feptx;
|
||||
/// condition varible for RU TX FEP PREC thread
|
||||
pthread_cond_t cond_feptx;
|
||||
/// mutex for fep PREC TX worker thread
|
||||
pthread_mutex_t mutex_feptx;
|
||||
struct RU_t_s *ru;
|
||||
int aa;//physical MAX nb_tx
|
||||
int half_slot;//first or second half of a slot
|
||||
int slot;//current slot
|
||||
int symbol;//current symbol
|
||||
int nb_antenna_ports;//number of logical port
|
||||
int index;
|
||||
}RU_feptx_t;
|
||||
typedef struct {
|
||||
int aid;
|
||||
struct RU_t_s *ru;
|
||||
int startSymbol;
|
||||
int endSymbol;
|
||||
int slot;
|
||||
} feprx_cmd_t;
|
||||
|
||||
typedef struct {
|
||||
int aid;
|
||||
struct RU_t_s *ru;
|
||||
int slot;
|
||||
int startSymbol;
|
||||
int numSymbols;
|
||||
} feptx_cmd_t;
|
||||
|
||||
typedef struct {
|
||||
int frame;
|
||||
@@ -246,7 +244,7 @@ typedef struct RU_proc_t_s {
|
||||
/// \internal This variable is protected by \ref mutex_asynch_rxtx.
|
||||
int instance_cnt_asynch_rxtx;
|
||||
/// \internal This variable is protected by \ref mutex_fep
|
||||
int instance_cnt_fep;
|
||||
int instance_cnt_fep[8];
|
||||
/// \internal This variable is protected by \ref mutex_feptx
|
||||
int instance_cnt_feptx;
|
||||
/// \internal This variable is protected by \ref mutex_ru_thread
|
||||
@@ -265,7 +263,7 @@ typedef struct RU_proc_t_s {
|
||||
/// pthread struct for RU synch thread
|
||||
pthread_t pthread_synch;
|
||||
/// pthread struct for RU RX FEP worker thread
|
||||
pthread_t pthread_fep;
|
||||
pthread_t pthread_fep[8];
|
||||
/// pthread struct for RU TX FEP worker thread
|
||||
pthread_t pthread_feptx;
|
||||
/// pthread struct for emulated RF
|
||||
@@ -318,7 +316,7 @@ typedef struct RU_proc_t_s {
|
||||
/// condition variable for asynch RX/TX thread
|
||||
pthread_cond_t cond_asynch_rxtx;
|
||||
/// condition varible for RU RX FEP thread
|
||||
pthread_cond_t cond_fep;
|
||||
pthread_cond_t cond_fep[8];
|
||||
/// condition varible for RU TX FEP thread
|
||||
pthread_cond_t cond_feptx;
|
||||
/// condition varible for emulated RF
|
||||
@@ -345,7 +343,7 @@ typedef struct RU_proc_t_s {
|
||||
/// mutex for asynch RX/TX thread
|
||||
pthread_mutex_t mutex_asynch_rxtx;
|
||||
/// mutex for fep RX worker thread
|
||||
pthread_mutex_t mutex_fep;
|
||||
pthread_mutex_t mutex_fep[8];
|
||||
/// mutex for fep TX worker thread
|
||||
pthread_mutex_t mutex_feptx;
|
||||
/// mutex for ru_thread
|
||||
@@ -395,10 +393,6 @@ typedef struct RU_proc_t_s {
|
||||
|
||||
/// structure for precoding thread
|
||||
RU_prec_t prec[16];
|
||||
/// structure for feptx thread
|
||||
RU_feptx_t feptx[16];
|
||||
/// mask for checking process finished
|
||||
int feptx_mask;
|
||||
} RU_proc_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -433,6 +427,8 @@ typedef enum {
|
||||
|
||||
|
||||
typedef struct RU_t_s {
|
||||
/// ThreadPool for RU
|
||||
tpool_t *threadPool;
|
||||
/// index of this ru
|
||||
uint32_t idx;
|
||||
/// pointer to first RU
|
||||
@@ -507,6 +503,10 @@ typedef struct RU_t_s {
|
||||
int sf_ahead;
|
||||
/// TX processing advance in slots (for NR)
|
||||
int sl_ahead;
|
||||
/// flag to indicate TX FH is embedded in TX FEP
|
||||
int txfh_in_fep;
|
||||
/// flag to indicate half-slot parallelization
|
||||
int half_slot_parallelization;
|
||||
/// FAPI confiuration
|
||||
nfapi_nr_config_request_scf_t config;
|
||||
/// Frame parameters
|
||||
@@ -645,6 +645,22 @@ typedef struct RU_t_s {
|
||||
uint64_t if_frequency;
|
||||
/// UL IF frequency offset to DL IF frequency in Hz
|
||||
int if_freq_offset;
|
||||
/// to signal end of feprx
|
||||
notifiedFIFO_t *respfeprx;
|
||||
/// to signal end of feptx
|
||||
notifiedFIFO_t *respfeptx;
|
||||
/// core id for RX fhaul (IF5 ECPRI)
|
||||
int rxfh_core_id;
|
||||
/// core id for RX fhaul (IF5 ECPRI)
|
||||
int txfh_core_id;
|
||||
/// number of RU interfaces
|
||||
int num_fd;
|
||||
/// list of cores for RU ThreadPool
|
||||
int tpcores[16];
|
||||
/// number of cores for RU ThreadPool
|
||||
int num_tpcores;
|
||||
/// structure for analyzing high-level RT measurements
|
||||
rt_ru_profiling_t rt_ru_profiling;
|
||||
} RU_t;
|
||||
|
||||
|
||||
|
||||
@@ -253,11 +253,9 @@ typedef struct {
|
||||
/// mutex for RXn-TXnp4 processing thread
|
||||
pthread_mutex_t mutex_RUs;
|
||||
tpool_t *threadPool;
|
||||
int nbEncode;
|
||||
int nbDecode;
|
||||
notifiedFIFO_t *respEncode;
|
||||
notifiedFIFO_t *respDecode;
|
||||
pthread_mutex_t mutex_emulateRF;
|
||||
pthread_mutex_t mutex_emulateRF;
|
||||
int instance_cnt_emulateRF;
|
||||
pthread_t pthread_emulateRF;
|
||||
pthread_attr_t attr_emulateRF;
|
||||
@@ -731,11 +729,6 @@ typedef struct PHY_VARS_eNB_s {
|
||||
time_stats_t dlsch_turbo_encoding_preperation_stats;
|
||||
time_stats_t dlsch_turbo_encoding_segmentation_stats;
|
||||
time_stats_t dlsch_turbo_encoding_stats;
|
||||
time_stats_t dlsch_turbo_encoding_waiting_stats;
|
||||
time_stats_t dlsch_turbo_encoding_signal_stats;
|
||||
time_stats_t dlsch_turbo_encoding_main_stats;
|
||||
time_stats_t dlsch_turbo_encoding_wakeup_stats0;
|
||||
time_stats_t dlsch_turbo_encoding_wakeup_stats1;
|
||||
time_stats_t dlsch_interleaving_stats;
|
||||
|
||||
time_stats_t rx_dft_stats;
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "PHY/defs_common.h"
|
||||
#include "PHY/CODING/nrLDPC_extern.h"
|
||||
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
|
||||
#include "executables/rt_profiling.h"
|
||||
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
|
||||
@@ -840,6 +841,7 @@ typedef struct PHY_VARS_gNB_s {
|
||||
int pucch0_thres;
|
||||
int pusch_thres;
|
||||
int prach_thres;
|
||||
int srs_thres;
|
||||
uint64_t bad_pucch;
|
||||
int num_ulprbbl;
|
||||
int ulprbbl[275];
|
||||
@@ -897,6 +899,8 @@ typedef struct PHY_VARS_gNB_s {
|
||||
int number_of_nr_dlsch_max;
|
||||
int number_of_nr_ulsch_max;
|
||||
void * scopeData;
|
||||
/// structure for analyzing high-level RT measurements
|
||||
rt_L1_profiling_t rt_L1_profiling;
|
||||
} PHY_VARS_gNB;
|
||||
|
||||
typedef struct LDPCDecode_s {
|
||||
|
||||
@@ -23,6 +23,6 @@
|
||||
#define __openair_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#define MAKE_VERSION(a,b,c) ((a)*256+(b)*16+c)
|
||||
#define MAKE_VERSION(a,b,c) ((a)*65536+(b)*256+c)
|
||||
|
||||
#endif /*__openair_TYPES_H__ */
|
||||
|
||||
@@ -413,33 +413,9 @@ bool dlsch_procedures(PHY_VARS_eNB *eNB,
|
||||
}
|
||||
|
||||
start_meas(&eNB->dlsch_encoding_stats);
|
||||
dlsch_encoding_all(eNB,
|
||||
proc,
|
||||
dlsch_harq->pdu,
|
||||
dlsch_harq->pdsch_start,
|
||||
dlsch,
|
||||
frame,
|
||||
subframe,
|
||||
&eNB->dlsch_rate_matching_stats,
|
||||
&eNB->dlsch_turbo_encoding_stats,
|
||||
&eNB->dlsch_turbo_encoding_waiting_stats,
|
||||
&eNB->dlsch_turbo_encoding_main_stats,
|
||||
&eNB->dlsch_turbo_encoding_wakeup_stats0,
|
||||
&eNB->dlsch_turbo_encoding_wakeup_stats1,
|
||||
&eNB->dlsch_interleaving_stats);
|
||||
dlsch_encoding(eNB, proc, dlsch_harq->pdu, dlsch_harq->pdsch_start, dlsch, frame, subframe, &eNB->dlsch_rate_matching_stats, &eNB->dlsch_turbo_encoding_stats, &eNB->dlsch_interleaving_stats);
|
||||
stop_meas(&eNB->dlsch_encoding_stats);
|
||||
|
||||
if ( proc->threadPool->activated ) {
|
||||
// Wait all other threads finish to process
|
||||
while (proc->nbEncode) {
|
||||
notifiedFIFO_elt_t *res = pullTpool(proc->respEncode, proc->threadPool);
|
||||
if (res == NULL)
|
||||
break; // Tpool has been stopped
|
||||
delNotifiedFIFO_elt(res);
|
||||
proc->nbEncode--;
|
||||
}
|
||||
}
|
||||
|
||||
if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) {
|
||||
print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
#include "SCHED/sched_eNB.h"
|
||||
#include "PHY/MODULATION/modulation_eNB.h"
|
||||
#include "PHY/LTE_TRANSPORT/if4_tools.h"
|
||||
#include "PHY/LTE_TRANSPORT/if5_tools.h"
|
||||
#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
|
||||
#include "PHY/LTE_TRANSPORT/transport_proto.h"
|
||||
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
|
||||
@@ -566,15 +565,15 @@ static void *fep_thread(void *param)
|
||||
|
||||
while (!oai_exit) {
|
||||
|
||||
if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread")<0) break;
|
||||
if (wait_on_condition(&proc->mutex_fep[0],&proc->cond_fep[0],&proc->instance_cnt_fep[0],"fep thread")<0) break;
|
||||
if (oai_exit) break;
|
||||
//stop_meas(&ru->ofdm_demod_wakeup_stats);
|
||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 );
|
||||
fep0(ru,0);
|
||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 0 );
|
||||
if (release_thread(&proc->mutex_fep,&proc->instance_cnt_fep,"fep thread")<0) break;
|
||||
if (release_thread(&proc->mutex_fep[0],&proc->instance_cnt_fep[0],"fep thread")<0) break;
|
||||
|
||||
if (pthread_cond_signal(&proc->cond_fep) != 0) {
|
||||
if (pthread_cond_signal(&proc->cond_fep[0]) != 0) {
|
||||
printf("[eNB] ERROR pthread_cond_signal for fep thread exit\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
return NULL;
|
||||
@@ -607,12 +606,12 @@ void init_fep_thread(RU_t *ru,
|
||||
{
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
|
||||
proc->instance_cnt_fep = -1;
|
||||
proc->instance_cnt_fep[0] = -1;
|
||||
|
||||
pthread_mutex_init( &proc->mutex_fep, NULL);
|
||||
pthread_cond_init( &proc->cond_fep, NULL);
|
||||
pthread_mutex_init( &proc->mutex_fep[0], NULL);
|
||||
pthread_cond_init( &proc->cond_fep[0], NULL);
|
||||
|
||||
threadCreate(&proc->pthread_fep, fep_thread, (void*)ru, "fep", -1, OAI_PRIORITY_RT);
|
||||
threadCreate(&proc->pthread_fep[0], fep_thread, (void*)ru, "fep", -1, OAI_PRIORITY_RT);
|
||||
}
|
||||
|
||||
|
||||
@@ -621,14 +620,14 @@ void kill_fep_thread(RU_t *ru)
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
if (proc->pthread_fep == 0)
|
||||
return;
|
||||
pthread_mutex_lock( &proc->mutex_fep );
|
||||
proc->instance_cnt_fep = 0;
|
||||
pthread_cond_signal(&proc->cond_fep);
|
||||
pthread_mutex_unlock( &proc->mutex_fep );
|
||||
pthread_mutex_lock( &proc->mutex_fep[0] );
|
||||
proc->instance_cnt_fep[0] = 0;
|
||||
pthread_cond_signal(&proc->cond_fep[0]);
|
||||
pthread_mutex_unlock( &proc->mutex_fep[0] );
|
||||
LOG_D(PHY, "Joining pthread_fep\n");
|
||||
pthread_join(proc->pthread_fep, NULL);
|
||||
pthread_mutex_destroy( &proc->mutex_fep );
|
||||
pthread_cond_destroy( &proc->cond_fep );
|
||||
pthread_join(proc->pthread_fep[0], NULL);
|
||||
pthread_mutex_destroy( &proc->mutex_fep[0] );
|
||||
pthread_cond_destroy( &proc->cond_fep[0] );
|
||||
}
|
||||
|
||||
|
||||
@@ -670,35 +669,35 @@ void ru_fep_full_2thread(RU_t *ru,
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+ru->idx, 1 );
|
||||
start_meas(&ru->ofdm_demod_stats);
|
||||
|
||||
if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) {
|
||||
printf("[RU] ERROR pthread_mutex_lock for fep thread (IC %d)\n", proc->instance_cnt_fep);
|
||||
if (pthread_mutex_timedlock(&proc->mutex_fep[0],&wait) != 0) {
|
||||
printf("[RU] ERROR pthread_mutex_lock for fep thread (IC %d)\n", proc->instance_cnt_fep[0]);
|
||||
exit_fun( "error locking mutex_fep" );
|
||||
return;
|
||||
}
|
||||
|
||||
if (proc->instance_cnt_fep==0) {
|
||||
if (proc->instance_cnt_fep[0]==0) {
|
||||
printf("[RU] FEP thread busy\n");
|
||||
exit_fun("FEP thread busy");
|
||||
pthread_mutex_unlock( &proc->mutex_fep );
|
||||
pthread_mutex_unlock( &proc->mutex_fep[0] );
|
||||
return;
|
||||
}
|
||||
|
||||
++proc->instance_cnt_fep;
|
||||
++proc->instance_cnt_fep[0];
|
||||
|
||||
if (pthread_cond_signal(&proc->cond_fep) != 0) {
|
||||
if (pthread_cond_signal(&proc->cond_fep[0]) != 0) {
|
||||
printf("[RU] ERROR pthread_cond_signal for fep thread\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
return;
|
||||
}
|
||||
//start_meas(&ru->ofdm_demod_wakeup_stats);
|
||||
|
||||
pthread_mutex_unlock( &proc->mutex_fep );
|
||||
pthread_mutex_unlock( &proc->mutex_fep[0] );
|
||||
|
||||
// call second slot in this symbol
|
||||
fep0(ru,1);
|
||||
|
||||
start_meas(&ru->ofdm_demod_wait_stats);
|
||||
wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread");
|
||||
wait_on_busy_condition(&proc->mutex_fep[0],&proc->cond_fep[0],&proc->instance_cnt_fep[0],"fep thread");
|
||||
stop_meas(&ru->ofdm_demod_wait_stats);
|
||||
if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){
|
||||
print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr);
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "PHY/MODULATION/modulation_common.h"
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
#include "PHY/LTE_TRANSPORT/if4_tools.h"
|
||||
#include "PHY/LTE_TRANSPORT/if5_tools.h"
|
||||
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/system.h"
|
||||
@@ -46,12 +45,14 @@
|
||||
#include "assertions.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
|
||||
// RU OFDM Modulator gNodeB
|
||||
|
||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
extern int oai_exit;
|
||||
|
||||
// OFDM modulation core routine, generates a first_symbol to first_symbol+num_symbols on a particular slot and TX antenna port
|
||||
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
@@ -62,6 +63,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
|
||||
|
||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 );
|
||||
|
||||
if (aa==0 && first_symbol == 0) start_meas(&ru->ofdm_mod_stats);
|
||||
slot_offset = fp->get_samples_slot_timestamp(slot,fp,0);
|
||||
slot_offsetF = first_symbol*fp->ofdm_symbol_size;
|
||||
|
||||
@@ -72,16 +74,16 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
|
||||
|
||||
slot_offset += fp->ofdm_symbol_size*first_symbol;
|
||||
|
||||
LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d (first_symbol %d num_symbols %d)\n",ru->proc.frame_tx, ru->proc.tti_tx,slot,first_symbol,num_symbols);
|
||||
LOG_D(PHY,"SFN/SF:RU:TX:%d/%d aa %d Generating slot %d (first_symbol %d num_symbols %d) slot_offset %d, slot_offsetF %d\n",ru->proc.frame_tx, ru->proc.tti_tx,aa,slot,first_symbol,num_symbols,slot_offset,slot_offsetF);
|
||||
|
||||
if (fp->Ncp == 1)
|
||||
if (fp->Ncp == 1) {
|
||||
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
|
||||
(int*)&ru->common.txdata[aa][slot_offset],
|
||||
fp->ofdm_symbol_size,
|
||||
num_symbols,
|
||||
fp->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
else {
|
||||
} else {
|
||||
if (fp->numerology_index != 0) {
|
||||
|
||||
if (!(slot%(fp->slots_per_subframe/2))&&(first_symbol==0)) { // case where first symbol in slot has longer prefix
|
||||
@@ -130,280 +132,16 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
|
||||
slot_offset += fp->nb_prefix_samples0+fp->ofdm_symbol_size;
|
||||
slot_offsetF += fp->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // for(idx_symbol..
|
||||
} // numerology 0
|
||||
}
|
||||
|
||||
if (aa==0 && first_symbol==0) stop_meas(&ru->ofdm_mod_stats);
|
||||
|
||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0), 0);
|
||||
}
|
||||
|
||||
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
RU_feptx_t *feptx = proc->feptx;
|
||||
|
||||
PHY_VARS_gNB *gNB;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
|
||||
int slot = tti_tx;
|
||||
|
||||
int i = 0;
|
||||
int j = 0;//symbol
|
||||
int aa = 0;//physical antenna number
|
||||
int ret = 0;
|
||||
int ofdm_mask_full = (1<<(ru->nb_tx*2))-1;
|
||||
int txdataF_offset = (tti_tx*fp->samples_per_slot_wCP);
|
||||
|
||||
if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return;
|
||||
for (aa=0; aa<ru->nb_tx; aa++) memset(ru->common.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t));
|
||||
|
||||
start_meas(&ru->ofdm_total_stats);
|
||||
|
||||
//if (nr_slot_select(cfg,frame_tx,slot)==NR_DOWNLINK_SLOT) {
|
||||
if(ru->num_gNB != 0){//L1 RU on same machine
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 );
|
||||
for(j=0; j<2; ++j){//half slot
|
||||
for(i=0; i<ru->nb_tx; ++i){
|
||||
if(j == 0){
|
||||
AssertFatal((ret=pthread_mutex_lock(&feptx[i].mutex_feptx))==0,"mutex_lock return %d\n",ret);
|
||||
feptx[i].aa = i;
|
||||
feptx[i].index = i;
|
||||
feptx[i].ru = ru;
|
||||
feptx[i].symbol = 0;
|
||||
feptx[i].slot = slot;
|
||||
feptx[i].nb_antenna_ports = ru->nb_tx;
|
||||
feptx[i].instance_cnt_feptx = 0;
|
||||
AssertFatal(pthread_cond_signal(&feptx[i].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n");
|
||||
AssertFatal((ret=pthread_mutex_unlock(&feptx[i].mutex_feptx))==0,"mutex_lock returns %d\n",ret);
|
||||
}//first half
|
||||
else{
|
||||
AssertFatal((ret=pthread_mutex_lock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock return %d\n",ret);
|
||||
feptx[i+ru->nb_tx].aa = i;
|
||||
feptx[i+ru->nb_tx].index = i+ru->nb_tx;
|
||||
feptx[i+ru->nb_tx].ru = ru;
|
||||
feptx[i+ru->nb_tx].symbol = fp->symbols_per_slot>>1;
|
||||
feptx[i+ru->nb_tx].slot = slot;
|
||||
feptx[i+ru->nb_tx].nb_antenna_ports = ru->nb_tx;
|
||||
feptx[i+ru->nb_tx].instance_cnt_feptx = 0;
|
||||
AssertFatal(pthread_cond_signal(&feptx[i+ru->nb_tx].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n");
|
||||
AssertFatal((ret=pthread_mutex_unlock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock returns %d\n",ret);
|
||||
}//second half
|
||||
}//physical antenna
|
||||
}//half slot
|
||||
}//if L1 RU on same machine
|
||||
else{//(RU only machine)
|
||||
for(j=0; j<fp->symbols_per_slot; ++j){
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 1);
|
||||
start_meas(&ru->txdataF_copy_stats);
|
||||
AssertFatal(ru->num_gNB==1,"num_gNB>1, help\n");
|
||||
gNB = ru->gNB_list[0];
|
||||
cfg = &gNB->gNB_config;
|
||||
|
||||
for(i=0; i<ru->nb_tx; ++i){
|
||||
memcpy((void*)&ru->common.txdataF[i][j*fp->ofdm_symbol_size],
|
||||
(void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset],
|
||||
fp->ofdm_symbol_size*sizeof(int32_t));
|
||||
|
||||
}
|
||||
|
||||
stop_meas(&ru->txdataF_copy_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 0);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 );
|
||||
|
||||
if (nr_slot_select(cfg,slot,frame_tx)==SF_DL) {
|
||||
// If this is not an S-tti
|
||||
for(i=0; i<ru->nb_tx; ++i){
|
||||
if(j%2 == 0){
|
||||
while(feptx[i].instance_cnt_feptx != -1){
|
||||
usleep(5);
|
||||
}
|
||||
AssertFatal((ret=pthread_mutex_lock(&feptx[i].mutex_feptx))==0,"mutex_lock return %d\n",ret);
|
||||
feptx[i].aa = i;
|
||||
feptx[i].index = i;
|
||||
feptx[i].ru = ru;
|
||||
feptx[i].symbol = j;
|
||||
feptx[i].slot = slot;
|
||||
feptx[i].nb_antenna_ports = ru->nb_tx;
|
||||
feptx[i].instance_cnt_feptx = 0;
|
||||
AssertFatal(pthread_cond_signal(&feptx[i].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n");
|
||||
AssertFatal((ret=pthread_mutex_unlock(&feptx[i].mutex_feptx))==0,"mutex_lock returns %d\n",ret);
|
||||
}
|
||||
else{
|
||||
while(feptx[i+ru->nb_tx].instance_cnt_feptx != -1){
|
||||
usleep(5);
|
||||
}
|
||||
AssertFatal((ret=pthread_mutex_lock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock return %d\n",ret);
|
||||
feptx[i+ru->nb_tx].aa = i;
|
||||
feptx[i+ru->nb_tx].index = i+ru->nb_tx;
|
||||
feptx[i+ru->nb_tx].ru = ru;
|
||||
feptx[i+ru->nb_tx].symbol = j;
|
||||
feptx[i+ru->nb_tx].slot = slot;
|
||||
feptx[i+ru->nb_tx].nb_antenna_ports = ru->nb_tx;
|
||||
feptx[i+ru->nb_tx].instance_cnt_feptx = 0;
|
||||
AssertFatal(pthread_cond_signal(&feptx[i+ru->nb_tx].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n");
|
||||
AssertFatal((ret=pthread_mutex_unlock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock returns %d\n",ret);
|
||||
}
|
||||
}
|
||||
}//if == SF_DL
|
||||
else {
|
||||
proc->feptx_mask = ofdm_mask_full;
|
||||
}
|
||||
}//j<fp->symbols_per_slot
|
||||
}//else (RU only machine)
|
||||
//}
|
||||
// wait all process to finish
|
||||
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_feptx))==0,"mutex_lock return %d\n",ret);
|
||||
while (proc->feptx_mask != ofdm_mask_full) {
|
||||
// most of the time the thread is waiting here
|
||||
// proc->instance_cnt_rxtx is -1
|
||||
pthread_cond_wait(&proc->cond_feptx,&proc->mutex_feptx); // this unlocks mutex_rxtx while waiting and then locks it again
|
||||
}
|
||||
proc->feptx_mask = 0;
|
||||
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_feptx))==0,"mutex_lock return %d\n",ret);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, proc->feptx_mask );
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 );
|
||||
|
||||
|
||||
stop_meas(&ru->ofdm_total_stats);
|
||||
|
||||
}
|
||||
|
||||
static void *nr_feptx_thread(void *param) {
|
||||
|
||||
RU_feptx_t *feptx = (RU_feptx_t *)param;
|
||||
RU_t *ru;
|
||||
int aa, slot, start, l, ret;
|
||||
int i;
|
||||
int32_t ***bw;
|
||||
NR_DL_FRAME_PARMS *fp;
|
||||
int ofdm_mask_full;
|
||||
int txdataF_offset;
|
||||
while (!oai_exit) {
|
||||
ret = 0;
|
||||
if (wait_on_condition(&feptx->mutex_feptx,&feptx->cond_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+feptx->index+1 , 1 );
|
||||
|
||||
AssertFatal(feptx->ru->nb_log_antennas>0 && feptx->ru->nb_log_antennas < 13,"ru->nb_log_antennas is %d\n", feptx->ru->nb_log_antennas);
|
||||
|
||||
ru = feptx->ru;
|
||||
slot = feptx->slot;
|
||||
aa = feptx->aa;
|
||||
l = feptx->symbol;
|
||||
fp = ru->nr_frame_parms;
|
||||
start = feptx->symbol;
|
||||
ofdm_mask_full = (1<<(ru->nb_tx*2))-1;
|
||||
|
||||
if(ru->num_gNB != 0){
|
||||
txdataF_offset = (slot*fp->samples_per_slot_wCP);
|
||||
////////////precoding////////////
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1);
|
||||
|
||||
if (aa==0 && l==0) start_meas(&ru->precoding_stats);
|
||||
|
||||
if (ru->do_precoding == 1) {
|
||||
for(i=0; i<ru->nb_log_antennas; ++i) {
|
||||
memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot+l],
|
||||
(void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot+l],
|
||||
(fp->symbols_per_slot>>1)*sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) {
|
||||
memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size],
|
||||
(fp->samples_per_slot_wCP>>1)*sizeof(int32_t));
|
||||
}
|
||||
else if (ru->do_precoding == 0) {
|
||||
int gNB_tx = ru->gNB_list[0]->frame_parms.nb_antennas_tx;
|
||||
memcpy((void*)&ru->common.txdataF_BF[aa][l*fp->ofdm_symbol_size],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[aa%gNB_tx][txdataF_offset + l*fp->ofdm_symbol_size],
|
||||
(fp->samples_per_slot_wCP>>1)*sizeof(int32_t));
|
||||
}
|
||||
else {
|
||||
bw = ru->beam_weights[0];
|
||||
for(i=0; i<fp->symbols_per_slot>>1; ++i){
|
||||
nr_beam_precoding(ru->gNB_list[0]->common_vars.txdataF,
|
||||
ru->common.txdataF_BF,
|
||||
fp,
|
||||
bw,
|
||||
slot,
|
||||
l+i,
|
||||
aa,
|
||||
ru->nb_log_antennas,
|
||||
txdataF_offset);//here
|
||||
}
|
||||
}
|
||||
if (aa==0 && l==0) stop_meas(&ru->precoding_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0);
|
||||
|
||||
////////////FEPTX////////////
|
||||
if (aa==0 && l==0) start_meas(&ru->ofdm_mod_stats);
|
||||
nr_feptx0(ru,slot,start,fp->symbols_per_slot>>1,aa);
|
||||
if (aa==0 && l==0) stop_meas(&ru->ofdm_mod_stats);
|
||||
|
||||
if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break;
|
||||
|
||||
AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_feptx))==0,"mutex_lock return %d\n",ret);
|
||||
ru->proc.feptx_mask |= 1<<(feptx->index);
|
||||
if(ru->proc.feptx_mask == ofdm_mask_full)
|
||||
AssertFatal(pthread_cond_signal(&ru->proc.cond_feptx) == 0,"ERROR pthread_cond_signal for precoding and ofdm finish\n");
|
||||
AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_feptx))==0,"mutex_lock returns %d\n",ret);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, ru->proc.feptx_mask );
|
||||
}// if L1 RU on same machine
|
||||
|
||||
else{
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1);
|
||||
start_meas(&ru->precoding_stats);
|
||||
if (ru->nb_tx == 1 && ru->nb_log_antennas) {
|
||||
memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size],
|
||||
(void*)&ru->common.txdataF[0][l*fp->ofdm_symbol_size],
|
||||
fp->ofdm_symbol_size*sizeof(int32_t));
|
||||
}
|
||||
else {
|
||||
bw = ru->beam_weights[0];
|
||||
nr_beam_precoding(ru->common.txdataF,
|
||||
ru->common.txdataF_BF,
|
||||
fp,
|
||||
bw,
|
||||
slot,
|
||||
l,
|
||||
aa,
|
||||
ru->nb_log_antennas,
|
||||
0);
|
||||
}
|
||||
stop_meas(&ru->precoding_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0);
|
||||
|
||||
|
||||
start_meas(&ru->ofdm_mod_stats);
|
||||
nr_feptx0(ru,slot,start,1,aa);
|
||||
stop_meas(&ru->ofdm_mod_stats);
|
||||
|
||||
if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break;
|
||||
|
||||
if(l >= fp->symbols_per_slot -2){
|
||||
AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_feptx))==0,"mutex_lock return %d\n",ret);
|
||||
ru->proc.feptx_mask |= 1<<(feptx->index);
|
||||
if(ru->proc.feptx_mask == ofdm_mask_full)
|
||||
AssertFatal(pthread_cond_signal(&ru->proc.cond_feptx) == 0,"ERROR pthread_cond_signal for precoding and ofdm finish\n");
|
||||
AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_feptx))==0,"mutex_lock returns %d\n",ret);
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, ru->proc.feptx_mask );
|
||||
}// else (RU only machine)
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+feptx->index+1 , 0 );
|
||||
}// while (oai_exit)
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
// is this supposed to generate a slot or a subframe???
|
||||
// seems to be hardcoded to numerology 1 (2 slots=1 subframe)
|
||||
// RU FEP TX OFDM modulation, single-thread
|
||||
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
@@ -419,7 +157,6 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 );
|
||||
start_meas(&ru->ofdm_mod_stats);
|
||||
|
||||
|
||||
// LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
|
||||
@@ -427,7 +164,6 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
nr_feptx0(ru,slot,0,NR_NUMBER_OF_SYMBOLS_PER_SLOT,aa);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 );
|
||||
stop_meas(&ru->ofdm_mod_stats);
|
||||
|
||||
LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, slot %d: txp (time %p) %d dB, txp (freq) %d dB\n",
|
||||
frame_tx,slot,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->get_samples_per_slot(
|
||||
@@ -435,43 +171,6 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
|
||||
}
|
||||
|
||||
void nr_init_feptx_thread(RU_t *ru) {
|
||||
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
RU_feptx_t *feptx = proc->feptx;
|
||||
int i = 0;
|
||||
|
||||
for(i=0; i<(ru->nb_tx*2); i++){
|
||||
feptx[i].instance_cnt_feptx = -1;
|
||||
|
||||
pthread_mutex_init( &feptx[i].mutex_feptx, NULL);
|
||||
pthread_cond_init( &feptx[i].cond_feptx, NULL);
|
||||
|
||||
threadCreate(&feptx[i].pthread_feptx, nr_feptx_thread, (void*)&feptx[i], "feptx", -1, OAI_PRIORITY_RT);
|
||||
LOG_I(PHY,"init feptx thread %d\n", i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void nr_kill_feptx_thread(RU_t *ru) {
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
|
||||
for (int i = 0; i < ru->nb_tx * 2; i++) {
|
||||
RU_feptx_t *feptx = &proc->feptx[i];
|
||||
if (feptx->pthread_feptx == 0)
|
||||
continue;
|
||||
|
||||
pthread_mutex_lock(&feptx->mutex_feptx);
|
||||
feptx->instance_cnt_feptx = 0;
|
||||
pthread_mutex_unlock(&feptx->mutex_feptx);
|
||||
pthread_cond_signal(&feptx->cond_feptx);
|
||||
LOG_I(PHY, "Joining pthread_feptx %d\n", i);
|
||||
pthread_join(feptx->pthread_feptx, NULL);
|
||||
pthread_mutex_destroy(&feptx->mutex_feptx);
|
||||
pthread_cond_destroy(&feptx->cond_feptx);
|
||||
}
|
||||
}
|
||||
|
||||
void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
|
||||
int l,aa;
|
||||
@@ -530,157 +229,6 @@ void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
stop_meas(&ru->precoding_stats);
|
||||
}
|
||||
|
||||
void nr_fep0(RU_t *ru, int first_half) {
|
||||
|
||||
uint8_t start_symbol, end_symbol, l, aa;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
|
||||
if(first_half == 1) {
|
||||
start_symbol = 0;
|
||||
end_symbol = NR_SYMBOLS_PER_SLOT/2;
|
||||
} else {
|
||||
start_symbol = NR_SYMBOLS_PER_SLOT/2;
|
||||
end_symbol = NR_SYMBOLS_PER_SLOT;
|
||||
}
|
||||
|
||||
LOG_D(PHY,"In fep0 for slot = %d, first_half = %d, start_symbol = %d, end_symbol = %d, nb_antennas_rx = %d,N_TA_offset = %d\n",
|
||||
proc->tti_rx, first_half, start_symbol, end_symbol,fp->nb_antennas_rx,ru->N_TA_offset);
|
||||
// printf("fep0: slot %d\n",slot);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 1);
|
||||
|
||||
int offset = (proc->tti_rx&3) * fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
for (l = start_symbol; l < end_symbol; l++) {
|
||||
for (aa = 0; aa < fp->nb_antennas_rx; aa++) {
|
||||
nr_slot_fep_ul(fp,
|
||||
ru->common.rxdata[aa],
|
||||
&ru->common.rxdataF[aa][offset],
|
||||
l,
|
||||
proc->tti_rx,
|
||||
ru->N_TA_offset);
|
||||
}
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 0);
|
||||
}
|
||||
|
||||
|
||||
static void *nr_feprx_thread(void *param) {
|
||||
|
||||
RU_t *ru = (RU_t *)param;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
|
||||
|
||||
while (!oai_exit) {
|
||||
|
||||
if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"NR feprx thread")<0) break;
|
||||
|
||||
if (oai_exit) break;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 );
|
||||
|
||||
nr_fep0(ru, 0);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 0 );
|
||||
|
||||
if (release_thread(&proc->mutex_fep,&proc->instance_cnt_fep,"nr_feprx thread")<0) break;
|
||||
|
||||
if (pthread_cond_signal(&proc->cond_fep) != 0) {
|
||||
printf("[gNB] ERROR pthread_cond_signal for nr_feprx thread exit\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void nr_init_feprx_thread(RU_t *ru) {
|
||||
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
|
||||
proc->instance_cnt_fep = -1;
|
||||
|
||||
pthread_mutex_init( &proc->mutex_fep, NULL);
|
||||
pthread_cond_init( &proc->cond_fep, NULL);
|
||||
|
||||
threadCreate(&proc->pthread_fep, nr_feprx_thread, (void*)ru, "feprx", -1, OAI_PRIORITY_RT);
|
||||
}
|
||||
|
||||
void nr_kill_feprx_thread(RU_t *ru) {
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
if (proc->pthread_fep == 0)
|
||||
return;
|
||||
LOG_I(PHY, "Joining pthread_feprx\n");
|
||||
pthread_mutex_lock(&proc->mutex_fep);
|
||||
proc->instance_cnt_fep = 0;
|
||||
pthread_mutex_unlock(&proc->mutex_fep);
|
||||
pthread_cond_signal(&proc->cond_fep);
|
||||
pthread_join(proc->pthread_fep, NULL);
|
||||
pthread_mutex_destroy(&proc->mutex_fep);
|
||||
pthread_cond_destroy(&proc->cond_fep);
|
||||
}
|
||||
|
||||
void nr_fep_full_2thread(RU_t *ru, int slot) {
|
||||
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
|
||||
struct timespec wait;
|
||||
|
||||
// NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
|
||||
// if ((fp->frame_type == TDD) &&
|
||||
// (subframe_select(fp,proc->tti_rx) != NR_UPLINK_SLOT)) return;
|
||||
|
||||
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
|
||||
|
||||
wait.tv_sec=0;
|
||||
wait.tv_nsec=5000000L;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
|
||||
start_meas(&ru->ofdm_demod_stats);
|
||||
|
||||
if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) {
|
||||
printf("[RU] ERROR pthread_mutex_lock for nr_feprx thread (IC %d)\n", proc->instance_cnt_fep);
|
||||
exit_fun( "error locking mutex_fep" );
|
||||
return;
|
||||
}
|
||||
|
||||
if (proc->instance_cnt_fep==0) {
|
||||
LOG_E(PHY, "RU FEP thread busy, exiting %s\n", __func__);
|
||||
pthread_mutex_unlock( &proc->mutex_fep );
|
||||
return;
|
||||
}
|
||||
|
||||
++proc->instance_cnt_fep;
|
||||
|
||||
|
||||
if (pthread_cond_signal(&proc->cond_fep) != 0) {
|
||||
printf("[RU] ERROR pthread_cond_signal for nr_feprx thread\n");
|
||||
exit_fun( "ERROR pthread_cond_signal" );
|
||||
return;
|
||||
}
|
||||
//start_meas(&ru->ofdm_demod_wakeup_stats);
|
||||
|
||||
pthread_mutex_unlock( &proc->mutex_fep );
|
||||
|
||||
// call second slot in this symbol
|
||||
nr_fep0(ru, 1);
|
||||
|
||||
start_meas(&ru->ofdm_demod_wait_stats);
|
||||
wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"nr_feprx thread");
|
||||
stop_meas(&ru->ofdm_demod_wait_stats);
|
||||
if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){
|
||||
print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr);
|
||||
printf("delay in fep wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->tti_rx);
|
||||
}
|
||||
|
||||
stop_meas(&ru->ofdm_demod_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void nr_fep_full(RU_t *ru, int slot) {
|
||||
|
||||
@@ -716,3 +264,170 @@ void nr_fep_full(RU_t *ru, int slot) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
// core routine for FEP TX, called from threads in RU TX thread-pool
|
||||
void nr_feptx(void *arg) {
|
||||
|
||||
feptx_cmd_t *feptx = (feptx_cmd_t *)arg;
|
||||
|
||||
RU_t *ru = feptx->ru;
|
||||
int slot = feptx->slot;
|
||||
int aa = feptx->aid;
|
||||
int startSymbol = feptx->startSymbol;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int numSymbols = feptx->numSymbols;
|
||||
int numSamples = feptx->numSymbols*fp->ofdm_symbol_size;
|
||||
int txdataF_offset = (slot*fp->samples_per_slot_wCP) + startSymbol*fp->ofdm_symbol_size;
|
||||
int txdataF_BF_offset = startSymbol*fp->ofdm_symbol_size;
|
||||
|
||||
////////////precoding////////////
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 1);
|
||||
|
||||
if (aa==0) start_meas(&ru->precoding_stats);
|
||||
|
||||
if (ru->do_precoding == 1) {
|
||||
for(int i=0; i<ru->nb_log_antennas; ++i) {
|
||||
memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot],
|
||||
(void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot)*sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) {
|
||||
memcpy((void*)&ru->common.txdataF_BF[0][txdataF_BF_offset],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset],
|
||||
numSamples*sizeof(int32_t));
|
||||
}
|
||||
else if (ru->do_precoding == 0) {
|
||||
int gNB_tx = ru->gNB_list[0]->frame_parms.nb_antennas_tx;
|
||||
memcpy((void*)&ru->common.txdataF_BF[aa][txdataF_BF_offset],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[aa%gNB_tx][txdataF_offset],
|
||||
numSamples*sizeof(int32_t));
|
||||
}
|
||||
else {
|
||||
AssertFatal(1==0,"This needs to be fixed, do not use beamforming.\n");
|
||||
int32_t ***bw = ru->beam_weights[0];
|
||||
for(int i=0; i<fp->symbols_per_slot; ++i){
|
||||
nr_beam_precoding(ru->gNB_list[0]->common_vars.txdataF,
|
||||
ru->common.txdataF_BF,
|
||||
fp,
|
||||
bw,
|
||||
slot,
|
||||
i,
|
||||
aa,
|
||||
ru->nb_log_antennas,
|
||||
txdataF_offset);//here
|
||||
}
|
||||
}
|
||||
if (aa==0) stop_meas(&ru->precoding_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 0);
|
||||
|
||||
////////////FEPTX////////////
|
||||
nr_feptx0(ru,slot,startSymbol,numSymbols,aa);
|
||||
}
|
||||
|
||||
// RU FEP TX using thread-pool
|
||||
void nr_feptx_tp(RU_t *ru, int frame_tx, int slot) {
|
||||
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
int nbfeptx=0;
|
||||
if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return;
|
||||
// for (int aa=0; aa<ru->nb_tx; aa++) memset(ru->common.txdataF[aa],0,ru->nr_frame_parms->samples_per_slot_wCP*sizeof(int32_t));
|
||||
|
||||
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 1 );
|
||||
start_meas(&ru->ofdm_total_stats);
|
||||
for (int aid=0;aid<ru->nb_tx;aid++) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid,ru->respfeptx,nr_feptx);
|
||||
feptx_cmd_t *feptx_cmd=(feptx_cmd_t*)NotifiedFifoData(req);
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = 0;
|
||||
feptx_cmd->numSymbols = (ru->half_slot_parallelization>0)?ru->nr_frame_parms->symbols_per_slot>>1:ru->nr_frame_parms->symbols_per_slot;
|
||||
pushTpool(ru->threadPool,req);
|
||||
nbfeptx++;
|
||||
if (ru->half_slot_parallelization>0) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx,ru->respfeptx,nr_feptx);
|
||||
feptx_cmd_t *feptx_cmd=(feptx_cmd_t*)NotifiedFifoData(req);
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot>>1;
|
||||
feptx_cmd->numSymbols = ru->nr_frame_parms->symbols_per_slot>>1;
|
||||
pushTpool(ru->threadPool,req);
|
||||
nbfeptx++;
|
||||
}
|
||||
}
|
||||
while (nbfeptx>0) {
|
||||
notifiedFIFO_elt_t *req=pullTpool(ru->respfeptx, ru->threadPool);
|
||||
delNotifiedFIFO_elt(req);
|
||||
nbfeptx--;
|
||||
}
|
||||
stop_meas(&ru->ofdm_total_stats);
|
||||
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 0 );
|
||||
}
|
||||
|
||||
// core RX FEP routine, called by threads in RU thread-pool
|
||||
void nr_fep(void* arg) {
|
||||
|
||||
feprx_cmd_t *feprx_cmd = (feprx_cmd_t *)arg;
|
||||
|
||||
RU_t *ru = feprx_cmd->ru;
|
||||
int aid = feprx_cmd->aid;
|
||||
int tti_rx = feprx_cmd->slot;
|
||||
int startSymbol = feprx_cmd->startSymbol;
|
||||
int endSymbol = feprx_cmd->endSymbol;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
|
||||
LOG_D(PHY,"In nr_fep for aid %d, slot = %d, startSymbol %d, endSymbol %d\n", aid, tti_rx,startSymbol,endSymbol);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 1);
|
||||
|
||||
int offset = (tti_rx&3) * fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
for (int l = startSymbol; l <= endSymbol; l++)
|
||||
nr_slot_fep_ul(fp,
|
||||
ru->common.rxdata[aid],
|
||||
&ru->common.rxdataF[aid][offset],
|
||||
l,
|
||||
tti_rx,
|
||||
ru->N_TA_offset);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 0);
|
||||
}
|
||||
|
||||
// RU RX FEP using thread-pool
|
||||
void nr_fep_tp(RU_t *ru, int slot) {
|
||||
|
||||
int nbfeprx=0;
|
||||
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
|
||||
start_meas(&ru->ofdm_demod_stats);
|
||||
for (int aid=0;aid<ru->nb_rx;aid++) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feprx_cmd_t), 1000 + aid,ru->respfeprx,nr_fep);
|
||||
feprx_cmd_t *feprx_cmd=(feprx_cmd_t*)NotifiedFifoData(req);
|
||||
feprx_cmd->aid = aid;
|
||||
feprx_cmd->ru = ru;
|
||||
feprx_cmd->slot = ru->proc.tti_rx;
|
||||
feprx_cmd->startSymbol = 0;
|
||||
feprx_cmd->endSymbol = (ru->half_slot_parallelization > 0)?(ru->nr_frame_parms->symbols_per_slot>>1)-1:(ru->nr_frame_parms->symbols_per_slot-1);
|
||||
pushTpool(ru->threadPool,req);
|
||||
nbfeprx++;
|
||||
if (ru->half_slot_parallelization>0) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feprx_cmd_t), 1000 + aid + ru->nb_rx,ru->respfeprx,nr_fep);
|
||||
feprx_cmd_t *feprx_cmd=(feprx_cmd_t*)NotifiedFifoData(req);
|
||||
feprx_cmd->aid = aid;
|
||||
feprx_cmd->ru = ru;
|
||||
feprx_cmd->slot = ru->proc.tti_rx;
|
||||
feprx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot>>1;
|
||||
feprx_cmd->endSymbol = ru->nr_frame_parms->symbols_per_slot-1;
|
||||
pushTpool(ru->threadPool,req);
|
||||
nbfeprx++;
|
||||
}
|
||||
}
|
||||
while (nbfeprx>0) {
|
||||
notifiedFIFO_elt_t *req=pullTpool(ru->respfeprx, ru->threadPool);
|
||||
delNotifiedFIFO_elt(req);
|
||||
nbfeprx--;
|
||||
}
|
||||
stop_meas(&ru->ofdm_demod_stats);
|
||||
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 );
|
||||
}
|
||||
|
||||
|
||||
@@ -846,29 +846,28 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0;i<NUMBER_OF_NR_SRS_MAX;i++) {
|
||||
for (int i = 0; i < NUMBER_OF_NR_SRS_MAX; i++) {
|
||||
NR_gNB_SRS_t *srs = gNB->srs[i];
|
||||
if (srs) {
|
||||
if ((srs->active == 1) && (srs->frame == frame_rx) && (srs->slot == slot_rx)) {
|
||||
|
||||
LOG_D(NR_PHY, "(%d.%d) gNB is waiting for SRS, id = %i\n", frame_rx, slot_rx, i);
|
||||
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu;
|
||||
uint8_t N_symb_SRS = 1<<srs_pdu->num_symbols;
|
||||
int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS];
|
||||
int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][1<<srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32)));
|
||||
int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][1<<srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32)));
|
||||
int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][1<<srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size];
|
||||
uint8_t N_symb_SRS = 1 << srs_pdu->num_symbols;
|
||||
int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size * N_symb_SRS];
|
||||
int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size * N_symb_SRS] __attribute__((aligned(32)));
|
||||
int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||
int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size];
|
||||
int8_t snr_per_rb[srs_pdu->bwp_size];
|
||||
int8_t snr;
|
||||
|
||||
// At least currently, the configuration is constant, so it is enough to generate the sequence just once.
|
||||
if(gNB->nr_srs_info[i]->srs_generated_signal_bits == 0) {
|
||||
if (gNB->nr_srs_info[i]->srs_generated_signal_bits == 0) {
|
||||
generate_srs_nr(srs_pdu, frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, 0, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx);
|
||||
}
|
||||
|
||||
const int srs_est = nr_get_srs_signal(gNB,frame_rx,slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal);
|
||||
int srs_est = nr_get_srs_signal(gNB, frame_rx, slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal);
|
||||
|
||||
if (srs_est >= 0) {
|
||||
nr_srs_channel_estimation(gNB,
|
||||
@@ -876,7 +875,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
slot_rx,
|
||||
srs_pdu,
|
||||
gNB->nr_srs_info[i],
|
||||
(const int32_t **) gNB->nr_srs_info[i]->srs_generated_signal,
|
||||
(const int32_t **)gNB->nr_srs_info[i]->srs_generated_signal,
|
||||
srs_received_signal,
|
||||
srs_estimated_channel_freq,
|
||||
srs_estimated_channel_time,
|
||||
@@ -885,102 +884,108 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
&snr);
|
||||
}
|
||||
|
||||
T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0),
|
||||
T_BUFFER(srs_estimated_channel_freq[0][0], frame_parms->ofdm_symbol_size*sizeof(int32_t)));
|
||||
if ((snr * 10) < gNB->srs_thres) {
|
||||
srs_est = -1;
|
||||
}
|
||||
|
||||
T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0),
|
||||
T_BUFFER(srs_estimated_channel_time_shifted[0][0], frame_parms->ofdm_symbol_size*sizeof(int32_t)));
|
||||
T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE,
|
||||
T_INT(0),
|
||||
T_INT(srs_pdu->rnti),
|
||||
T_INT(frame_rx),
|
||||
T_INT(0),
|
||||
T_INT(0),
|
||||
T_BUFFER(srs_estimated_channel_freq[0][0], frame_parms->ofdm_symbol_size * sizeof(int32_t)));
|
||||
|
||||
T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE,
|
||||
T_INT(0),
|
||||
T_INT(srs_pdu->rnti),
|
||||
T_INT(frame_rx),
|
||||
T_INT(0),
|
||||
T_INT(0),
|
||||
T_BUFFER(srs_estimated_channel_time_shifted[0][0], frame_parms->ofdm_symbol_size * sizeof(int32_t)));
|
||||
|
||||
const uint16_t num_srs = gNB->UL_INFO.srs_ind.number_of_pdus;
|
||||
gNB->UL_INFO.srs_ind.pdu_list = &gNB->srs_pdu_list[0];
|
||||
gNB->UL_INFO.srs_ind.sfn = frame_rx;
|
||||
gNB->UL_INFO.srs_ind.slot = slot_rx;
|
||||
gNB->srs_pdu_list[num_srs].handle = srs_pdu->handle;
|
||||
gNB->srs_pdu_list[num_srs].rnti = srs_pdu->rnti;
|
||||
gNB->srs_pdu_list[num_srs].timing_advance_offset = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms,
|
||||
srs_estimated_channel_time[0]) : 0xFFFF;
|
||||
gNB->srs_pdu_list[num_srs].timing_advance_offset_nsec = srs_est >= 0 ? (int16_t)(( ((int32_t)gNB->srs_pdu_list[num_srs].timing_advance_offset-31) * ((int32_t)TC_NSEC_x32768) ) >> 15) : 0xFFFF;
|
||||
|
||||
nfapi_nr_srs_indication_pdu_t *srs_indication = &gNB->srs_pdu_list[gNB->UL_INFO.srs_ind.number_of_pdus];
|
||||
srs_indication->handle = srs_pdu->handle;
|
||||
srs_indication->rnti = srs_pdu->rnti;
|
||||
srs_indication->timing_advance_offset = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms, srs_estimated_channel_time[0]) : 0xFFFF;
|
||||
srs_indication->timing_advance_offset_nsec = srs_est >= 0 ? (int16_t)((((int32_t)srs_indication->timing_advance_offset - 31) * ((int32_t)TC_NSEC_x32768)) >> 15) : 0xFFFF;
|
||||
switch (srs_pdu->srs_parameters_v4.usage) {
|
||||
case 0:
|
||||
LOG_W(NR_PHY, "SRS report was not requested by MAC\n");
|
||||
return 0;
|
||||
case 1<<NR_SRS_ResourceSet__usage_beamManagement:
|
||||
gNB->srs_pdu_list[num_srs].srs_usage = NR_SRS_ResourceSet__usage_beamManagement;
|
||||
case 1 << NR_SRS_ResourceSet__usage_beamManagement:
|
||||
srs_indication->srs_usage = NR_SRS_ResourceSet__usage_beamManagement;
|
||||
break;
|
||||
case 1<<NR_SRS_ResourceSet__usage_codebook:
|
||||
gNB->srs_pdu_list[num_srs].srs_usage = NR_SRS_ResourceSet__usage_codebook;
|
||||
case 1 << NR_SRS_ResourceSet__usage_codebook:
|
||||
srs_indication->srs_usage = NR_SRS_ResourceSet__usage_codebook;
|
||||
break;
|
||||
case 1<<NR_SRS_ResourceSet__usage_nonCodebook:
|
||||
gNB->srs_pdu_list[num_srs].srs_usage = NR_SRS_ResourceSet__usage_nonCodebook;
|
||||
case 1 << NR_SRS_ResourceSet__usage_nonCodebook:
|
||||
srs_indication->srs_usage = NR_SRS_ResourceSet__usage_nonCodebook;
|
||||
break;
|
||||
case 1<<NR_SRS_ResourceSet__usage_antennaSwitching:
|
||||
gNB->srs_pdu_list[num_srs].srs_usage = NR_SRS_ResourceSet__usage_antennaSwitching;
|
||||
case 1 << NR_SRS_ResourceSet__usage_antennaSwitching:
|
||||
srs_indication->srs_usage = NR_SRS_ResourceSet__usage_antennaSwitching;
|
||||
break;
|
||||
default:
|
||||
LOG_E(NR_PHY, "Invalid srs_pdu->srs_parameters_v4.usage %i\n", srs_pdu->srs_parameters_v4.usage);
|
||||
}
|
||||
gNB->srs_pdu_list[num_srs].report_type = srs_pdu->srs_parameters_v4.report_type[0];
|
||||
srs_indication->report_type = srs_pdu->srs_parameters_v4.report_type[0];
|
||||
|
||||
#ifdef SRS_IND_DEBUG
|
||||
LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.sfn = %i\n", gNB->UL_INFO.srs_ind.sfn);
|
||||
LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.slot = %i\n", gNB->UL_INFO.srs_ind.slot);
|
||||
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].rnti = %04x\n", num_srs, gNB->srs_pdu_list[num_srs].rnti);
|
||||
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].timing_advance = %i\n", num_srs, gNB->srs_pdu_list[num_srs].timing_advance_offset);
|
||||
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].timing_advance_offset_nsec = %i\n", num_srs, gNB->srs_pdu_list[num_srs].timing_advance_offset_nsec);
|
||||
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].srs_usage = %i\n", num_srs, gNB->srs_pdu_list[num_srs].srs_usage);
|
||||
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].report_type = %i\n", num_srs, gNB->srs_pdu_list[num_srs].report_type);
|
||||
LOG_I(NR_PHY, "srs_indication->rnti = %04x\n", srs_indication->rnti);
|
||||
LOG_I(NR_PHY, "srs_indication->timing_advance = %i\n", srs_indication->timing_advance_offset);
|
||||
LOG_I(NR_PHY, "srs_indication->timing_advance_offset_nsec = %i\n", srs_indication->timing_advance_offset_nsec);
|
||||
LOG_I(NR_PHY, "srs_indication->srs_usage = %i\n", srs_indication->srs_usage);
|
||||
LOG_I(NR_PHY, "srs_indication->report_type = %i\n", srs_indication->report_type);
|
||||
#endif
|
||||
|
||||
if(!gNB->srs_pdu_list[num_srs].report_tlv) {
|
||||
gNB->srs_pdu_list[num_srs].report_tlv = (nfapi_srs_report_tlv_t*) calloc(1, sizeof(nfapi_srs_report_tlv_t));
|
||||
if (!srs_indication->report_tlv) {
|
||||
srs_indication->report_tlv = (nfapi_srs_report_tlv_t *)calloc(1, sizeof(nfapi_srs_report_tlv_t));
|
||||
}
|
||||
gNB->srs_pdu_list[num_srs].report_tlv->tag = 0;
|
||||
gNB->srs_pdu_list[num_srs].report_tlv->length = 0;
|
||||
|
||||
switch (gNB->srs_pdu_list[num_srs].srs_usage) {
|
||||
srs_indication->report_tlv->tag = 0;
|
||||
srs_indication->report_tlv->length = 0;
|
||||
|
||||
switch (srs_indication->srs_usage) {
|
||||
case NR_SRS_ResourceSet__usage_beamManagement: {
|
||||
|
||||
nfapi_nr_srs_beamforming_report_t nr_srs_beamforming_report;
|
||||
nr_srs_beamforming_report.prg_size = srs_pdu->beamforming.prg_size;
|
||||
nr_srs_beamforming_report.num_symbols = 1<<srs_pdu->num_symbols;
|
||||
nr_srs_beamforming_report.wide_band_snr = srs_est >= 0 ? (snr + 64)<<1 : 0xFF; // 0xFF will be set if this field is invalid
|
||||
nr_srs_beamforming_report.num_reported_symbols = 1<<srs_pdu->num_symbols;
|
||||
nr_srs_beamforming_report.prgs = (nfapi_nr_srs_reported_symbol_t*) calloc(1, nr_srs_beamforming_report.num_reported_symbols*sizeof(nfapi_nr_srs_reported_symbol_t));
|
||||
fill_srs_reported_symbol_list(&nr_srs_beamforming_report.prgs[0],
|
||||
srs_pdu,
|
||||
frame_parms->N_RB_UL,
|
||||
snr_per_rb,
|
||||
srs_est);
|
||||
nr_srs_beamforming_report.num_symbols = 1 << srs_pdu->num_symbols;
|
||||
nr_srs_beamforming_report.wide_band_snr = srs_est >= 0 ? (snr + 64) << 1 : 0xFF; // 0xFF will be set if this field is invalid
|
||||
nr_srs_beamforming_report.num_reported_symbols = 1 << srs_pdu->num_symbols;
|
||||
nr_srs_beamforming_report.prgs = (nfapi_nr_srs_reported_symbol_t *)calloc(1, nr_srs_beamforming_report.num_reported_symbols * sizeof(nfapi_nr_srs_reported_symbol_t));
|
||||
fill_srs_reported_symbol_list(&nr_srs_beamforming_report.prgs[0], srs_pdu, frame_parms->N_RB_UL, snr_per_rb, srs_est);
|
||||
|
||||
#ifdef SRS_IND_DEBUG
|
||||
LOG_I(NR_PHY, "nr_srs_beamforming_report.prg_size = %i\n", nr_srs_beamforming_report.prg_size);
|
||||
LOG_I(NR_PHY, "nr_srs_beamforming_report.num_symbols = %i\n", nr_srs_beamforming_report.num_symbols);
|
||||
LOG_I(NR_PHY, "nr_srs_beamforming_report.wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report.wide_band_snr, (nr_srs_beamforming_report.wide_band_snr>>1)-64);
|
||||
LOG_I(NR_PHY, "nr_srs_beamforming_report.wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report.wide_band_snr, (nr_srs_beamforming_report.wide_band_snr >> 1) - 64);
|
||||
LOG_I(NR_PHY, "nr_srs_beamforming_report.num_reported_symbols = %i\n", nr_srs_beamforming_report.num_reported_symbols);
|
||||
LOG_I(NR_PHY, "nr_srs_beamforming_report.prgs[0].num_prgs = %i\n", nr_srs_beamforming_report.prgs[0].num_prgs);
|
||||
for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report.prgs[0].num_prgs; prg_idx++) {
|
||||
LOG_I(NR_PHY, "nr_srs_beamforming_report.prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n",
|
||||
for (int prg_idx = 0; prg_idx < nr_srs_beamforming_report.prgs[0].num_prgs; prg_idx++) {
|
||||
LOG_I(NR_PHY,
|
||||
"nr_srs_beamforming_report.prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n",
|
||||
prg_idx,
|
||||
nr_srs_beamforming_report.prgs[0].prg_list[prg_idx].rb_snr,
|
||||
(nr_srs_beamforming_report.prgs[0].prg_list[prg_idx].rb_snr>>1)-64);
|
||||
(nr_srs_beamforming_report.prgs[0].prg_list[prg_idx].rb_snr >> 1) - 64);
|
||||
}
|
||||
#endif
|
||||
|
||||
gNB->srs_pdu_list[num_srs].report_tlv->length = pack_nr_srs_beamforming_report(&nr_srs_beamforming_report,
|
||||
gNB->srs_pdu_list[num_srs].report_tlv->value,
|
||||
16384*sizeof(uint32_t));
|
||||
srs_indication->report_tlv->length = pack_nr_srs_beamforming_report(&nr_srs_beamforming_report, srs_indication->report_tlv->value, 16384 * sizeof(uint32_t));
|
||||
break;
|
||||
}
|
||||
|
||||
case NR_SRS_ResourceSet__usage_codebook: {
|
||||
|
||||
nfapi_nr_srs_normalized_channel_iq_matrix_t nr_srs_normalized_channel_iq_matrix;
|
||||
nr_srs_normalized_channel_iq_matrix.normalized_iq_representation = srs_pdu->srs_parameters_v4.iq_representation;
|
||||
nr_srs_normalized_channel_iq_matrix.num_gnb_antenna_elements = gNB->frame_parms.nb_antennas_rx;
|
||||
nr_srs_normalized_channel_iq_matrix.num_ue_srs_ports = srs_pdu->srs_parameters_v4.num_total_ue_antennas;
|
||||
nr_srs_normalized_channel_iq_matrix.prg_size = srs_pdu->srs_parameters_v4.prg_size;
|
||||
nr_srs_normalized_channel_iq_matrix.num_prgs = srs_pdu->srs_parameters_v4.srs_bandwidth_size/srs_pdu->srs_parameters_v4.prg_size;
|
||||
nr_srs_normalized_channel_iq_matrix.num_prgs = srs_pdu->srs_parameters_v4.srs_bandwidth_size / srs_pdu->srs_parameters_v4.prg_size;
|
||||
fill_srs_channel_matrix(nr_srs_normalized_channel_iq_matrix.channel_matrix,
|
||||
srs_pdu,
|
||||
gNB->nr_srs_info[i],
|
||||
@@ -998,14 +1003,18 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
LOG_I(NR_PHY, "nr_srs_normalized_channel_iq_matrix.num_ue_srs_ports = %i\n", nr_srs_normalized_channel_iq_matrix.num_ue_srs_ports);
|
||||
LOG_I(NR_PHY, "nr_srs_normalized_channel_iq_matrix.prg_size = %i\n", nr_srs_normalized_channel_iq_matrix.prg_size);
|
||||
LOG_I(NR_PHY, "nr_srs_normalized_channel_iq_matrix.num_prgs = %i\n", nr_srs_normalized_channel_iq_matrix.num_prgs);
|
||||
c16_t *channel_matrix16 = (c16_t*)nr_srs_normalized_channel_iq_matrix.channel_matrix;
|
||||
c8_t *channel_matrix8 = (c8_t*)nr_srs_normalized_channel_iq_matrix.channel_matrix;
|
||||
for(int uI = 0; uI < nr_srs_normalized_channel_iq_matrix.num_ue_srs_ports; uI++) {
|
||||
for(int gI = 0; gI < nr_srs_normalized_channel_iq_matrix.num_gnb_antenna_elements; gI++) {
|
||||
for(int pI = 0; pI < nr_srs_normalized_channel_iq_matrix.num_prgs; pI++) {
|
||||
uint16_t index = uI*nr_srs_normalized_channel_iq_matrix.num_gnb_antenna_elements*nr_srs_normalized_channel_iq_matrix.num_prgs + gI*nr_srs_normalized_channel_iq_matrix.num_prgs + pI;
|
||||
LOG_I(NR_PHY, "(uI %i, gI %i, pI %i) channel_matrix --> real %i, imag %i\n",
|
||||
uI, gI, pI,
|
||||
c16_t *channel_matrix16 = (c16_t *)nr_srs_normalized_channel_iq_matrix.channel_matrix;
|
||||
c8_t *channel_matrix8 = (c8_t *)nr_srs_normalized_channel_iq_matrix.channel_matrix;
|
||||
for (int uI = 0; uI < nr_srs_normalized_channel_iq_matrix.num_ue_srs_ports; uI++) {
|
||||
for (int gI = 0; gI < nr_srs_normalized_channel_iq_matrix.num_gnb_antenna_elements; gI++) {
|
||||
for (int pI = 0; pI < nr_srs_normalized_channel_iq_matrix.num_prgs; pI++) {
|
||||
uint16_t index =
|
||||
uI * nr_srs_normalized_channel_iq_matrix.num_gnb_antenna_elements * nr_srs_normalized_channel_iq_matrix.num_prgs + gI * nr_srs_normalized_channel_iq_matrix.num_prgs + pI;
|
||||
LOG_I(NR_PHY,
|
||||
"(uI %i, gI %i, pI %i) channel_matrix --> real %i, imag %i\n",
|
||||
uI,
|
||||
gI,
|
||||
pI,
|
||||
nr_srs_normalized_channel_iq_matrix.normalized_iq_representation == 0 ? channel_matrix8[index].r : channel_matrix16[index].r,
|
||||
nr_srs_normalized_channel_iq_matrix.normalized_iq_representation == 0 ? channel_matrix8[index].i : channel_matrix16[index].i);
|
||||
}
|
||||
@@ -1013,9 +1022,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
}
|
||||
#endif
|
||||
|
||||
gNB->srs_pdu_list[num_srs].report_tlv->length = pack_nr_srs_normalized_channel_iq_matrix(&nr_srs_normalized_channel_iq_matrix,
|
||||
gNB->srs_pdu_list[num_srs].report_tlv->value,
|
||||
16384*sizeof(uint32_t));
|
||||
srs_indication->report_tlv->length = pack_nr_srs_normalized_channel_iq_matrix(&nr_srs_normalized_channel_iq_matrix,
|
||||
srs_indication->report_tlv->value,
|
||||
16384 * sizeof(uint32_t));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1026,15 +1035,15 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid SRS usage\n");
|
||||
AssertFatal(1 == 0, "Invalid SRS usage\n");
|
||||
}
|
||||
|
||||
#ifdef SRS_IND_DEBUG
|
||||
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].report_tlv->tag = %i\n", num_srs, gNB->srs_pdu_list[num_srs].report_tlv->tag);
|
||||
LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].report_tlv->length = %i\n", num_srs, gNB->srs_pdu_list[num_srs].report_tlv->length);
|
||||
char *value = (char*)gNB->srs_pdu_list[num_srs].report_tlv->value;
|
||||
for(int b = 0; b < gNB->srs_pdu_list[num_srs].report_tlv->length; b++) {
|
||||
LOG_I(NR_PHY, "value[%i] = 0x%02x\n", b, value[b]&0xFF);
|
||||
LOG_I(NR_PHY, "srs_indication->report_tlv->tag = %i\n", srs_indication->report_tlv->tag);
|
||||
LOG_I(NR_PHY, "srs_indication->report_tlv->length = %i\n", srs_indication->report_tlv->length);
|
||||
char *value = (char *)srs_indication->report_tlv->value;
|
||||
for (int b = 0; b < srs_indication->report_tlv->length; b++) {
|
||||
LOG_I(NR_PHY, "value[%i] = 0x%02x\n", b, value[b] & 0xFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -41,18 +41,14 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
|
||||
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
|
||||
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu);
|
||||
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
|
||||
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
|
||||
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa);
|
||||
void nr_init_feptx_thread(RU_t *ru);
|
||||
void nr_kill_feptx_thread(RU_t *ru);
|
||||
|
||||
void fep_full(RU_t *ru,int slot);
|
||||
void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx);
|
||||
void nr_init_feptx_prec_thread(RU_t *ru);
|
||||
void nr_feptx_prec_control(RU_t *ru,int frame,int tti_tx);
|
||||
void nr_init_feprx_thread(RU_t *ru);
|
||||
void nr_kill_feprx_thread(RU_t *ru);
|
||||
void nr_fep_full(RU_t *ru, int slot);
|
||||
void nr_fep_full_2thread(RU_t *ru, int slot);
|
||||
void nr_fep_tp(RU_t *ru, int slot);
|
||||
void nr_feptx_tp(RU_t *ru, int frame_tx, int slot);
|
||||
void feptx_prec(RU_t *ru,int frame_tx,int tti_tx);
|
||||
int nr_phy_init_RU(RU_t *ru);
|
||||
void nr_phy_free_RU(RU_t *ru);
|
||||
|
||||
@@ -1306,11 +1306,9 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc;
|
||||
proc_eNB->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
|
||||
proc_eNB->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
proc_eNB->threadPool = (tpool_t *)malloc(sizeof(tpool_t));
|
||||
proc_eNB->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initTpool("n", proc_eNB->threadPool, true);
|
||||
initNotifiedFIFO(proc_eNB->respEncode);
|
||||
initNotifiedFIFO(proc_eNB->respDecode);
|
||||
|
||||
proc_eNB->frame_tx=0;
|
||||
|
||||
@@ -814,11 +814,9 @@ int main(int argc, char **argv) {
|
||||
proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx);
|
||||
proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
|
||||
proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10;
|
||||
proc_rxtx->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
|
||||
proc_rxtx->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
proc_rxtx->threadPool = (tpool_t *)malloc(sizeof(tpool_t));
|
||||
proc_rxtx->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initTpool("n",proc_rxtx->threadPool, true);
|
||||
initNotifiedFIFO(proc_rxtx->respEncode);
|
||||
initTpool("n", proc_rxtx->threadPool, true);
|
||||
initNotifiedFIFO(proc_rxtx->respDecode);
|
||||
|
||||
printf("Init UL hopping UE\n");
|
||||
@@ -1533,7 +1531,7 @@ int main(int argc, char **argv) {
|
||||
}//ch realization
|
||||
|
||||
oai_exit=1;
|
||||
pthread_cond_signal(&ru->proc.cond_fep);
|
||||
pthread_cond_signal(&ru->proc.cond_fep[0]);
|
||||
|
||||
if (abstx) { // ABSTRACTION
|
||||
fprintf(csv_fdUL,"];");
|
||||
|
||||
@@ -1063,7 +1063,6 @@ int main(int argc, char **argv)
|
||||
double blerStats[4][100];
|
||||
double berStats[4][100];
|
||||
double snrStats[100];
|
||||
double ldpcDecStats[100] = {0};
|
||||
memset(errors_scrambling, 0, sizeof(uint32_t)*4*100);
|
||||
memset(n_errors, 0, sizeof(int)*4*100);
|
||||
memset(round_trials, 0, sizeof(int)*4*100);
|
||||
@@ -1633,8 +1632,6 @@ int main(int argc, char **argv)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
ldpcDecStats[snrRun] = gNB->ulsch_decoding_stats.trials?inMicroS(gNB->ulsch_decoding_stats.diff/gNB->ulsch_decoding_stats.trials):0;
|
||||
|
||||
if(n_trials==1)
|
||||
break;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ set(DEBUG_DLSCH True)
|
||||
set(T_TRACER False)
|
||||
|
||||
# standard cmake file for nr ue build
|
||||
include(../../../../../cmake_targets/CMakeLists.txt)
|
||||
include(../../../../../CMakeLists.txt)
|
||||
|
||||
|
||||
set(SRC_UNIT_TESTS
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
add_subdirectory(E1AP)
|
||||
@@ -0,0 +1,7 @@
|
||||
add_subdirectory(MESSAGES)
|
||||
|
||||
add_library(E1AP e1ap.c)
|
||||
target_link_libraries(E1AP
|
||||
PUBLIC asn1_e1ap
|
||||
PRIVATE UTIL)
|
||||
target_include_directories(E1AP PUBLIC ${CMAKE_CURRENT_DIR})
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,941 @@
|
||||
set(E1AP_GRAMMAR ASN.1/38463-g80.R16.78.0.asn)
|
||||
|
||||
set(e1ap_source
|
||||
ANY.c
|
||||
asn_application.c
|
||||
asn_bit_data.c
|
||||
asn_codecs_prim.c
|
||||
asn_internal.c
|
||||
asn_random_fill.c
|
||||
asn_SEQUENCE_OF.c
|
||||
asn_SET_OF.c
|
||||
ber_decoder.c
|
||||
ber_tlv_length.c
|
||||
ber_tlv_tag.c
|
||||
BIT_STRING.c
|
||||
constraints.c
|
||||
constr_CHOICE.c
|
||||
constr_SEQUENCE.c
|
||||
constr_SEQUENCE_OF.c
|
||||
constr_SET_OF.c
|
||||
constr_TYPE.c
|
||||
der_encoder.c
|
||||
E1AP_ActivityInformation.c
|
||||
E1AP_ActivityNotificationLevel.c
|
||||
E1AP_AdditionalHandoverInfo.c
|
||||
E1AP_AdditionalPDCPduplicationInformation.c
|
||||
E1AP_AdditionalRRMPriorityIndex.c
|
||||
E1AP_AlternativeQoSParaSetItem.c
|
||||
E1AP_AlternativeQoSParaSetList.c
|
||||
E1AP_AveragingWindow.c
|
||||
E1AP_BearerContextInactivityNotification.c
|
||||
E1AP_BearerContextModificationConfirm.c
|
||||
E1AP_BearerContextModificationFailure.c
|
||||
E1AP_BearerContextModificationRequest.c
|
||||
E1AP_BearerContextModificationRequired.c
|
||||
E1AP_BearerContextModificationResponse.c
|
||||
E1AP_BearerContextReleaseCommand.c
|
||||
E1AP_BearerContextReleaseComplete.c
|
||||
E1AP_BearerContextReleaseRequest.c
|
||||
E1AP_BearerContextSetupFailure.c
|
||||
E1AP_BearerContextSetupRequest.c
|
||||
E1AP_BearerContextSetupResponse.c
|
||||
E1AP_BearerContextStatusChange.c
|
||||
E1AP_BitRate.c
|
||||
E1AP_BurstArrivalTime.c
|
||||
E1AP_Cause.c
|
||||
E1AP_CauseMisc.c
|
||||
E1AP_CauseProtocol.c
|
||||
E1AP_CauseRadioNetwork.c
|
||||
E1AP_CauseTransport.c
|
||||
E1AP_Cell-Group-ID.c
|
||||
E1AP_Cell-Group-Information.c
|
||||
E1AP_Cell-Group-Information-Item.c
|
||||
E1AP_CellTrafficTrace.c
|
||||
E1AP_CHOInitiation.c
|
||||
E1AP_CipheringAlgorithm.c
|
||||
E1AP_CNSupport.c
|
||||
E1AP_CommonNetworkInstance.c
|
||||
E1AP_ConfidentialityProtectionIndication.c
|
||||
E1AP_ConfidentialityProtectionResult.c
|
||||
E1AP_CP-TNL-Information.c
|
||||
E1AP_Criticality.c
|
||||
E1AP_CriticalityDiagnostics.c
|
||||
E1AP_CriticalityDiagnostics-IE-List.c
|
||||
E1AP_DAPSRequestInfo.c
|
||||
E1AP_DataDiscardRequired.c
|
||||
E1AP_Data-Forwarding-Information.c
|
||||
E1AP_Data-Forwarding-Information-Request.c
|
||||
E1AP_Data-Forwarding-Request.c
|
||||
E1AP_DataForwardingtoE-UTRANInformationList.c
|
||||
E1AP_DataForwardingtoE-UTRANInformationListItem.c
|
||||
E1AP_DataForwardingtoNG-RANQoSFlowInformationList.c
|
||||
E1AP_DataForwardingtoNG-RANQoSFlowInformationList-Item.c
|
||||
E1AP_Data-Usage-per-PDU-Session-Report.c
|
||||
E1AP_Data-Usage-per-QoS-Flow-Item.c
|
||||
E1AP_Data-Usage-per-QoS-Flow-List.c
|
||||
E1AP_DataUsageReport.c
|
||||
E1AP_Data-Usage-Report-Item.c
|
||||
E1AP_Data-Usage-Report-List.c
|
||||
E1AP_DeactivateTrace.c
|
||||
E1AP_DefaultDRB.c
|
||||
E1AP_DirectForwardingPathAvailability.c
|
||||
E1AP_DiscardTimer.c
|
||||
E1AP_DLDataNotification.c
|
||||
E1AP_DLDiscarding.c
|
||||
E1AP_DL-TX-Stop.c
|
||||
E1AP_DLUPTNLAddressToUpdateItem.c
|
||||
E1AP_DLUPTNLAddressToUpdateList.c
|
||||
E1AP_DRB-Activity.c
|
||||
E1AP_DRB-Activity-Item.c
|
||||
E1AP_DRB-Activity-List.c
|
||||
E1AP_DRBBStatusTransfer.c
|
||||
E1AP_DRB-Confirm-Modified-Item-EUTRAN.c
|
||||
E1AP_DRB-Confirm-Modified-Item-NG-RAN.c
|
||||
E1AP_DRB-Confirm-Modified-List-EUTRAN.c
|
||||
E1AP_DRB-Confirm-Modified-List-NG-RAN.c
|
||||
E1AP_DRB-Failed-Item-EUTRAN.c
|
||||
E1AP_DRB-Failed-Item-NG-RAN.c
|
||||
E1AP_DRB-Failed-List-EUTRAN.c
|
||||
E1AP_DRB-Failed-List-NG-RAN.c
|
||||
E1AP_DRB-Failed-Mod-Item-EUTRAN.c
|
||||
E1AP_DRB-Failed-Mod-Item-NG-RAN.c
|
||||
E1AP_DRB-Failed-Mod-List-EUTRAN.c
|
||||
E1AP_DRB-Failed-Mod-List-NG-RAN.c
|
||||
E1AP_DRB-Failed-To-Modify-Item-EUTRAN.c
|
||||
E1AP_DRB-Failed-To-Modify-Item-NG-RAN.c
|
||||
E1AP_DRB-Failed-To-Modify-List-EUTRAN.c
|
||||
E1AP_DRB-Failed-To-Modify-List-NG-RAN.c
|
||||
E1AP_DRB-ID.c
|
||||
E1AP_DRB-Measurement-Results-Information-Item.c
|
||||
E1AP_DRB-Measurement-Results-Information-List.c
|
||||
E1AP_DRB-Modified-Item-EUTRAN.c
|
||||
E1AP_DRB-Modified-Item-NG-RAN.c
|
||||
E1AP_DRB-Modified-List-EUTRAN.c
|
||||
E1AP_DRB-Modified-List-NG-RAN.c
|
||||
E1AP_DRB-Removed-Item.c
|
||||
E1AP_DRB-Required-To-Modify-Item-EUTRAN.c
|
||||
E1AP_DRB-Required-To-Modify-Item-NG-RAN.c
|
||||
E1AP_DRB-Required-To-Modify-List-EUTRAN.c
|
||||
E1AP_DRB-Required-To-Modify-List-NG-RAN.c
|
||||
E1AP_DRB-Required-To-Remove-Item-EUTRAN.c
|
||||
E1AP_DRB-Required-To-Remove-Item-NG-RAN.c
|
||||
E1AP_DRB-Required-To-Remove-List-EUTRAN.c
|
||||
E1AP_DRB-Required-To-Remove-List-NG-RAN.c
|
||||
E1AP_DRB-Setup-Item-EUTRAN.c
|
||||
E1AP_DRB-Setup-Item-NG-RAN.c
|
||||
E1AP_DRB-Setup-List-EUTRAN.c
|
||||
E1AP_DRB-Setup-List-NG-RAN.c
|
||||
E1AP_DRB-Setup-Mod-Item-EUTRAN.c
|
||||
E1AP_DRB-Setup-Mod-Item-NG-RAN.c
|
||||
E1AP_DRB-Setup-Mod-List-EUTRAN.c
|
||||
E1AP_DRB-Setup-Mod-List-NG-RAN.c
|
||||
E1AP_DRBs-Subject-To-Counter-Check-Item-EUTRAN.c
|
||||
E1AP_DRBs-Subject-To-Counter-Check-Item-NG-RAN.c
|
||||
E1AP_DRBs-Subject-To-Counter-Check-List-EUTRAN.c
|
||||
E1AP_DRBs-Subject-To-Counter-Check-List-NG-RAN.c
|
||||
E1AP_DRBs-Subject-To-Early-Forwarding-Item.c
|
||||
E1AP_DRBs-Subject-To-Early-Forwarding-List.c
|
||||
E1AP_DRB-Status-Item.c
|
||||
E1AP_DRB-Status-List.c
|
||||
E1AP_DRB-To-Modify-Item-EUTRAN.c
|
||||
E1AP_DRB-To-Modify-Item-NG-RAN.c
|
||||
E1AP_DRB-To-Modify-List-EUTRAN.c
|
||||
E1AP_DRB-To-Modify-List-NG-RAN.c
|
||||
E1AP_DRB-To-Remove-Item-EUTRAN.c
|
||||
E1AP_DRB-To-Remove-Item-NG-RAN.c
|
||||
E1AP_DRB-To-Remove-List-EUTRAN.c
|
||||
E1AP_DRB-To-Remove-List-NG-RAN.c
|
||||
E1AP_DRB-To-Setup-Item-EUTRAN.c
|
||||
E1AP_DRB-To-Setup-Item-NG-RAN.c
|
||||
E1AP_DRB-To-Setup-List-EUTRAN.c
|
||||
E1AP_DRB-To-Setup-List-NG-RAN.c
|
||||
E1AP_DRB-To-Setup-Mod-Item-EUTRAN.c
|
||||
E1AP_DRB-To-Setup-Mod-Item-NG-RAN.c
|
||||
E1AP_DRB-To-Setup-Mod-List-EUTRAN.c
|
||||
E1AP_DRB-To-Setup-Mod-List-NG-RAN.c
|
||||
E1AP_DRB-Usage-Report-Item.c
|
||||
E1AP_DRB-Usage-Report-List.c
|
||||
E1AP_Duplication-Activation.c
|
||||
E1AP_Dynamic5QIDescriptor.c
|
||||
E1AP_E1AP-PDU.c
|
||||
E1AP_E1ReleaseRequest.c
|
||||
E1AP_E1ReleaseResponse.c
|
||||
E1AP_EarlyDataForwardingIndicator.c
|
||||
E1AP_EarlyForwardingCOUNTInfo.c
|
||||
E1AP_EarlyForwardingCOUNTReq.c
|
||||
E1AP_EarlyForwardingSNTransfer.c
|
||||
E1AP_EHC-Common-Parameters.c
|
||||
E1AP_EHC-Downlink-Parameters.c
|
||||
E1AP_EHC-Parameters.c
|
||||
E1AP_EHC-Uplink-Parameters.c
|
||||
E1AP_EncryptionKey.c
|
||||
E1AP_Endpoint-IP-address-and-port.c
|
||||
E1AP_ErrorIndication.c
|
||||
E1AP_EUTRANAllocationAndRetentionPriority.c
|
||||
E1AP_EUTRAN-QoS.c
|
||||
E1AP_EUTRAN-QoS-Support-Item.c
|
||||
E1AP_EUTRAN-QoS-Support-List.c
|
||||
E1AP_Extended-GNB-CU-CP-Name.c
|
||||
E1AP_Extended-GNB-CU-UP-Name.c
|
||||
E1AP_Extended-NR-CGI-Support-Item.c
|
||||
E1AP_Extended-NR-CGI-Support-List.c
|
||||
E1AP_ExtendedPacketDelayBudget.c
|
||||
E1AP_ExtendedSliceSupportList.c
|
||||
E1AP_FirstDLCount.c
|
||||
E1AP_GBR-QoSFlowInformation.c
|
||||
E1AP_GBR-QosInformation.c
|
||||
E1AP_GNB-CU-CP-ConfigurationUpdateAcknowledge.c
|
||||
E1AP_GNB-CU-CP-ConfigurationUpdate.c
|
||||
E1AP_GNB-CU-CP-ConfigurationUpdateFailure.c
|
||||
E1AP_GNB-CU-CP-E1SetupFailure.c
|
||||
E1AP_GNB-CU-CP-E1SetupRequest.c
|
||||
E1AP_GNB-CU-CP-E1SetupResponse.c
|
||||
E1AP_GNB-CU-CPMeasurementResultsInformation.c
|
||||
E1AP_GNB-CU-CP-Name.c
|
||||
E1AP_GNB-CU-CP-NameUTF8String.c
|
||||
E1AP_GNB-CU-CP-NameVisibleString.c
|
||||
E1AP_GNB-CU-CP-TNLA-Failed-To-Setup-Item.c
|
||||
E1AP_GNB-CU-CP-TNLA-Failed-To-Setup-List.c
|
||||
E1AP_GNB-CU-CP-TNLA-Setup-Item.c
|
||||
E1AP_GNB-CU-CP-TNLA-Setup-List.c
|
||||
E1AP_GNB-CU-CP-TNLA-To-Add-Item.c
|
||||
E1AP_GNB-CU-CP-TNLA-To-Add-List.c
|
||||
E1AP_GNB-CU-CP-TNLA-To-Remove-Item.c
|
||||
E1AP_GNB-CU-CP-TNLA-To-Remove-List.c
|
||||
E1AP_GNB-CU-CP-TNLA-To-Update-Item.c
|
||||
E1AP_GNB-CU-CP-TNLA-To-Update-List.c
|
||||
E1AP_GNB-CU-CP-UE-E1AP-ID.c
|
||||
E1AP_GNB-CU-UP-Capacity.c
|
||||
E1AP_GNB-CU-UP-CellGroupRelatedConfiguration.c
|
||||
E1AP_GNB-CU-UP-CellGroupRelatedConfiguration-Item.c
|
||||
E1AP_GNB-CU-UP-ConfigurationUpdateAcknowledge.c
|
||||
E1AP_GNB-CU-UP-ConfigurationUpdate.c
|
||||
E1AP_GNB-CU-UP-ConfigurationUpdateFailure.c
|
||||
E1AP_GNB-CU-UP-CounterCheckRequest.c
|
||||
E1AP_GNB-CU-UP-E1SetupFailure.c
|
||||
E1AP_GNB-CU-UP-E1SetupRequest.c
|
||||
E1AP_GNB-CU-UP-E1SetupResponse.c
|
||||
E1AP_GNB-CU-UP-ID.c
|
||||
E1AP_GNB-CU-UP-Name.c
|
||||
E1AP_GNB-CU-UP-NameUTF8String.c
|
||||
E1AP_GNB-CU-UP-NameVisibleString.c
|
||||
E1AP_GNB-CU-UP-OverloadInformation.c
|
||||
E1AP_GNB-CU-UP-StatusIndication.c
|
||||
E1AP_GNB-CU-UP-TNLA-To-Remove-Item.c
|
||||
E1AP_GNB-CU-UP-TNLA-To-Remove-List.c
|
||||
E1AP_GNB-CU-UP-UE-E1AP-ID.c
|
||||
E1AP_GNB-DU-ID.c
|
||||
E1AP_GTP-TEID.c
|
||||
E1AP_GTPTLA-Item.c
|
||||
E1AP_GTPTLAs.c
|
||||
E1AP_GTPTunnel.c
|
||||
E1AP_HFN.c
|
||||
E1AP_HW-CapacityIndicator.c
|
||||
E1AP_IAB-UPTNLAddressUpdateAcknowledge.c
|
||||
E1AP_IAB-UPTNLAddressUpdate.c
|
||||
E1AP_IAB-UPTNLAddressUpdateFailure.c
|
||||
E1AP_IgnoreMappingRuleIndication.c
|
||||
E1AP_ImmediateMDT.c
|
||||
E1AP_Inactivity-Timer.c
|
||||
E1AP_InitiatingMessage.c
|
||||
E1AP_IntegrityProtectionAlgorithm.c
|
||||
E1AP_IntegrityProtectionIndication.c
|
||||
E1AP_IntegrityProtectionKey.c
|
||||
E1AP_IntegrityProtectionResult.c
|
||||
E1AP_InterfacesToTrace.c
|
||||
E1AP_Links-to-log.c
|
||||
E1AP_M4Configuration.c
|
||||
E1AP_M4period.c
|
||||
E1AP_M6Configuration.c
|
||||
E1AP_M6report-Interval.c
|
||||
E1AP_M7Configuration.c
|
||||
E1AP_M7period.c
|
||||
E1AP_MaxCIDEHCDL.c
|
||||
E1AP_MaxDataBurstVolume.c
|
||||
E1AP_MaximumIPdatarate.c
|
||||
E1AP_MaxIPrate.c
|
||||
E1AP_MaxPacketLossRate.c
|
||||
E1AP_MDT-Activation.c
|
||||
E1AP_MDT-Configuration.c
|
||||
E1AP_MDTMode.c
|
||||
E1AP_MDTPLMNList.c
|
||||
E1AP_MeasurementsToActivate.c
|
||||
E1AP_MRDC-DataUsageReport.c
|
||||
E1AP_MRDC-Data-Usage-Report-Item.c
|
||||
E1AP_MRDC-Usage-Information.c
|
||||
E1AP_NetworkInstance.c
|
||||
E1AP_New-UL-TNL-Information-Required.c
|
||||
E1AP_NGRANAllocationAndRetentionPriority.c
|
||||
E1AP_NG-RAN-QoS-Support-Item.c
|
||||
E1AP_NG-RAN-QoS-Support-List.c
|
||||
E1AP_NID.c
|
||||
E1AP_Non-Dynamic5QIDescriptor.c
|
||||
E1AP_NPNContextInfo.c
|
||||
E1AP_NPNContextInfo-SNPN.c
|
||||
E1AP_NPNSupportInfo.c
|
||||
E1AP_NPNSupportInfo-SNPN.c
|
||||
E1AP_NR-Cell-Identity.c
|
||||
E1AP_NR-CGI.c
|
||||
E1AP_NR-CGI-Support-Item.c
|
||||
E1AP_NR-CGI-Support-List.c
|
||||
E1AP_Number-of-tunnels.c
|
||||
E1AP_OutOfOrderDelivery.c
|
||||
E1AP_PacketDelayBudget.c
|
||||
E1AP_PacketErrorRate.c
|
||||
E1AP_PDCP-Configuration.c
|
||||
E1AP_PDCP-Count.c
|
||||
E1AP_PDCP-DataRecovery.c
|
||||
E1AP_PDCP-Duplication.c
|
||||
E1AP_PDCP-Reestablishment.c
|
||||
E1AP_PDCP-SN.c
|
||||
E1AP_PDCP-SN-Size.c
|
||||
E1AP_PDCP-SN-Status-Information.c
|
||||
E1AP_PDCP-SN-Status-Request.c
|
||||
E1AP_PDCP-StatusReportIndication.c
|
||||
E1AP_PDU-Session-ID.c
|
||||
E1AP_PDU-Session-Resource-Activity.c
|
||||
E1AP_PDU-Session-Resource-Activity-Item.c
|
||||
E1AP_PDU-Session-Resource-Activity-List.c
|
||||
E1AP_PDU-Session-Resource-Confirm-Modified-Item.c
|
||||
E1AP_PDU-Session-Resource-Confirm-Modified-List.c
|
||||
E1AP_PDU-Session-Resource-Data-Usage-Item.c
|
||||
E1AP_PDU-Session-Resource-Data-Usage-List.c
|
||||
E1AP_PDU-Session-Resource-Failed-Item.c
|
||||
E1AP_PDU-Session-Resource-Failed-List.c
|
||||
E1AP_PDU-Session-Resource-Failed-Mod-Item.c
|
||||
E1AP_PDU-Session-Resource-Failed-Mod-List.c
|
||||
E1AP_PDU-Session-Resource-Failed-To-Modify-Item.c
|
||||
E1AP_PDU-Session-Resource-Failed-To-Modify-List.c
|
||||
E1AP_PDU-Session-Resource-Modified-Item.c
|
||||
E1AP_PDU-Session-Resource-Modified-List.c
|
||||
E1AP_PDU-Session-Resource-Required-To-Modify-Item.c
|
||||
E1AP_PDU-Session-Resource-Required-To-Modify-List.c
|
||||
E1AP_PDU-Session-Resource-Setup-Item.c
|
||||
E1AP_PDU-Session-Resource-Setup-List.c
|
||||
E1AP_PDU-Session-Resource-Setup-Mod-Item.c
|
||||
E1AP_PDU-Session-Resource-Setup-Mod-List.c
|
||||
E1AP_PDU-Session-Resource-To-Modify-Item.c
|
||||
E1AP_PDU-Session-Resource-To-Modify-List.c
|
||||
E1AP_PDU-Session-Resource-To-Remove-Item.c
|
||||
E1AP_PDU-Session-Resource-To-Remove-List.c
|
||||
E1AP_PDU-Session-Resource-To-Setup-Item.c
|
||||
E1AP_PDU-Session-Resource-To-Setup-List.c
|
||||
E1AP_PDU-Session-Resource-To-Setup-Mod-Item.c
|
||||
E1AP_PDU-Session-Resource-To-Setup-Mod-List.c
|
||||
E1AP_PDU-Session-To-Notify-Item.c
|
||||
E1AP_PDU-Session-To-Notify-List.c
|
||||
E1AP_PDU-Session-Type.c
|
||||
E1AP_PER-Exponent.c
|
||||
E1AP_Periodicity.c
|
||||
E1AP_PER-Scalar.c
|
||||
E1AP_PLMN-Identity.c
|
||||
E1AP_PortNumber.c
|
||||
E1AP_PPI.c
|
||||
E1AP_Pre-emptionCapability.c
|
||||
E1AP_Pre-emptionVulnerability.c
|
||||
E1AP_Presence.c
|
||||
E1AP_PriorityLevel.c
|
||||
E1AP_PrivacyIndicator.c
|
||||
E1AP_PrivateIE-Container.c
|
||||
E1AP_PrivateIE-Field.c
|
||||
E1AP_PrivateIE-ID.c
|
||||
E1AP_PrivateMessage.c
|
||||
E1AP_ProcedureCode.c
|
||||
E1AP_ProtocolExtensionContainer.c
|
||||
E1AP_ProtocolExtensionField.c
|
||||
E1AP_ProtocolExtensionID.c
|
||||
E1AP_ProtocolIE-Container.c
|
||||
E1AP_ProtocolIE-ContainerList.c
|
||||
E1AP_ProtocolIE-Field.c
|
||||
E1AP_ProtocolIE-ID.c
|
||||
E1AP_ProtocolIE-SingleContainer.c
|
||||
E1AP_QCI.c
|
||||
E1AP_QoS-Characteristics.c
|
||||
E1AP_QoS-Flow-Failed-Item.c
|
||||
E1AP_QoS-Flow-Failed-List.c
|
||||
E1AP_QoS-Flow-Identifier.c
|
||||
E1AP_QoS-Flow-Item.c
|
||||
E1AP_QoSFlowLevelQoSParameters.c
|
||||
E1AP_QoS-Flow-List.c
|
||||
E1AP_QoS-Flow-Mapping-Indication.c
|
||||
E1AP_QoS-Flow-Mapping-Item.c
|
||||
E1AP_QoS-Flow-Mapping-List.c
|
||||
E1AP_QoS-Flow-QoS-Parameter-Item.c
|
||||
E1AP_QoS-Flow-QoS-Parameter-List.c
|
||||
E1AP_QoS-Flow-Removed-Item.c
|
||||
E1AP_QoS-Flows-DRB-Remapping.c
|
||||
E1AP_QoS-Flows-to-be-forwarded-Item.c
|
||||
E1AP_QoS-Flows-to-be-forwarded-List.c
|
||||
E1AP_QoS-Mapping-Information.c
|
||||
E1AP_QosMonitoringDisabled.c
|
||||
E1AP_QosMonitoringReportingFrequency.c
|
||||
E1AP_QosMonitoringRequest.c
|
||||
E1AP_QoS-Parameters-Support-List.c
|
||||
E1AP_QoSPriorityLevel.c
|
||||
E1AP_RANUEID.c
|
||||
E1AP_RAT-Type.c
|
||||
E1AP_RedundantPDUSessionInformation.c
|
||||
E1AP_RedundantQoSFlowIndicator.c
|
||||
E1AP_RegistrationRequest.c
|
||||
E1AP_ReportCharacteristics.c
|
||||
E1AP_ReportingPeriodicity.c
|
||||
E1AP_ResetAcknowledge.c
|
||||
E1AP_ResetAll.c
|
||||
E1AP_Reset.c
|
||||
E1AP_ResetType.c
|
||||
E1AP_ResourceStatusFailure.c
|
||||
E1AP_ResourceStatusRequest.c
|
||||
E1AP_ResourceStatusResponse.c
|
||||
E1AP_ResourceStatusUpdate.c
|
||||
E1AP_RetainabilityMeasurementsInfo.c
|
||||
E1AP_RLC-Mode.c
|
||||
E1AP_ROHC.c
|
||||
E1AP_ROHC-Parameters.c
|
||||
E1AP_RSN.c
|
||||
E1AP_SDAP-Configuration.c
|
||||
E1AP_SDAP-Header-DL.c
|
||||
E1AP_SDAP-Header-UL.c
|
||||
E1AP_SecurityAlgorithm.c
|
||||
E1AP_SecurityIndication.c
|
||||
E1AP_SecurityInformation.c
|
||||
E1AP_SecurityResult.c
|
||||
E1AP_Slice-Support-Item.c
|
||||
E1AP_Slice-Support-List.c
|
||||
E1AP_SNSSAI.c
|
||||
E1AP_SubscriberProfileIDforRFP.c
|
||||
E1AP_SuccessfulOutcome.c
|
||||
E1AP_SupportedPLMNs-Item.c
|
||||
E1AP_SupportedPLMNs-List.c
|
||||
E1AP_System-BearerContextModificationConfirm.c
|
||||
E1AP_System-BearerContextModificationRequest.c
|
||||
E1AP_System-BearerContextModificationRequired.c
|
||||
E1AP_System-BearerContextModificationResponse.c
|
||||
E1AP_System-BearerContextSetupRequest.c
|
||||
E1AP_System-BearerContextSetupResponse.c
|
||||
E1AP_System-GNB-CU-UP-CounterCheckRequest.c
|
||||
E1AP_TimeToWait.c
|
||||
E1AP_TNLAssociationUsage.c
|
||||
E1AP_TNL-AvailableCapacityIndicator.c
|
||||
E1AP_TraceActivation.c
|
||||
E1AP_TraceDepth.c
|
||||
E1AP_TraceID.c
|
||||
E1AP_TraceStart.c
|
||||
E1AP_TransactionID.c
|
||||
E1AP_TransportLayerAddress.c
|
||||
E1AP_Transport-Layer-Address-Info.c
|
||||
E1AP_Transport-UP-Layer-Addresses-Info-To-Add-Item.c
|
||||
E1AP_Transport-UP-Layer-Addresses-Info-To-Add-List.c
|
||||
E1AP_Transport-UP-Layer-Addresses-Info-To-Remove-Item.c
|
||||
E1AP_Transport-UP-Layer-Addresses-Info-To-Remove-List.c
|
||||
E1AP_T-Reordering.c
|
||||
E1AP_T-ReorderingTimer.c
|
||||
E1AP_TriggeringMessage.c
|
||||
E1AP_TSCTrafficCharacteristics.c
|
||||
E1AP_TSCTrafficInformation.c
|
||||
E1AP_TypeOfError.c
|
||||
E1AP_UE-Activity.c
|
||||
E1AP_UE-associatedLogicalE1-ConnectionItem.c
|
||||
E1AP_UE-associatedLogicalE1-ConnectionListResAck.c
|
||||
E1AP_UE-associatedLogicalE1-ConnectionListRes.c
|
||||
E1AP_UL-Configuration.c
|
||||
E1AP_ULDataNotification.c
|
||||
E1AP_ULDataSplitThreshold.c
|
||||
E1AP_ULUPTNLAddressToUpdateItem.c
|
||||
E1AP_ULUPTNLAddressToUpdateList.c
|
||||
E1AP_UnsuccessfulOutcome.c
|
||||
E1AP_UplinkOnlyROHC.c
|
||||
E1AP_UP-Parameters.c
|
||||
E1AP_UP-Parameters-Item.c
|
||||
E1AP_UPSecuritykey.c
|
||||
E1AP_UP-TNL-Information.c
|
||||
E1AP_URIaddress.c
|
||||
INTEGER.c
|
||||
NativeEnumerated.c
|
||||
NativeInteger.c
|
||||
OBJECT_IDENTIFIER.c
|
||||
OCTET_STRING.c
|
||||
OPEN_TYPE.c
|
||||
per_decoder.c
|
||||
per_encoder.c
|
||||
per_opentype.c
|
||||
per_support.c
|
||||
PrintableString.c
|
||||
UTF8String.c
|
||||
VisibleString.c
|
||||
xer_decoder.c
|
||||
xer_encoder.c
|
||||
xer_support.c
|
||||
)
|
||||
|
||||
set(e1ap_headers
|
||||
ANY.h
|
||||
asn_application.h
|
||||
asn_bit_data.h
|
||||
asn_codecs.h
|
||||
asn_codecs_prim.h
|
||||
asn_internal.h
|
||||
asn_ioc.h
|
||||
asn_random_fill.h
|
||||
asn_SEQUENCE_OF.h
|
||||
asn_SET_OF.h
|
||||
asn_system.h
|
||||
ber_decoder.h
|
||||
ber_tlv_length.h
|
||||
ber_tlv_tag.h
|
||||
BIT_STRING.h
|
||||
constraints.h
|
||||
constr_CHOICE.h
|
||||
constr_SEQUENCE.h
|
||||
constr_SEQUENCE_OF.h
|
||||
constr_SET_OF.h
|
||||
constr_TYPE.h
|
||||
der_encoder.h
|
||||
E1AP_ActivityInformation.h
|
||||
E1AP_ActivityNotificationLevel.h
|
||||
E1AP_AdditionalHandoverInfo.h
|
||||
E1AP_AdditionalPDCPduplicationInformation.h
|
||||
E1AP_AdditionalRRMPriorityIndex.h
|
||||
E1AP_AlternativeQoSParaSetItem.h
|
||||
E1AP_AlternativeQoSParaSetList.h
|
||||
E1AP_asn_constant.h
|
||||
E1AP_AveragingWindow.h
|
||||
E1AP_BearerContextInactivityNotification.h
|
||||
E1AP_BearerContextModificationConfirm.h
|
||||
E1AP_BearerContextModificationFailure.h
|
||||
E1AP_BearerContextModificationRequest.h
|
||||
E1AP_BearerContextModificationRequired.h
|
||||
E1AP_BearerContextModificationResponse.h
|
||||
E1AP_BearerContextReleaseCommand.h
|
||||
E1AP_BearerContextReleaseComplete.h
|
||||
E1AP_BearerContextReleaseRequest.h
|
||||
E1AP_BearerContextSetupFailure.h
|
||||
E1AP_BearerContextSetupRequest.h
|
||||
E1AP_BearerContextSetupResponse.h
|
||||
E1AP_BearerContextStatusChange.h
|
||||
E1AP_BitRate.h
|
||||
E1AP_BurstArrivalTime.h
|
||||
E1AP_Cause.h
|
||||
E1AP_CauseMisc.h
|
||||
E1AP_CauseProtocol.h
|
||||
E1AP_CauseRadioNetwork.h
|
||||
E1AP_CauseTransport.h
|
||||
E1AP_Cell-Group-ID.h
|
||||
E1AP_Cell-Group-Information.h
|
||||
E1AP_Cell-Group-Information-Item.h
|
||||
E1AP_CellTrafficTrace.h
|
||||
E1AP_CHOInitiation.h
|
||||
E1AP_CipheringAlgorithm.h
|
||||
E1AP_CNSupport.h
|
||||
E1AP_CommonNetworkInstance.h
|
||||
E1AP_ConfidentialityProtectionIndication.h
|
||||
E1AP_ConfidentialityProtectionResult.h
|
||||
E1AP_CP-TNL-Information.h
|
||||
E1AP_CriticalityDiagnostics.h
|
||||
E1AP_CriticalityDiagnostics-IE-List.h
|
||||
E1AP_Criticality.h
|
||||
E1AP_DAPSRequestInfo.h
|
||||
E1AP_DataDiscardRequired.h
|
||||
E1AP_Data-Forwarding-Information.h
|
||||
E1AP_Data-Forwarding-Information-Request.h
|
||||
E1AP_Data-Forwarding-Request.h
|
||||
E1AP_DataForwardingtoE-UTRANInformationList.h
|
||||
E1AP_DataForwardingtoE-UTRANInformationListItem.h
|
||||
E1AP_DataForwardingtoNG-RANQoSFlowInformationList.h
|
||||
E1AP_DataForwardingtoNG-RANQoSFlowInformationList-Item.h
|
||||
E1AP_Data-Usage-per-PDU-Session-Report.h
|
||||
E1AP_Data-Usage-per-QoS-Flow-Item.h
|
||||
E1AP_Data-Usage-per-QoS-Flow-List.h
|
||||
E1AP_DataUsageReport.h
|
||||
E1AP_Data-Usage-Report-Item.h
|
||||
E1AP_Data-Usage-Report-List.h
|
||||
E1AP_DeactivateTrace.h
|
||||
E1AP_DefaultDRB.h
|
||||
E1AP_DirectForwardingPathAvailability.h
|
||||
E1AP_DiscardTimer.h
|
||||
E1AP_DLDataNotification.h
|
||||
E1AP_DLDiscarding.h
|
||||
E1AP_DL-TX-Stop.h
|
||||
E1AP_DLUPTNLAddressToUpdateItem.h
|
||||
E1AP_DLUPTNLAddressToUpdateList.h
|
||||
E1AP_DRB-Activity.h
|
||||
E1AP_DRB-Activity-Item.h
|
||||
E1AP_DRB-Activity-List.h
|
||||
E1AP_DRBBStatusTransfer.h
|
||||
E1AP_DRB-Confirm-Modified-Item-EUTRAN.h
|
||||
E1AP_DRB-Confirm-Modified-Item-NG-RAN.h
|
||||
E1AP_DRB-Confirm-Modified-List-EUTRAN.h
|
||||
E1AP_DRB-Confirm-Modified-List-NG-RAN.h
|
||||
E1AP_DRB-Failed-Item-EUTRAN.h
|
||||
E1AP_DRB-Failed-Item-NG-RAN.h
|
||||
E1AP_DRB-Failed-List-EUTRAN.h
|
||||
E1AP_DRB-Failed-List-NG-RAN.h
|
||||
E1AP_DRB-Failed-Mod-Item-EUTRAN.h
|
||||
E1AP_DRB-Failed-Mod-Item-NG-RAN.h
|
||||
E1AP_DRB-Failed-Mod-List-EUTRAN.h
|
||||
E1AP_DRB-Failed-Mod-List-NG-RAN.h
|
||||
E1AP_DRB-Failed-To-Modify-Item-EUTRAN.h
|
||||
E1AP_DRB-Failed-To-Modify-Item-NG-RAN.h
|
||||
E1AP_DRB-Failed-To-Modify-List-EUTRAN.h
|
||||
E1AP_DRB-Failed-To-Modify-List-NG-RAN.h
|
||||
E1AP_DRB-ID.h
|
||||
E1AP_DRB-Measurement-Results-Information-Item.h
|
||||
E1AP_DRB-Measurement-Results-Information-List.h
|
||||
E1AP_DRB-Modified-Item-EUTRAN.h
|
||||
E1AP_DRB-Modified-Item-NG-RAN.h
|
||||
E1AP_DRB-Modified-List-EUTRAN.h
|
||||
E1AP_DRB-Modified-List-NG-RAN.h
|
||||
E1AP_DRB-Removed-Item.h
|
||||
E1AP_DRB-Required-To-Modify-Item-EUTRAN.h
|
||||
E1AP_DRB-Required-To-Modify-Item-NG-RAN.h
|
||||
E1AP_DRB-Required-To-Modify-List-EUTRAN.h
|
||||
E1AP_DRB-Required-To-Modify-List-NG-RAN.h
|
||||
E1AP_DRB-Required-To-Remove-Item-EUTRAN.h
|
||||
E1AP_DRB-Required-To-Remove-Item-NG-RAN.h
|
||||
E1AP_DRB-Required-To-Remove-List-EUTRAN.h
|
||||
E1AP_DRB-Required-To-Remove-List-NG-RAN.h
|
||||
E1AP_DRB-Setup-Item-EUTRAN.h
|
||||
E1AP_DRB-Setup-Item-NG-RAN.h
|
||||
E1AP_DRB-Setup-List-EUTRAN.h
|
||||
E1AP_DRB-Setup-List-NG-RAN.h
|
||||
E1AP_DRB-Setup-Mod-Item-EUTRAN.h
|
||||
E1AP_DRB-Setup-Mod-Item-NG-RAN.h
|
||||
E1AP_DRB-Setup-Mod-List-EUTRAN.h
|
||||
E1AP_DRB-Setup-Mod-List-NG-RAN.h
|
||||
E1AP_DRBs-Subject-To-Counter-Check-Item-EUTRAN.h
|
||||
E1AP_DRBs-Subject-To-Counter-Check-Item-NG-RAN.h
|
||||
E1AP_DRBs-Subject-To-Counter-Check-List-EUTRAN.h
|
||||
E1AP_DRBs-Subject-To-Counter-Check-List-NG-RAN.h
|
||||
E1AP_DRBs-Subject-To-Early-Forwarding-Item.h
|
||||
E1AP_DRBs-Subject-To-Early-Forwarding-List.h
|
||||
E1AP_DRB-Status-Item.h
|
||||
E1AP_DRB-Status-List.h
|
||||
E1AP_DRB-To-Modify-Item-EUTRAN.h
|
||||
E1AP_DRB-To-Modify-Item-NG-RAN.h
|
||||
E1AP_DRB-To-Modify-List-EUTRAN.h
|
||||
E1AP_DRB-To-Modify-List-NG-RAN.h
|
||||
E1AP_DRB-To-Remove-Item-EUTRAN.h
|
||||
E1AP_DRB-To-Remove-Item-NG-RAN.h
|
||||
E1AP_DRB-To-Remove-List-EUTRAN.h
|
||||
E1AP_DRB-To-Remove-List-NG-RAN.h
|
||||
E1AP_DRB-To-Setup-Item-EUTRAN.h
|
||||
E1AP_DRB-To-Setup-Item-NG-RAN.h
|
||||
E1AP_DRB-To-Setup-List-EUTRAN.h
|
||||
E1AP_DRB-To-Setup-List-NG-RAN.h
|
||||
E1AP_DRB-To-Setup-Mod-Item-EUTRAN.h
|
||||
E1AP_DRB-To-Setup-Mod-Item-NG-RAN.h
|
||||
E1AP_DRB-To-Setup-Mod-List-EUTRAN.h
|
||||
E1AP_DRB-To-Setup-Mod-List-NG-RAN.h
|
||||
E1AP_DRB-Usage-Report-Item.h
|
||||
E1AP_DRB-Usage-Report-List.h
|
||||
E1AP_Duplication-Activation.h
|
||||
E1AP_Dynamic5QIDescriptor.h
|
||||
E1AP_E1AP-PDU.h
|
||||
E1AP_E1ReleaseRequest.h
|
||||
E1AP_E1ReleaseResponse.h
|
||||
E1AP_EarlyDataForwardingIndicator.h
|
||||
E1AP_EarlyForwardingCOUNTInfo.h
|
||||
E1AP_EarlyForwardingCOUNTReq.h
|
||||
E1AP_EarlyForwardingSNTransfer.h
|
||||
E1AP_EHC-Common-Parameters.h
|
||||
E1AP_EHC-Downlink-Parameters.h
|
||||
E1AP_EHC-Parameters.h
|
||||
E1AP_EHC-Uplink-Parameters.h
|
||||
E1AP_EncryptionKey.h
|
||||
E1AP_Endpoint-IP-address-and-port.h
|
||||
E1AP_ErrorIndication.h
|
||||
E1AP_EUTRANAllocationAndRetentionPriority.h
|
||||
E1AP_EUTRAN-QoS.h
|
||||
E1AP_EUTRAN-QoS-Support-Item.h
|
||||
E1AP_EUTRAN-QoS-Support-List.h
|
||||
E1AP_Extended-GNB-CU-CP-Name.h
|
||||
E1AP_Extended-GNB-CU-UP-Name.h
|
||||
E1AP_Extended-NR-CGI-Support-Item.h
|
||||
E1AP_Extended-NR-CGI-Support-List.h
|
||||
E1AP_ExtendedPacketDelayBudget.h
|
||||
E1AP_ExtendedSliceSupportList.h
|
||||
E1AP_FirstDLCount.h
|
||||
E1AP_GBR-QoSFlowInformation.h
|
||||
E1AP_GBR-QosInformation.h
|
||||
E1AP_GNB-CU-CP-ConfigurationUpdateAcknowledge.h
|
||||
E1AP_GNB-CU-CP-ConfigurationUpdateFailure.h
|
||||
E1AP_GNB-CU-CP-ConfigurationUpdate.h
|
||||
E1AP_GNB-CU-CP-E1SetupFailure.h
|
||||
E1AP_GNB-CU-CP-E1SetupRequest.h
|
||||
E1AP_GNB-CU-CP-E1SetupResponse.h
|
||||
E1AP_GNB-CU-CPMeasurementResultsInformation.h
|
||||
E1AP_GNB-CU-CP-Name.h
|
||||
E1AP_GNB-CU-CP-NameUTF8String.h
|
||||
E1AP_GNB-CU-CP-NameVisibleString.h
|
||||
E1AP_GNB-CU-CP-TNLA-Failed-To-Setup-Item.h
|
||||
E1AP_GNB-CU-CP-TNLA-Failed-To-Setup-List.h
|
||||
E1AP_GNB-CU-CP-TNLA-Setup-Item.h
|
||||
E1AP_GNB-CU-CP-TNLA-Setup-List.h
|
||||
E1AP_GNB-CU-CP-TNLA-To-Add-Item.h
|
||||
E1AP_GNB-CU-CP-TNLA-To-Add-List.h
|
||||
E1AP_GNB-CU-CP-TNLA-To-Remove-Item.h
|
||||
E1AP_GNB-CU-CP-TNLA-To-Remove-List.h
|
||||
E1AP_GNB-CU-CP-TNLA-To-Update-Item.h
|
||||
E1AP_GNB-CU-CP-TNLA-To-Update-List.h
|
||||
E1AP_GNB-CU-CP-UE-E1AP-ID.h
|
||||
E1AP_GNB-CU-UP-Capacity.h
|
||||
E1AP_GNB-CU-UP-CellGroupRelatedConfiguration.h
|
||||
E1AP_GNB-CU-UP-CellGroupRelatedConfiguration-Item.h
|
||||
E1AP_GNB-CU-UP-ConfigurationUpdateAcknowledge.h
|
||||
E1AP_GNB-CU-UP-ConfigurationUpdateFailure.h
|
||||
E1AP_GNB-CU-UP-ConfigurationUpdate.h
|
||||
E1AP_GNB-CU-UP-CounterCheckRequest.h
|
||||
E1AP_GNB-CU-UP-E1SetupFailure.h
|
||||
E1AP_GNB-CU-UP-E1SetupRequest.h
|
||||
E1AP_GNB-CU-UP-E1SetupResponse.h
|
||||
E1AP_GNB-CU-UP-ID.h
|
||||
E1AP_GNB-CU-UP-Name.h
|
||||
E1AP_GNB-CU-UP-NameUTF8String.h
|
||||
E1AP_GNB-CU-UP-NameVisibleString.h
|
||||
E1AP_GNB-CU-UP-OverloadInformation.h
|
||||
E1AP_GNB-CU-UP-StatusIndication.h
|
||||
E1AP_GNB-CU-UP-TNLA-To-Remove-Item.h
|
||||
E1AP_GNB-CU-UP-TNLA-To-Remove-List.h
|
||||
E1AP_GNB-CU-UP-UE-E1AP-ID.h
|
||||
E1AP_GNB-DU-ID.h
|
||||
E1AP_GTP-TEID.h
|
||||
E1AP_GTPTLA-Item.h
|
||||
E1AP_GTPTLAs.h
|
||||
E1AP_GTPTunnel.h
|
||||
E1AP_HFN.h
|
||||
E1AP_HW-CapacityIndicator.h
|
||||
E1AP_IAB-UPTNLAddressUpdateAcknowledge.h
|
||||
E1AP_IAB-UPTNLAddressUpdateFailure.h
|
||||
E1AP_IAB-UPTNLAddressUpdate.h
|
||||
E1AP_IgnoreMappingRuleIndication.h
|
||||
E1AP_ImmediateMDT.h
|
||||
E1AP_Inactivity-Timer.h
|
||||
E1AP_InitiatingMessage.h
|
||||
E1AP_IntegrityProtectionAlgorithm.h
|
||||
E1AP_IntegrityProtectionIndication.h
|
||||
E1AP_IntegrityProtectionKey.h
|
||||
E1AP_IntegrityProtectionResult.h
|
||||
E1AP_InterfacesToTrace.h
|
||||
E1AP_Links-to-log.h
|
||||
E1AP_M4Configuration.h
|
||||
E1AP_M4period.h
|
||||
E1AP_M6Configuration.h
|
||||
E1AP_M6report-Interval.h
|
||||
E1AP_M7Configuration.h
|
||||
E1AP_M7period.h
|
||||
E1AP_MaxCIDEHCDL.h
|
||||
E1AP_MaxDataBurstVolume.h
|
||||
E1AP_MaximumIPdatarate.h
|
||||
E1AP_MaxIPrate.h
|
||||
E1AP_MaxPacketLossRate.h
|
||||
E1AP_MDT-Activation.h
|
||||
E1AP_MDT-Configuration.h
|
||||
E1AP_MDTMode.h
|
||||
E1AP_MDTPLMNList.h
|
||||
E1AP_MeasurementsToActivate.h
|
||||
E1AP_MRDC-DataUsageReport.h
|
||||
E1AP_MRDC-Data-Usage-Report-Item.h
|
||||
E1AP_MRDC-Usage-Information.h
|
||||
E1AP_NetworkInstance.h
|
||||
E1AP_New-UL-TNL-Information-Required.h
|
||||
E1AP_NGRANAllocationAndRetentionPriority.h
|
||||
E1AP_NG-RAN-QoS-Support-Item.h
|
||||
E1AP_NG-RAN-QoS-Support-List.h
|
||||
E1AP_NID.h
|
||||
E1AP_Non-Dynamic5QIDescriptor.h
|
||||
E1AP_NPNContextInfo.h
|
||||
E1AP_NPNContextInfo-SNPN.h
|
||||
E1AP_NPNSupportInfo.h
|
||||
E1AP_NPNSupportInfo-SNPN.h
|
||||
E1AP_NR-Cell-Identity.h
|
||||
E1AP_NR-CGI.h
|
||||
E1AP_NR-CGI-Support-Item.h
|
||||
E1AP_NR-CGI-Support-List.h
|
||||
E1AP_Number-of-tunnels.h
|
||||
E1AP_OutOfOrderDelivery.h
|
||||
E1AP_PacketDelayBudget.h
|
||||
E1AP_PacketErrorRate.h
|
||||
E1AP_PDCP-Configuration.h
|
||||
E1AP_PDCP-Count.h
|
||||
E1AP_PDCP-DataRecovery.h
|
||||
E1AP_PDCP-Duplication.h
|
||||
E1AP_PDCP-Reestablishment.h
|
||||
E1AP_PDCP-SN.h
|
||||
E1AP_PDCP-SN-Size.h
|
||||
E1AP_PDCP-SN-Status-Information.h
|
||||
E1AP_PDCP-SN-Status-Request.h
|
||||
E1AP_PDCP-StatusReportIndication.h
|
||||
E1AP_PDU-Session-ID.h
|
||||
E1AP_PDU-Session-Resource-Activity.h
|
||||
E1AP_PDU-Session-Resource-Activity-Item.h
|
||||
E1AP_PDU-Session-Resource-Activity-List.h
|
||||
E1AP_PDU-Session-Resource-Confirm-Modified-Item.h
|
||||
E1AP_PDU-Session-Resource-Confirm-Modified-List.h
|
||||
E1AP_PDU-Session-Resource-Data-Usage-Item.h
|
||||
E1AP_PDU-Session-Resource-Data-Usage-List.h
|
||||
E1AP_PDU-Session-Resource-Failed-Item.h
|
||||
E1AP_PDU-Session-Resource-Failed-List.h
|
||||
E1AP_PDU-Session-Resource-Failed-Mod-Item.h
|
||||
E1AP_PDU-Session-Resource-Failed-Mod-List.h
|
||||
E1AP_PDU-Session-Resource-Failed-To-Modify-Item.h
|
||||
E1AP_PDU-Session-Resource-Failed-To-Modify-List.h
|
||||
E1AP_PDU-Session-Resource-Modified-Item.h
|
||||
E1AP_PDU-Session-Resource-Modified-List.h
|
||||
E1AP_PDU-Session-Resource-Required-To-Modify-Item.h
|
||||
E1AP_PDU-Session-Resource-Required-To-Modify-List.h
|
||||
E1AP_PDU-Session-Resource-Setup-Item.h
|
||||
E1AP_PDU-Session-Resource-Setup-List.h
|
||||
E1AP_PDU-Session-Resource-Setup-Mod-Item.h
|
||||
E1AP_PDU-Session-Resource-Setup-Mod-List.h
|
||||
E1AP_PDU-Session-Resource-To-Modify-Item.h
|
||||
E1AP_PDU-Session-Resource-To-Modify-List.h
|
||||
E1AP_PDU-Session-Resource-To-Remove-Item.h
|
||||
E1AP_PDU-Session-Resource-To-Remove-List.h
|
||||
E1AP_PDU-Session-Resource-To-Setup-Item.h
|
||||
E1AP_PDU-Session-Resource-To-Setup-List.h
|
||||
E1AP_PDU-Session-Resource-To-Setup-Mod-Item.h
|
||||
E1AP_PDU-Session-Resource-To-Setup-Mod-List.h
|
||||
E1AP_PDU-Session-To-Notify-Item.h
|
||||
E1AP_PDU-Session-To-Notify-List.h
|
||||
E1AP_PDU-Session-Type.h
|
||||
E1AP_PER-Exponent.h
|
||||
E1AP_Periodicity.h
|
||||
E1AP_PER-Scalar.h
|
||||
E1AP_PLMN-Identity.h
|
||||
E1AP_PortNumber.h
|
||||
E1AP_PPI.h
|
||||
E1AP_Pre-emptionCapability.h
|
||||
E1AP_Pre-emptionVulnerability.h
|
||||
E1AP_Presence.h
|
||||
E1AP_PriorityLevel.h
|
||||
E1AP_PrivacyIndicator.h
|
||||
E1AP_PrivateIE-Container.h
|
||||
E1AP_PrivateIE-Field.h
|
||||
E1AP_PrivateIE-ID.h
|
||||
E1AP_PrivateMessage.h
|
||||
E1AP_ProcedureCode.h
|
||||
E1AP_ProtocolExtensionContainer.h
|
||||
E1AP_ProtocolExtensionField.h
|
||||
E1AP_ProtocolExtensionID.h
|
||||
E1AP_ProtocolIE-Container.h
|
||||
E1AP_ProtocolIE-ContainerList.h
|
||||
E1AP_ProtocolIE-Field.h
|
||||
E1AP_ProtocolIE-ID.h
|
||||
E1AP_ProtocolIE-SingleContainer.h
|
||||
E1AP_QCI.h
|
||||
E1AP_QoS-Characteristics.h
|
||||
E1AP_QoS-Flow-Failed-Item.h
|
||||
E1AP_QoS-Flow-Failed-List.h
|
||||
E1AP_QoS-Flow-Identifier.h
|
||||
E1AP_QoS-Flow-Item.h
|
||||
E1AP_QoSFlowLevelQoSParameters.h
|
||||
E1AP_QoS-Flow-List.h
|
||||
E1AP_QoS-Flow-Mapping-Indication.h
|
||||
E1AP_QoS-Flow-Mapping-Item.h
|
||||
E1AP_QoS-Flow-Mapping-List.h
|
||||
E1AP_QoS-Flow-QoS-Parameter-Item.h
|
||||
E1AP_QoS-Flow-QoS-Parameter-List.h
|
||||
E1AP_QoS-Flow-Removed-Item.h
|
||||
E1AP_QoS-Flows-DRB-Remapping.h
|
||||
E1AP_QoS-Flows-to-be-forwarded-Item.h
|
||||
E1AP_QoS-Flows-to-be-forwarded-List.h
|
||||
E1AP_QoS-Mapping-Information.h
|
||||
E1AP_QosMonitoringDisabled.h
|
||||
E1AP_QosMonitoringReportingFrequency.h
|
||||
E1AP_QosMonitoringRequest.h
|
||||
E1AP_QoS-Parameters-Support-List.h
|
||||
E1AP_QoSPriorityLevel.h
|
||||
E1AP_RANUEID.h
|
||||
E1AP_RAT-Type.h
|
||||
E1AP_RedundantPDUSessionInformation.h
|
||||
E1AP_RedundantQoSFlowIndicator.h
|
||||
E1AP_RegistrationRequest.h
|
||||
E1AP_ReportCharacteristics.h
|
||||
E1AP_ReportingPeriodicity.h
|
||||
E1AP_ResetAcknowledge.h
|
||||
E1AP_ResetAll.h
|
||||
E1AP_Reset.h
|
||||
E1AP_ResetType.h
|
||||
E1AP_ResourceStatusFailure.h
|
||||
E1AP_ResourceStatusRequest.h
|
||||
E1AP_ResourceStatusResponse.h
|
||||
E1AP_ResourceStatusUpdate.h
|
||||
E1AP_RetainabilityMeasurementsInfo.h
|
||||
E1AP_RLC-Mode.h
|
||||
E1AP_ROHC.h
|
||||
E1AP_ROHC-Parameters.h
|
||||
E1AP_RSN.h
|
||||
E1AP_SDAP-Configuration.h
|
||||
E1AP_SDAP-Header-DL.h
|
||||
E1AP_SDAP-Header-UL.h
|
||||
E1AP_SecurityAlgorithm.h
|
||||
E1AP_SecurityIndication.h
|
||||
E1AP_SecurityInformation.h
|
||||
E1AP_SecurityResult.h
|
||||
E1AP_Slice-Support-Item.h
|
||||
E1AP_Slice-Support-List.h
|
||||
E1AP_SNSSAI.h
|
||||
E1AP_SubscriberProfileIDforRFP.h
|
||||
E1AP_SuccessfulOutcome.h
|
||||
E1AP_SupportedPLMNs-Item.h
|
||||
E1AP_SupportedPLMNs-List.h
|
||||
E1AP_System-BearerContextModificationConfirm.h
|
||||
E1AP_System-BearerContextModificationRequest.h
|
||||
E1AP_System-BearerContextModificationRequired.h
|
||||
E1AP_System-BearerContextModificationResponse.h
|
||||
E1AP_System-BearerContextSetupRequest.h
|
||||
E1AP_System-BearerContextSetupResponse.h
|
||||
E1AP_System-GNB-CU-UP-CounterCheckRequest.h
|
||||
E1AP_TimeToWait.h
|
||||
E1AP_TNLAssociationUsage.h
|
||||
E1AP_TNL-AvailableCapacityIndicator.h
|
||||
E1AP_TraceActivation.h
|
||||
E1AP_TraceDepth.h
|
||||
E1AP_TraceID.h
|
||||
E1AP_TraceStart.h
|
||||
E1AP_TransactionID.h
|
||||
E1AP_TransportLayerAddress.h
|
||||
E1AP_Transport-Layer-Address-Info.h
|
||||
E1AP_Transport-UP-Layer-Addresses-Info-To-Add-Item.h
|
||||
E1AP_Transport-UP-Layer-Addresses-Info-To-Add-List.h
|
||||
E1AP_Transport-UP-Layer-Addresses-Info-To-Remove-Item.h
|
||||
E1AP_Transport-UP-Layer-Addresses-Info-To-Remove-List.h
|
||||
E1AP_T-Reordering.h
|
||||
E1AP_T-ReorderingTimer.h
|
||||
E1AP_TriggeringMessage.h
|
||||
E1AP_TSCTrafficCharacteristics.h
|
||||
E1AP_TSCTrafficInformation.h
|
||||
E1AP_TypeOfError.h
|
||||
E1AP_UE-Activity.h
|
||||
E1AP_UE-associatedLogicalE1-ConnectionItem.h
|
||||
E1AP_UE-associatedLogicalE1-ConnectionListResAck.h
|
||||
E1AP_UE-associatedLogicalE1-ConnectionListRes.h
|
||||
E1AP_UL-Configuration.h
|
||||
E1AP_ULDataNotification.h
|
||||
E1AP_ULDataSplitThreshold.h
|
||||
E1AP_ULUPTNLAddressToUpdateItem.h
|
||||
E1AP_ULUPTNLAddressToUpdateList.h
|
||||
E1AP_UnsuccessfulOutcome.h
|
||||
E1AP_UplinkOnlyROHC.h
|
||||
E1AP_UP-Parameters.h
|
||||
E1AP_UP-Parameters-Item.h
|
||||
E1AP_UPSecuritykey.h
|
||||
E1AP_UP-TNL-Information.h
|
||||
E1AP_URIaddress.h
|
||||
INTEGER.h
|
||||
NativeEnumerated.h
|
||||
NativeInteger.h
|
||||
OBJECT_IDENTIFIER.h
|
||||
OCTET_STRING.h
|
||||
OPEN_TYPE.h
|
||||
per_decoder.h
|
||||
per_encoder.h
|
||||
per_opentype.h
|
||||
per_support.h
|
||||
PrintableString.h
|
||||
UTF8String.h
|
||||
VisibleString.h
|
||||
xer_decoder.h
|
||||
xer_encoder.h
|
||||
xer_support.h
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
set(E1AP_VERSION 16 78 0)
|
||||
make_version(E1AP_cc ${E1AP_VERSION})
|
||||
#add_definitions(-DE1AP_VERSION=${E1AP_cc})
|
||||
string(REPLACE ";" "." E1AP_RELEASE "${E1AP_VERSION}")
|
||||
|
||||
if(E1AP_RELEASE VERSION_EQUAL "16.78.0")
|
||||
include(ASN.1/38463-g80.R16.78.0.cmake)
|
||||
else()
|
||||
message(FATAL_ERROR "unknown E1AP_RELEASE ${E1AP_RELEASE}")
|
||||
endif()
|
||||
|
||||
add_custom_command(OUTPUT ${e1ap_source} ${e1ap_headers}
|
||||
COMMAND ASN1C_PREFIX=E1AP_ asn1c -gen-PER -no-gen-OER -fcompound-names -no-gen-example -findirect-choice -fno-include-deps -D ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${E1AP_GRAMMAR}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${E1AP_GRAMMAR}
|
||||
COMMENT "Generating E1AP source files from ${CMAKE_CURRENT_SOURCE_DIR}/${E1AP_GRAMMAR}"
|
||||
)
|
||||
|
||||
add_library(asn1_e1ap ${e1ap_source})
|
||||
target_include_directories(asn1_e1ap PUBLIC "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
target_compile_options(asn1_e1ap PRIVATE -DASN_DISABLE_OER_SUPPORT -w)
|
||||
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* 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 "e1ap.h"
|
||||
|
||||
int asn1_encoder_xer_print = 1;
|
||||
|
||||
int e1ap_assoc_id(bool isCu, instance_t instance) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int e1ap_encode_send(bool isCu, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func) {
|
||||
DevAssert(pdu != NULL);
|
||||
|
||||
if (asn1_encoder_xer_print) {
|
||||
LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT START ----------------- \n");
|
||||
xer_fprint(stdout, &asn_DEF_E1AP_E1AP_PDU, pdu);
|
||||
LOG_E(E1AP, "----------------- ASN1 ENCODER PRINT END----------------- \n");
|
||||
}
|
||||
|
||||
char errbuf[2048]; /* Buffer for error message */
|
||||
size_t errlen = sizeof(errbuf); /* Size of the buffer */
|
||||
int ret = asn_check_constraints(&asn_DEF_E1AP_E1AP_PDU, pdu, errbuf, &errlen);
|
||||
|
||||
if(ret) {
|
||||
fprintf(stderr, "%s: Constraint validation failed: %s\n", func, errbuf);
|
||||
}
|
||||
|
||||
void *buffer = NULL;
|
||||
ssize_t encoded = aper_encode_to_new_buffer(&asn_DEF_E1AP_E1AP_PDU, 0, pdu, buffer);
|
||||
|
||||
if (encoded < 0) {
|
||||
LOG_E(E1AP, "%s: Failed to encode E1AP message\n", func);
|
||||
return -1;
|
||||
} else {
|
||||
MessageDef *message = itti_alloc_new_message(isCu?TASK_CUCP_E1:TASK_CUUP_E1, 0, SCTP_DATA_REQ);
|
||||
sctp_data_req_t *s = &message->ittiMsg.sctp_data_req;
|
||||
s->assoc_id = e1ap_assoc_id(isCu,instance);
|
||||
s->buffer = buffer;
|
||||
s->buffer_length = encoded;
|
||||
s->stream = stream;
|
||||
LOG_I(E1AP, "%s: Sending ITTI message to SCTP Task\n", func);
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message);
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
void e1ap_itti_send_sctp_close_association(bool isCu, instance_t instance) {
|
||||
MessageDef *message = itti_alloc_new_message(TASK_S1AP, 0, SCTP_CLOSE_ASSOCIATION);
|
||||
sctp_close_association_t *sctp_close_association = &message->ittiMsg.sctp_close_association;
|
||||
sctp_close_association->assoc_id = e1ap_assoc_id(isCu,instance);
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message);
|
||||
}
|
||||
|
||||
int e1ap_send_RESET(bool isCu, instance_t instance, E1AP_Reset_t *Reset) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
E1AP_E1AP_PDU_t pdu= {0};
|
||||
return e1ap_encode_send(isCu, instance, &pdu,0, __func__);
|
||||
}
|
||||
|
||||
int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1ap_handle_RESET(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1ap_handle_RESET_ACKNOWLEDGE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
/*
|
||||
Error Indication
|
||||
*/
|
||||
int e1ap_handle_ERROR_INDICATION(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *ErrorIndication) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
E1 Setup: can be sent on both ways, to be refined
|
||||
*/
|
||||
|
||||
int e1apCUUP_send_SETUP_REQUEST(instance_t instance, E1AP_Reset_t *Reset) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_send_SETUP_RESPONSE(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_send_SETUP_FAILURE() {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_SETUP_REQUEST(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_handle_SETUP_RESPONSE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_handle_SETUP_FAILURE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
/*
|
||||
E1 configuration update: can be sent in both ways, to be refined
|
||||
*/
|
||||
|
||||
int e1apCUUP_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
/*
|
||||
E1 release
|
||||
*/
|
||||
|
||||
int e1ap_send_RELEASE_REQUEST(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1ap_send_RELEASE_ACKNOWLEDGE(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1ap_handle_RELEASE_REQUEST(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1ap_handle_RELEASE_ACKNOWLEDGE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
/*
|
||||
BEARER CONTEXT SETUP REQUEST
|
||||
*/
|
||||
|
||||
int e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
/*
|
||||
BEARER CONTEXT MODIFICATION REQUEST
|
||||
*/
|
||||
|
||||
int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_REQUIRED(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_CONFIRM(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
/*
|
||||
BEARER CONTEXT RELEASE
|
||||
*/
|
||||
|
||||
int e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_BEARER_CONTEXT_RELEASE_REQUEST(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
/*
|
||||
BEARER CONTEXT INACTIVITY NOTIFICATION
|
||||
*/
|
||||
|
||||
int e1apCUUP_send_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_BEARER_CONTEXT_INACTIVITY_NOTIFICATION(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
/*
|
||||
DL DATA
|
||||
*/
|
||||
|
||||
int e1apCUUP_send_DL_DATA_NOTIFICATION(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUUP_send_DATA_USAGE_REPORT(instance_t instance) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_DL_DATA_NOTIFICATION(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
|
||||
int e1apCUCP_handle_send_DATA_USAGE_REPORT(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
E1AP_E1AP_PDU_t *pdu) {
|
||||
AssertFatal(false,"Not implemented yet\n");
|
||||
}
|
||||
@@ -9,6 +9,8 @@
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* 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.
|
||||
@@ -19,52 +21,14 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/LTE_TRANSPORT/if5_tools.h
|
||||
* \brief
|
||||
* \author S. Sandeep Kumar, Raymond Knopp
|
||||
* \date 2016
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: ee13b1025@iith.ac.in, knopp@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifndef __E1AP_H_
|
||||
#define __E1AP_H_
|
||||
|
||||
#ifndef __IF5_TOOLS_H__
|
||||
#define __IF5_TOOLS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "PHY/defs_eNB.h"
|
||||
|
||||
#define IF5_RRH_GW_DL 0x0022
|
||||
#define IF5_RRH_GW_UL 0x0023
|
||||
#define IF5_MOBIPASS 0xbffe
|
||||
|
||||
struct IF5_mobipass_header {
|
||||
///
|
||||
uint16_t flags;
|
||||
///
|
||||
uint16_t fifo_status;
|
||||
///
|
||||
uint8_t seqno;
|
||||
///
|
||||
uint8_t ack;
|
||||
///
|
||||
uint32_t word0;
|
||||
///
|
||||
uint32_t time_stamp;
|
||||
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
typedef struct IF5_mobipass_header IF5_mobipass_header_t;
|
||||
#define sizeof_IF5_mobipass_header_t 14
|
||||
|
||||
void send_IF5(RU_t *, openair0_timestamp, int, uint8_t*, uint16_t);
|
||||
|
||||
void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16_t packet_type);
|
||||
|
||||
|
||||
void malloc_IF5_buffer(RU_t *ru);
|
||||
#include <common/utils/LOG/log.h>
|
||||
#include "openairinterface5g_limits.h"
|
||||
#include <openair2/RRC/NR/MESSAGES/asn1_msg.h>
|
||||
|
||||
#include <E1AP_Cause.h>
|
||||
#include <E1AP_InitiatingMessage.h>
|
||||
#include <E1AP_E1AP-PDU.h>
|
||||
#endif
|
||||
|
||||
@@ -103,11 +103,23 @@ typedef enum {
|
||||
#define CONFIG_STRING_RU_SL_AHEAD "sl_ahead"
|
||||
#define CONFIG_STRING_RU_NR_FLAG "nr_flag"
|
||||
#define CONFIG_STRING_RU_NR_SCS_FOR_RASTER "nr_scs_for_raster"
|
||||
#define CONFIG_STRING_RU_RXFH_CORE_ID "rxfh_core_id"
|
||||
#define CONFIG_STRING_RU_TXFH_CORE_ID "txfh_core_id"
|
||||
#define CONFIG_STRING_RU_TP_CORES "tp_cores"
|
||||
#define CONFIG_STRING_RU_NUM_TP_CORES "num_tp_cores"
|
||||
#define CONFIG_STRING_RU_NUM_INTERFACES "num_interfaces"
|
||||
#define CONFIG_STRING_RU_HALF_SLOT_PARALLELIZATION "half_slot_parallelization"
|
||||
|
||||
#define HLP_RU_SF_AHEAD "LTE TX processing advance"
|
||||
#define HLP_RU_SL_AHEAD "NR TX processing advance"
|
||||
#define HLP_RU_NR_FLAG "Use NR numerology (for AW2SORI)"
|
||||
#define HLP_RU_NR_SCS_FOR_RASTER "NR SCS for raster (for AW2SORI)"
|
||||
#define HLP_RU_RXFH_CORE_ID "Core ID for RX Fronthaul thread (ECPRI IF5)"
|
||||
#define HLP_RU_TXFH_CORE_ID "Core ID for TX Fronthaul thread (ECPRI IF5)"
|
||||
#define HLP_RU_TP_CORES "List of cores for RU ThreadPool"
|
||||
#define HLP_RU_NUM_TP_CORES "Number of cores for RU ThreadPool"
|
||||
#define HLP_RU_NUM_INTERFACES "Number of network interfaces for RU"
|
||||
#define HLP_RU_HALF_SLOT_PARALLELIZATION "run half slots in parallel in RU FEP"
|
||||
|
||||
#define RU_LOCAL_IF_NAME_IDX 0
|
||||
#define RU_LOCAL_ADDRESS_IDX 1
|
||||
@@ -142,6 +154,12 @@ typedef enum {
|
||||
#define RU_SL_AHEAD 30
|
||||
#define RU_NR_FLAG 31
|
||||
#define RU_NR_SCS_FOR_RASTER 32
|
||||
#define RU_RXFH_CORE_ID 33
|
||||
#define RU_TXFH_CORE_ID 34
|
||||
#define RU_TP_CORES 35
|
||||
#define RU_NUM_TP_CORES 36
|
||||
#define RU_NUM_INTERFACES 37
|
||||
#define RU_HALF_SLOT_PARALLELIZATION 38
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* RU configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
@@ -180,6 +198,12 @@ typedef enum {
|
||||
{CONFIG_STRING_RU_SL_AHEAD, HLP_RU_SL_AHEAD, 0, iptr:NULL, defintval:6, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_RU_NR_FLAG, HLP_RU_NR_FLAG, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_RU_NR_SCS_FOR_RASTER, HLP_RU_NR_SCS_FOR_RASTER, 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_RU_RXFH_CORE_ID, HLP_RU_RXFH_CORE_ID, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_RU_TXFH_CORE_ID, HLP_RU_TXFH_CORE_ID, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_RU_TP_CORES, HLP_RU_TP_CORES, 0, uptr:NULL, defintarrayval:DEFRUTPCORES, TYPE_INTARRAY, 8}, \
|
||||
{CONFIG_STRING_RU_NUM_TP_CORES, HLP_RU_NUM_TP_CORES, 0, uptr:NULL, defintval:2, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_RU_NUM_INTERFACES, HLP_RU_NUM_INTERFACES, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_RU_HALF_SLOT_PARALLELIZATION, HLP_RU_HALF_SLOT_PARALLELIZATION, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#define CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD "pucch0_dtx_threshold"
|
||||
#define CONFIG_STRING_L1_PRACH_DTX_THRESHOLD "prach_dtx_threshold"
|
||||
#define CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD "pusch_dtx_threshold"
|
||||
#define CONFIG_STRING_L1_SRS_DTX_THRESHOLD "srs_dtx_threshold"
|
||||
#define CONFIG_STRING_L1_MAX_LDPC_ITERATIONS "max_ldpc_iterations"
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* L1 configuration parameters */
|
||||
@@ -71,6 +72,7 @@
|
||||
{CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:100, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_PRACH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:150, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:50, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_SRS_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:50, TYPE_UINT, 0}, \
|
||||
{CONFIG_STRING_L1_MAX_LDPC_ITERATIONS, NULL, 0, uptr:NULL, defintval:5, TYPE_UINT, 0}, \
|
||||
}
|
||||
#define L1_CC_IDX 0
|
||||
@@ -87,7 +89,8 @@
|
||||
#define L1_PUCCH0_DTX_THRESHOLD 11
|
||||
#define L1_PRACH_DTX_THRESHOLD 12
|
||||
#define L1_PUSCH_DTX_THRESHOLD 13
|
||||
#define L1_MAX_LDPC_ITERATIONS 14
|
||||
#define L1_SRS_DTX_THRESHOLD 14
|
||||
#define L1_MAX_LDPC_ITERATIONS 15
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
@@ -731,6 +731,7 @@ void RCconfig_NR_L1(void) {
|
||||
RC.gNB[j]->pucch0_thres = *(L1_ParamList.paramarray[j][L1_PUCCH0_DTX_THRESHOLD].uptr);
|
||||
RC.gNB[j]->prach_thres = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_THRESHOLD].uptr);
|
||||
RC.gNB[j]->pusch_thres = *(L1_ParamList.paramarray[j][L1_PUSCH_DTX_THRESHOLD].uptr);
|
||||
RC.gNB[j]->srs_thres = *(L1_ParamList.paramarray[j][L1_SRS_DTX_THRESHOLD].uptr);
|
||||
RC.gNB[j]->max_ldpc_iterations = *(L1_ParamList.paramarray[j][L1_MAX_LDPC_ITERATIONS].uptr);
|
||||
RC.gNB[j]->num_ulprbbl = num_prbbl;
|
||||
RC.gNB[j]->ap_N1 = N1;
|
||||
|
||||
@@ -708,12 +708,12 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
|
||||
uint16_t msi_control_element[29], *msi_ptr;
|
||||
// MSI buffer pointer
|
||||
char *buffer_pointer=NULL;
|
||||
if (msi_flag == 1) {
|
||||
// Create MSI here
|
||||
msi_ptr = &msi_control_element[0];
|
||||
if (msi_flag == 1 && cc->mbms_SessionList) {
|
||||
// Create MSI here
|
||||
msi_ptr = &msi_control_element[0];
|
||||
|
||||
//Header for MTCHs
|
||||
num_mtch = cc->mbms_SessionList[mbms_mch_i]->list.count;
|
||||
// Header for MTCHs
|
||||
num_mtch = cc->mbms_SessionList[mbms_mch_i]->list.count;
|
||||
|
||||
TBS =
|
||||
get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth));
|
||||
@@ -867,52 +867,63 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
|
||||
//if ((i == 0) && ((RC.mac[module_idP]->MBMS_flag != multicast_relay) || (RC.mac[module_idP]->mcch_active==0))) {
|
||||
|
||||
// there is MTCHs, loop if there are more than 1
|
||||
if (mtch_flag == 1 ) {
|
||||
// Calculate TBS
|
||||
// get MTCH data from RLC (like for DTCH)
|
||||
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n",
|
||||
module_idP, CC_id, frameP, subframeP, i, j);
|
||||
// BAd race condition: all this struct is filled by another thread, no mutex or any code to make it coherent
|
||||
if (mtch_flag == 1 && cc->mbms_SessionList && cc->mbms_SessionList[0] && cc->mbms_SessionList[0]->list.array[0]) {
|
||||
// Calculate TBS
|
||||
// get MTCH data from RLC (like for DTCH)
|
||||
LOG_D(MAC, "[eNB %d] CC_id %d Frame %d subframeP %d: Schedule MTCH (area %d, sfAlloc %d)\n", module_idP, CC_id, frameP, subframeP, i, j);
|
||||
|
||||
header_len_mtch = 3;
|
||||
LOG_D(MAC,"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
|
||||
module_idP, CC_id, frameP, MTCH, TBS,
|
||||
TBS - header_len_mcch - header_len_msi - sdu_length_total -
|
||||
header_len_mtch);
|
||||
header_len_mtch = 3;
|
||||
LOG_D(MAC,
|
||||
"[eNB %d], CC_id %d, Frame %d, MTCH->MCH, Checking RLC status (rab %d, tbs %d, len %d)\n",
|
||||
module_idP,
|
||||
CC_id,
|
||||
frameP,
|
||||
MTCH,
|
||||
TBS,
|
||||
TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch);
|
||||
|
||||
//TODO
|
||||
mbms_rab_id = cc->mbms_SessionList[0/*mbms_mch_i*/]->list.array[0]->logicalChannelIdentity_r9;
|
||||
// TODO
|
||||
mbms_rab_id = cc->mbms_SessionList[0 /*mbms_mch_i*/]->list.array[0]->logicalChannelIdentity_r9;
|
||||
|
||||
rlc_status =
|
||||
mac_rlc_status_ind(module_idP, 0xfffd, frameP, subframeP,
|
||||
module_idP, ENB_FLAG_YES, MBMS_FLAG_YES,
|
||||
cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9,
|
||||
//MTCH,
|
||||
0, 0
|
||||
);
|
||||
rlc_status = mac_rlc_status_ind(module_idP,
|
||||
0xfffd,
|
||||
frameP,
|
||||
subframeP,
|
||||
module_idP,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_YES,
|
||||
cc->mbms_SessionList[mbms_mch_i]->list.array[0]->logicalChannelIdentity_r9,
|
||||
// MTCH,
|
||||
0,
|
||||
0);
|
||||
|
||||
bytes_in_buffer = rlc_status.bytes_in_buffer;
|
||||
bytes_in_buffer = rlc_status.bytes_in_buffer;
|
||||
|
||||
//TOCHECK is this really neede?
|
||||
if( !(mcch_flag==1 || msi_flag==1) )
|
||||
msi_sfs = rlc_status.bytes_in_buffer/(TBS- header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)+(rlc_status.bytes_in_buffer%(TBS- header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)?1:0);
|
||||
// TOCHECK is this really neede?
|
||||
if (!(mcch_flag == 1 || msi_flag == 1))
|
||||
msi_sfs = rlc_status.bytes_in_buffer / (TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch)
|
||||
+ (rlc_status.bytes_in_buffer % (TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch) ? 1 : 0);
|
||||
|
||||
uint16_t TBS_MTCH =
|
||||
get_TBS_DL(cc->pmch_Config[mbms_mch_i]->dataMCS_r9, to_prb(cc->mib->message.dl_Bandwidth));
|
||||
uint16_t TBS_MTCH = get_TBS_DL(cc->pmch_Config[mbms_mch_i]->dataMCS_r9, to_prb(cc->mib->message.dl_Bandwidth));
|
||||
|
||||
if(msi_flag==1 && buffer_pointer!=NULL){
|
||||
// msi_ptr = &msi_control_element[0];
|
||||
if (msi_flag == 1 && buffer_pointer != NULL) {
|
||||
// msi_ptr = &msi_control_element[0];
|
||||
|
||||
msi_pmch_stop = (rlc_status.bytes_in_buffer - header_len_mcch - header_len_msi -sdu_length_total - header_len_mtch)/(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)+((rlc_status.bytes_in_buffer-TBS-header_len_mcch - header_len_msi -sdu_length_total)%(TBS_MTCH/*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)?0:0);
|
||||
msi_pmch_stop =
|
||||
(rlc_status.bytes_in_buffer - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch) / (TBS_MTCH /*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch)
|
||||
+ ((rlc_status.bytes_in_buffer - TBS - header_len_mcch - header_len_msi - sdu_length_total) % (TBS_MTCH /*- header_len_mcch - header_len_msi -sdu_length_total*/ - header_len_mtch) ? 0
|
||||
: 0);
|
||||
|
||||
for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment
|
||||
msi_ptr = &msi_control_element[k];
|
||||
for (k = 0; k < num_mtch; k++) { // loop for all session in this MCH (MCH[0]) at this moment
|
||||
msi_ptr = &msi_control_element[k];
|
||||
|
||||
((MSI_ELEMENT *) msi_ptr)->lcid = cc->mbms_SessionList[mbms_mch_i]->list.array[k]->logicalChannelIdentity_r9; //mtch_lcid;
|
||||
((MSI_ELEMENT *)msi_ptr)->lcid = cc->mbms_SessionList[mbms_mch_i]->list.array[k]->logicalChannelIdentity_r9; // mtch_lcid;
|
||||
|
||||
if( msi_pmch_stop > cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9)
|
||||
LOG_E(MAC,"e-MBMS Buffer Overflow\n");
|
||||
if (msi_pmch_stop > cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9)
|
||||
LOG_E(MAC, "e-MBMS Buffer Overflow\n");
|
||||
|
||||
if(msi_pmch_stop>=num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) {
|
||||
if (msi_pmch_stop >= num_sf_alloc /*&& msi_pmch_stop <=cc->pmch_Config[0]->sf_AllocEnd_r9*/) {
|
||||
((MSI_ELEMENT *) msi_ptr)->stop_sf_MSB = (((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) >> 8) & 0x7f);
|
||||
((MSI_ELEMENT *) msi_ptr)->stop_sf_LSB = ((msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9) & 0xff);
|
||||
msi_pmch_stop = (msi_pmch_stop <=cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9 ? msi_pmch_stop: cc->pmch_Config[mbms_mch_i]->sf_AllocEnd_r9);
|
||||
|
||||
@@ -2076,7 +2076,7 @@ void get_delta_arfcn(int i, uint32_t nrarfcn, uint64_t N_OFFs){
|
||||
uint32_t delta_arfcn = nrarfcn - N_OFFs;
|
||||
|
||||
if(delta_arfcn%(nr_bandtable[i].step_size)!=0)
|
||||
AssertFatal(1 == 0, "nrarfcn %u is not on the channel raster for step size %lu", nrarfcn, nr_bandtable[i].step_size);
|
||||
AssertFatal(1==0, "nrarfcn %u is not on the channel raster for step size %lu", nrarfcn, nr_bandtable[i].step_size);
|
||||
|
||||
}
|
||||
|
||||
@@ -2096,10 +2096,10 @@ uint32_t to_nrarfcn(int nr_bandP,
|
||||
"Band %d, bw %u : DL carrier frequency %llu kHz < %llu\n",
|
||||
nr_bandP, bw, (long long unsigned int)dl_CarrierFreq_by_1k,
|
||||
(long long unsigned int)nr_bandtable[i].dl_min);
|
||||
AssertFatal(dl_CarrierFreq_by_1k <= (nr_bandtable[i].dl_max - bw_kHz),
|
||||
AssertFatal(dl_CarrierFreq_by_1k <= (nr_bandtable[i].dl_max - bw_kHz/2),
|
||||
"Band %d, dl_CarrierFreq %llu bw %u: DL carrier frequency %llu kHz > %llu\n",
|
||||
nr_bandP, (long long unsigned int)dl_CarrierFreq,bw, (long long unsigned int)dl_CarrierFreq_by_1k,
|
||||
(long long unsigned int)(nr_bandtable[i].dl_max - bw_kHz));
|
||||
(long long unsigned int)(nr_bandtable[i].dl_max - bw_kHz/2));
|
||||
|
||||
int deltaFglobal = 60;
|
||||
uint32_t N_REF_Offs = 2016667;
|
||||
@@ -2119,7 +2119,7 @@ uint32_t to_nrarfcn(int nr_bandP,
|
||||
// This is equation before Table 5.4.2.1-1 in 38101-1-f30
|
||||
// F_REF=F_REF_Offs + deltaF_Global(N_REF-NREF_REF_Offs)
|
||||
nrarfcn = (((dl_CarrierFreq_by_1k - F_REF_Offs_khz)/deltaFglobal)+N_REF_Offs);
|
||||
get_delta_arfcn(i, nrarfcn, nr_bandtable[i].N_OFFs_DL);
|
||||
//get_delta_arfcn(i, nrarfcn, nr_bandtable[i].N_OFFs_DL);
|
||||
|
||||
return nrarfcn;
|
||||
}
|
||||
|
||||
@@ -512,6 +512,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
int nr_dl_slots = n;
|
||||
int nr_ulstart_slot = 0;
|
||||
if (tdd) {
|
||||
nr_ulstart_slot = tdd->nrofDownlinkSlots + (tdd->nrofUplinkSymbols == 0);
|
||||
nr_dl_slots = tdd->nrofDownlinkSlots + (tdd->nrofDownlinkSymbols != 0);
|
||||
nr_ulstart_slot = tdd->nrofDownlinkSlots + (tdd->nrofUplinkSymbols == 0);
|
||||
nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
|
||||
|
||||
@@ -181,8 +181,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
|
||||
|
||||
if ((slot == 0) && (frame & 127) == 0) {
|
||||
char stats_output[16384];
|
||||
stats_output[0] = '\0';
|
||||
char stats_output[16000] = {0};
|
||||
dump_mac_stats(RC.nrmac[module_idP], stats_output, sizeof(stats_output), true);
|
||||
LOG_I(NR_MAC, "Frame.Slot %d.%d\n%s\n", frame, slot, stats_output);
|
||||
}
|
||||
|
||||
@@ -1109,8 +1109,8 @@ int nr_srs_tpmi_estimation(const NR_PUSCH_Config_t *pusch_Config,
|
||||
void handle_nr_srs_measurements(const module_id_t module_id,
|
||||
const frame_t frame,
|
||||
const sub_frame_t slot,
|
||||
const nfapi_nr_srs_indication_pdu_t *srs_ind) {
|
||||
|
||||
const nfapi_nr_srs_indication_pdu_t *srs_ind)
|
||||
{
|
||||
LOG_D(NR_MAC, "(%d.%d) Received SRS indication for UE %04x\n", frame, slot, srs_ind->rnti);
|
||||
|
||||
#ifdef SRS_IND_DEBUG
|
||||
@@ -1125,7 +1125,12 @@ void handle_nr_srs_measurements(const module_id_t module_id,
|
||||
|
||||
NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, srs_ind->rnti);
|
||||
if (!UE) {
|
||||
LOG_W(NR_MAC, "Could not find UE %04x\n", srs_ind->rnti);
|
||||
LOG_W(NR_MAC, "Could not find UE for RNTI %04x\n", srs_ind->rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
if (srs_ind->timing_advance_offset == 0xFFFF) {
|
||||
LOG_W(NR_MAC, "Invalid timing advance offset for RNTI %04x\n", srs_ind->rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1133,39 +1138,45 @@ void handle_nr_srs_measurements(const module_id_t module_id,
|
||||
NR_mac_stats_t *stats = &UE->mac_stats;
|
||||
|
||||
switch (srs_ind->srs_usage) {
|
||||
|
||||
case NR_SRS_ResourceSet__usage_beamManagement: {
|
||||
|
||||
nfapi_nr_srs_beamforming_report_t nr_srs_beamforming_report;
|
||||
unpack_nr_srs_beamforming_report(srs_ind->report_tlv->value,
|
||||
srs_ind->report_tlv->length,
|
||||
&nr_srs_beamforming_report,
|
||||
sizeof(nfapi_nr_srs_beamforming_report_t));
|
||||
|
||||
if (nr_srs_beamforming_report.wide_band_snr == 0xFF) {
|
||||
LOG_W(NR_MAC, "Invalid wide_band_snr for RNTI %04x\n", srs_ind->rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
int wide_band_snr_dB = (nr_srs_beamforming_report.wide_band_snr >> 1) - 64;
|
||||
|
||||
#ifdef SRS_IND_DEBUG
|
||||
LOG_I(NR_MAC, "nr_srs_beamforming_report.prg_size = %i\n", nr_srs_beamforming_report.prg_size);
|
||||
LOG_I(NR_MAC, "nr_srs_beamforming_report.num_symbols = %i\n", nr_srs_beamforming_report.num_symbols);
|
||||
LOG_I(NR_MAC, "nr_srs_beamforming_report.wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report.wide_band_snr, (nr_srs_beamforming_report.wide_band_snr>>1)-64);
|
||||
LOG_I(NR_MAC, "nr_srs_beamforming_report.wide_band_snr = %i (%i dB)\n", nr_srs_beamforming_report.wide_band_snr, wide_band_snr_dB);
|
||||
LOG_I(NR_MAC, "nr_srs_beamforming_report.num_reported_symbols = %i\n", nr_srs_beamforming_report.num_reported_symbols);
|
||||
LOG_I(NR_MAC, "nr_srs_beamforming_report.prgs[0].num_prgs = %i\n", nr_srs_beamforming_report.prgs[0].num_prgs);
|
||||
for(int prg_idx = 0; prg_idx < nr_srs_beamforming_report.prgs[0].num_prgs; prg_idx++) {
|
||||
LOG_I(NR_MAC, "nr_srs_beamforming_report.prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n",
|
||||
for (int prg_idx = 0; prg_idx < nr_srs_beamforming_report.prgs[0].num_prgs; prg_idx++) {
|
||||
LOG_I(NR_MAC,
|
||||
"nr_srs_beamforming_report.prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n",
|
||||
prg_idx,
|
||||
nr_srs_beamforming_report.prgs[0].prg_list[prg_idx].rb_snr,
|
||||
(nr_srs_beamforming_report.prgs[0].prg_list[prg_idx].rb_snr>>1)-64);
|
||||
(nr_srs_beamforming_report.prgs[0].prg_list[prg_idx].rb_snr >> 1) - 64);
|
||||
}
|
||||
#endif
|
||||
|
||||
sprintf(stats->srs_stats,"UL-SNR %i dB", (nr_srs_beamforming_report.wide_band_snr>>1)-64);
|
||||
sprintf(stats->srs_stats, "UL-SNR %i dB", wide_band_snr_dB);
|
||||
|
||||
const int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold;
|
||||
uint16_t *ulprbbl = nr_mac->ulprbbl;
|
||||
|
||||
uint8_t num_rbs = nr_srs_beamforming_report.prg_size * nr_srs_beamforming_report.prgs[0].num_prgs;
|
||||
memset(ulprbbl, 0, num_rbs*sizeof(uint16_t));
|
||||
memset(ulprbbl, 0, num_rbs * sizeof(uint16_t));
|
||||
for (int rb = 0; rb < num_rbs; rb++) {
|
||||
int snr = (nr_srs_beamforming_report.prgs[0].prg_list[rb/nr_srs_beamforming_report.prg_size].rb_snr>>1)-64;
|
||||
if (snr < ul_prbblack_SNR_threshold) {
|
||||
int snr = (nr_srs_beamforming_report.prgs[0].prg_list[rb / nr_srs_beamforming_report.prg_size].rb_snr >> 1) - 64;
|
||||
if (snr < wide_band_snr_dB - ul_prbblack_SNR_threshold) {
|
||||
ulprbbl[rb] = 0x3FFF; // all symbols taken
|
||||
}
|
||||
LOG_D(NR_MAC, "ulprbbl[%3i] = 0x%x\n", rb, ulprbbl[rb]);
|
||||
@@ -1175,7 +1186,6 @@ void handle_nr_srs_measurements(const module_id_t module_id,
|
||||
}
|
||||
|
||||
case NR_SRS_ResourceSet__usage_codebook: {
|
||||
|
||||
nfapi_nr_srs_normalized_channel_iq_matrix_t nr_srs_normalized_channel_iq_matrix;
|
||||
unpack_nr_srs_normalized_channel_iq_matrix(srs_ind->report_tlv->value,
|
||||
srs_ind->report_tlv->length,
|
||||
@@ -1230,9 +1240,8 @@ void handle_nr_srs_measurements(const module_id_t module_id,
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid SRS usage\n");
|
||||
AssertFatal(1 == 0, "Invalid SRS usage\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList,
|
||||
@@ -2268,7 +2277,14 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
dci_pdu_rel15_t uldci_payload;
|
||||
memset(&uldci_payload, 0, sizeof(uldci_payload));
|
||||
|
||||
config_uldci(sib1, scc, pusch_pdu, &uldci_payload, &sched_ctrl->srs_feedback, ps->time_domain_allocation, UE->UE_sched_ctrl.tpc0, current_BWP);
|
||||
config_uldci(sib1,
|
||||
scc,
|
||||
pusch_pdu,
|
||||
&uldci_payload,
|
||||
&sched_ctrl->srs_feedback,
|
||||
ps->time_domain_allocation,
|
||||
UE->UE_sched_ctrl.tpc0,
|
||||
current_BWP);
|
||||
|
||||
fill_dci_pdu_rel15(scc,
|
||||
cg,
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
|
||||
#define MACSTATSSTRLEN 65536
|
||||
#define MACSTATSSTRLEN 16000
|
||||
|
||||
void *nrmac_stats_thread(void *arg) {
|
||||
|
||||
|
||||
@@ -1102,7 +1102,7 @@ void nr_rlc_tick(int frame, int subframe)
|
||||
}
|
||||
|
||||
/* This is a hack, to compile the gNB.
|
||||
* TODO: remove it. The solution is to cleanup cmake_targets/CMakeLists.txt
|
||||
* TODO: remove it. The solution is to cleanup CMakeLists.txt
|
||||
*/
|
||||
void rlc_tick(int a, int b)
|
||||
{
|
||||
|
||||
@@ -868,11 +868,12 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
|
||||
DRB_config->pdcp_Config->drb->integrityProtection = NULL;
|
||||
DRB_config->pdcp_Config->drb->statusReportRequired = NULL;
|
||||
DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL;
|
||||
DRB_config->pdcp_Config->drb->outOfOrderDelivery = calloc(1,sizeof(*DRB_config->pdcp_Config->drb->outOfOrderDelivery));
|
||||
*DRB_config->pdcp_Config->drb->outOfOrderDelivery = NR_PDCP_Config__drb__outOfOrderDelivery_true;
|
||||
DRB_config->pdcp_Config->moreThanOneRLC = NULL;
|
||||
|
||||
DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering));
|
||||
*DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
|
||||
*DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms20;
|
||||
DRB_config->pdcp_Config->ext1 = NULL;
|
||||
|
||||
if (rrc->security.do_drb_integrity) {
|
||||
|
||||
@@ -16,16 +16,18 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "common_lib.h"
|
||||
#include "ethernet_lib.h"
|
||||
|
||||
#include "common/utils/system.h"
|
||||
#include "ori.h"
|
||||
|
||||
#include "targets/ARCH/COMMON/common_lib.h"
|
||||
@@ -250,7 +252,6 @@ int aw2s_startstreaming(openair0_device *device) {
|
||||
|
||||
}
|
||||
ORI_Object_s *link= ORI_FindObject(ori, ORI_ObjectType_ORILink, 0, NULL);
|
||||
|
||||
if (tx0 == NULL ||
|
||||
(tx1 == NULL && openair0_cfg->tx_num_channels > 1) ||
|
||||
(tx2 == NULL && openair0_cfg->tx_num_channels > 2) ||
|
||||
@@ -335,7 +336,7 @@ int aw2s_startstreaming(openair0_device *device) {
|
||||
printf("\n\n\n========================================================\n");
|
||||
|
||||
/* Put Tx3 into service */
|
||||
result = ORI_ObjectStateModification(ori, tx1, ORI_AST_Unlocked, &RE_result);
|
||||
result = ORI_ObjectStateModification(ori, tx3, ORI_AST_Unlocked, &RE_result);
|
||||
if(result != ORI_Result_SUCCESS)
|
||||
{
|
||||
printf("ORI_ObjectStateModify failed with error: %s\n", ORI_Result_Print(result));
|
||||
@@ -402,7 +403,7 @@ int aw2s_startstreaming(openair0_device *device) {
|
||||
if (rx3) {
|
||||
printf("\n\n\n========================================================\n");
|
||||
|
||||
/* Put Rx1 into service */
|
||||
/* Put Rx3 into service */
|
||||
result = ORI_ObjectStateModification(ori, rx3, ORI_AST_Unlocked, &RE_result);
|
||||
if(result != ORI_Result_SUCCESS)
|
||||
{
|
||||
@@ -412,37 +413,8 @@ int aw2s_startstreaming(openair0_device *device) {
|
||||
}
|
||||
printf("ORI_ObjectStateModify: %s\n", ORI_Result_Print(RE_result));
|
||||
}
|
||||
/*
|
||||
while (rx0->fst != ORI_FST_Operational ||
|
||||
(openair0_cfg->rx_num_channels > 1 && rx1->fst != ORI_FST_Operational) ||
|
||||
tx0->fst != ORI_FST_Operational ||
|
||||
(openair0_cfg->tx_num_channels > 1 && tx1->fst != ORI_FST_Operational))
|
||||
{}*/
|
||||
// test RX interface
|
||||
uint64_t TS;
|
||||
char temp_rx[2048] __attribute__((aligned(32)));
|
||||
int aid,r0=0,r1=(openair0_cfg->rx_num_channels > 1) ? 0 : 1;
|
||||
int r2=(openair0_cfg->rx_num_channels > 2) ? 0 : 1;
|
||||
int r3=(openair0_cfg->rx_num_channels > 3) ? 0 : 1;
|
||||
|
||||
int i;
|
||||
int Npackets=1024000;
|
||||
for (i=0;i<Npackets;i++) {
|
||||
device->trx_read_func2(device,
|
||||
(openair0_timestamp*)&TS,
|
||||
(void*)temp_rx,
|
||||
256,
|
||||
&aid);
|
||||
if (aid == 0) r0=1;
|
||||
if (aid == 1) r1=1;
|
||||
if (aid == 2) r2=1;
|
||||
if (aid == 3) r3=1;
|
||||
}
|
||||
if (r0==1 && r1==1 && r2==1 && r3==1) printf("Streaming started, returning to OAI\n");
|
||||
else {
|
||||
printf("Didn't get anything from one antenna port after %d packets %d,%d,%d,%d\n",Npackets,r0,r1,r2,r3);
|
||||
return(-1);
|
||||
}
|
||||
device->fhstate.active=1;
|
||||
return(0);
|
||||
|
||||
}
|
||||
@@ -924,7 +896,7 @@ int aw2s_oriinit(openair0_device *device) {
|
||||
|
||||
int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params ) {
|
||||
|
||||
|
||||
printf("Initializing AW2S (%p,%p,%p)\n",aw2s_oriinit,aw2s_oricleanup,aw2s_startstreaming);
|
||||
device->thirdparty_init = aw2s_oriinit;
|
||||
device->thirdparty_cleanup = aw2s_oricleanup;
|
||||
device->thirdparty_startstreaming = aw2s_startstreaming;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <openair1/PHY/TOOLS/tools_defs.h>
|
||||
#include "record_player.h"
|
||||
#include <common/utils/threadPool/thread-pool.h>
|
||||
|
||||
/* default name of shared library implementing the radio front end */
|
||||
#define OAI_RF_LIBNAME "oai_device"
|
||||
@@ -153,6 +154,14 @@ typedef enum {
|
||||
gpsdo=2
|
||||
} clock_source_t;
|
||||
|
||||
/*! \brief Structure used for initializing UDP read threads */
|
||||
typedef struct {
|
||||
openair0_device *device;
|
||||
int thread_id;
|
||||
pthread_t pthread;
|
||||
notifiedFIFO_t *resp;
|
||||
} udp_ctx_t;
|
||||
|
||||
|
||||
/*! \brief RF frontend parameters set by application */
|
||||
typedef struct {
|
||||
@@ -178,9 +187,11 @@ typedef struct {
|
||||
int rx_num_channels;
|
||||
//! number of TX channels (=TX antennas)
|
||||
int tx_num_channels;
|
||||
//! \brief RX base addresses for mmapped_dma
|
||||
//! \brief RX base addresses for mmapped_dma or direct access
|
||||
int32_t *rxbase[4];
|
||||
//! \brief TX base addresses for mmapped_dma
|
||||
//! \brief RX buffer size for direct access
|
||||
int rxsize;
|
||||
//! \brief TX base addresses for mmapped_dma or direct access
|
||||
int32_t *txbase[4];
|
||||
//! \brief Center frequency in Hz for RX.
|
||||
//! index: [0..rx_num_channels[
|
||||
@@ -246,6 +257,10 @@ typedef struct {
|
||||
int nr_band;
|
||||
//! NR scs for raster
|
||||
int nr_scs_for_raster;
|
||||
//! Core IDs for RX FH
|
||||
int rxfh_cores[4];
|
||||
//! Core IDs for TX FH
|
||||
int txfh_cores[4];
|
||||
} openair0_config_t;
|
||||
|
||||
/*! \brief RF mapping */
|
||||
@@ -314,6 +329,19 @@ typedef struct {
|
||||
bool write_thread_exit;
|
||||
} openair0_thread_t;
|
||||
|
||||
typedef struct fhstate_s {
|
||||
openair0_timestamp TS[8];
|
||||
openair0_timestamp TS0;
|
||||
openair0_timestamp olddeltaTS[8];
|
||||
openair0_timestamp oldTS[8];
|
||||
openair0_timestamp TS_read;
|
||||
int first_read;
|
||||
uint32_t *buff[8];
|
||||
uint32_t buff_size;
|
||||
int r[8];
|
||||
int active;
|
||||
} fhstate_t;
|
||||
|
||||
/*!\brief structure holds the parameters to configure USRP devices */
|
||||
struct openair0_device_t {
|
||||
/*!tx write thread*/
|
||||
@@ -348,6 +376,24 @@ struct openair0_device_t {
|
||||
/*!brief Can be used by driver to hold internal structure*/
|
||||
void *priv;
|
||||
|
||||
/*!brief pointer to FH state, used in ECPRI split 8*/
|
||||
fhstate_t fhstate;
|
||||
|
||||
/*!brief message response for notification fifo*/
|
||||
notifiedFIFO_t *respudpTX;
|
||||
|
||||
/*!brief UDP TX thread context*/
|
||||
udp_ctx_t **utx;
|
||||
|
||||
/*!brief Used in ECPRI split 8 to indicate numerator of sampling rate ratio*/
|
||||
int sampling_rate_ratio_n;
|
||||
|
||||
/*!brief Used in ECPRI split 8 to indicate denominator of sampling rate ratio*/
|
||||
int sampling_rate_ratio_d;
|
||||
|
||||
/*!brief Used in ECPRI split 8 to indicate the TX/RX timing offset*/
|
||||
int txrx_offset;
|
||||
|
||||
/* Functions API, which are called by the application*/
|
||||
|
||||
/*! \brief Called to start the transceiver. Return 0 if OK, < 0 if error
|
||||
@@ -394,7 +440,7 @@ struct openair0_device_t {
|
||||
@param antenna_id index of the antenna if the device has multiple anteannas
|
||||
@param flags flags must be set to true if timestamp parameter needs to be applied
|
||||
*/
|
||||
int (*trx_write_func2)(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int antenna_id, int flags);
|
||||
int (*trx_write_func2)(openair0_device *device, openair0_timestamp timestamp, void **buff, int fd_ind,int nsamps, int flags,int nant);
|
||||
|
||||
/*! \brief Receive samples from hardware.
|
||||
* Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
|
||||
@@ -416,12 +462,13 @@ struct openair0_device_t {
|
||||
* was received.
|
||||
* \param device the hardware to use
|
||||
* \param[out] ptimestamp the time at which the first sample was received.
|
||||
* \param[out] buff A pointers to a buffer for received samples. The buffer must be large enough to hold the number of samples \ref nsamps.
|
||||
* \param[out] buff A pointer to a buffer[ant_id][] for received samples. The buffer[ant_id] must be large enough to hold the number of samples \ref nsamps * the number of packets.
|
||||
* \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
|
||||
* \param packet_idx offset into
|
||||
* \param antenna_id Index of antenna from which samples were received
|
||||
* \returns the number of sample read
|
||||
*/
|
||||
int (*trx_read_func2)(openair0_device *device, openair0_timestamp *ptimestamp, void *buff, int nsamps,int *antenna_id);
|
||||
int (*trx_read_func2)(openair0_device *device, openair0_timestamp *ptimestamp, uint32_t **buff, int nsamps);
|
||||
|
||||
/*! \brief print the device statistics
|
||||
* \param device the hardware to use
|
||||
@@ -470,6 +517,7 @@ struct openair0_device_t {
|
||||
/*! \brief Pointer to generic RRU private information
|
||||
*/
|
||||
|
||||
|
||||
void *thirdparty_priv;
|
||||
|
||||
/*! \brief Callback for Third-party RRU Initialization routine
|
||||
@@ -496,6 +544,9 @@ struct openair0_device_t {
|
||||
* \return a pointer to the parameter
|
||||
*/
|
||||
void *(*get_internal_parameter)(char *id);
|
||||
/* \brief timing statistics for TX fronthaul (ethernet)
|
||||
*/
|
||||
time_stats_t tx_fhaul;
|
||||
};
|
||||
|
||||
/* type of device init function, implemented in shared lib */
|
||||
|
||||
@@ -80,10 +80,11 @@ int eth_socket_init_raw(openair0_device *device) {
|
||||
perror("ETHERNET: Error opening RAW socket (control)");
|
||||
exit(0);
|
||||
}
|
||||
if ((eth->sockfdd = socket(sock_dom, sock_type, sock_proto)) == -1) {
|
||||
perror("ETHERNET: Error opening RAW socket (user)");
|
||||
exit(0);
|
||||
}
|
||||
for (int i=0;i<eth->num_fd;i++)
|
||||
if ((eth->sockfdd[i] = socket(sock_dom, sock_type, sock_proto)) == -1) {
|
||||
perror("ETHERNET: Error opening RAW socket (user)");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* initialize destination address */
|
||||
bzero((void *)&(eth->local_addrc_ll), sizeof(struct sockaddr_ll));
|
||||
@@ -94,8 +95,9 @@ int eth_socket_init_raw(openair0_device *device) {
|
||||
strcpy(eth->if_index.ifr_name,eth->if_name);
|
||||
if (ioctl(eth->sockfdc, SIOCGIFINDEX, &(eth->if_index)) < 0)
|
||||
perror("SIOCGIFINDEX");
|
||||
if (ioctl(eth->sockfdd, SIOCGIFINDEX, &(eth->if_index)) < 0)
|
||||
perror("SIOCGIFINDEX");
|
||||
for (int i=0;i<eth->num_fd;i++)
|
||||
if (ioctl(eth->sockfdd[i], SIOCGIFINDEX, &(eth->if_index)) < 0)
|
||||
perror("SIOCGIFINDEX");
|
||||
|
||||
eth->local_addrc_ll.sll_family = AF_PACKET;
|
||||
eth->local_addrc_ll.sll_ifindex = eth->if_index.ifr_ifindex;
|
||||
@@ -111,10 +113,11 @@ int eth_socket_init_raw(openair0_device *device) {
|
||||
eth->local_addrd_ll.sll_pkttype = PACKET_OTHERHOST;
|
||||
eth->addr_len = sizeof(struct sockaddr_ll);
|
||||
|
||||
if (bind(eth->sockfdd,(struct sockaddr *)ð->local_addrd_ll,eth->addr_len)<0) {
|
||||
perror("ETHERNET: Cannot bind to socket (user)");
|
||||
exit(0);
|
||||
}
|
||||
for (int i=0;i<eth->num_fd;i++)
|
||||
if (bind(eth->sockfdd[i],(struct sockaddr *)ð->local_addrd_ll,eth->addr_len)<0) {
|
||||
perror("ETHERNET: Cannot bind to socket (user)");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Construct the Ethernet header */
|
||||
ether_aton_r(local_mac, (struct ether_addr *)(&(eth->ehd.ether_shost)));
|
||||
@@ -165,7 +168,7 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi
|
||||
|
||||
/* Send packet */
|
||||
|
||||
bytes_sent += send(eth->sockfdd,
|
||||
bytes_sent += send(eth->sockfdd[cc % eth->num_fd],
|
||||
buff2,
|
||||
pktsize,
|
||||
sendto_flag);
|
||||
@@ -214,7 +217,7 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam
|
||||
memcpy(buff[0], (void*)ð->ehd, MAC_HEADER_SIZE_BYTES);
|
||||
|
||||
|
||||
bytes_sent = send(eth->sockfdd,
|
||||
bytes_sent = send(eth->sockfdd[cc % eth->num_fd],
|
||||
buff[0],
|
||||
packet_size,
|
||||
0);
|
||||
@@ -266,7 +269,7 @@ int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, voi
|
||||
|
||||
while(bytes_received < receive_bytes) {
|
||||
again:
|
||||
ret = recv(eth->sockfdd,
|
||||
ret = recv(eth->sockfdd[cc % eth->num_fd],
|
||||
buff2,
|
||||
receive_bytes,
|
||||
rcvfrom_flag);
|
||||
@@ -345,7 +348,7 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam
|
||||
|
||||
while (bytes_received < packet_size) {
|
||||
again:
|
||||
ret = recv(eth->sockfdd,
|
||||
ret = recv(eth->sockfdd[cc % eth->num_fd],
|
||||
buff[0],
|
||||
packet_size,
|
||||
MSG_PEEK);
|
||||
@@ -397,7 +400,7 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam
|
||||
}
|
||||
|
||||
while(bytes_received < packet_size) {
|
||||
ret = recv(eth->sockfdd,
|
||||
ret = recv(eth->sockfdd[cc % eth->num_fd],
|
||||
buff[0],
|
||||
packet_size,
|
||||
0);
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
// _GNU_SOURCE needed to have sched_getcpu() from sched.h
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <stdio.h>
|
||||
@@ -37,14 +40,17 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/filter.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include <sched.h>
|
||||
|
||||
#include "common_lib.h"
|
||||
#include "ethernet_lib.h"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
@@ -101,10 +107,11 @@ int eth_socket_init_udp(openair0_device *device) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ((eth->sockfdd = socket(sock_dom, sock_type, sock_proto)) == -1) {
|
||||
perror("ETHERNET: Error opening socket (user)");
|
||||
exit(0);
|
||||
}
|
||||
for (int i = 0;i<eth->num_fd;i++)
|
||||
if ((eth->sockfdd[i] = socket(sock_dom, sock_type, sock_proto)) == -1) {
|
||||
printf("ETHERNET: Error opening socket (user %d)",i);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* initialize addresses */
|
||||
bzero((void *)&(eth->dest_addrc), sizeof(eth->dest_addrc));
|
||||
@@ -141,9 +148,31 @@ int eth_socket_init_udp(openair0_device *device) {
|
||||
perror("ETHERNET: Cannot set SO_REUSEADDR option on socket (control)");
|
||||
exit(0);
|
||||
}
|
||||
if (setsockopt(eth->sockfdd, SOL_SOCKET, SO_NO_CHECK, &enable, sizeof(int))) {
|
||||
perror("ETHERNET: Cannot set SO_NO_CHECK option on socket (user)");
|
||||
exit(0);
|
||||
for (int i=0;i<eth->num_fd;i++) {
|
||||
if (setsockopt(eth->sockfdd[i], SOL_SOCKET, SO_NO_CHECK, &enable, sizeof(int))) {
|
||||
printf("ETHERNET: Cannot set SO_NO_CHECK option on socket (user %d)",i);
|
||||
exit(0);
|
||||
}
|
||||
#if 0 /*def SO_ATTACH_REUSEPORT_EBPF*/
|
||||
if (setsockopt(eth->sockfdd[i], SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int))) {
|
||||
printf("ETHERNET: Cannot set SO_REUSEPORT option on socket (user %d)",i);
|
||||
exit(0);
|
||||
}
|
||||
struct sock_filter code[]={
|
||||
{ BPF_LD | BPF_W | BPF_ABS, 0, 0, SKF_AD_OFF + SKF_AD_CPU }, // A = #cpu
|
||||
{ BPF_RET | BPF_A, 0, 0, 0 }, // return A
|
||||
};
|
||||
struct sock_fprog bpf = {
|
||||
.len = sizeof(code)/sizeof(struct sock_filter),
|
||||
.filter = code,
|
||||
};
|
||||
if (i==0 && setsockopt(eth->sockfdd[i], SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &bpf, sizeof(bpf))) {
|
||||
printf("ETHERNET: Cannot set SO_ATTACH_REUSEPORT_EBPF option on socket (user %d)",i);
|
||||
exit(0);
|
||||
}
|
||||
else printf("ETHERNET: set SO_ATTACH_REUSEPORT_EBPF option on socket (user %d)\n",i);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* want to receive -> so bind */
|
||||
@@ -153,12 +182,13 @@ int eth_socket_init_udp(openair0_device *device) {
|
||||
} else {
|
||||
printf("[%s] binding to %s:%d (control)\n",str[hostind],str_local,ntohs(eth->local_addrc.sin_port));
|
||||
}
|
||||
if (bind(eth->sockfdd,(struct sockaddr *)ð->local_addrd,eth->addr_len)<0) {
|
||||
perror("ETHERNET: Cannot bind to socket (user)");
|
||||
exit(0);
|
||||
} else {
|
||||
printf("[%s] binding to %s:%d (user)\n",str[hostind],str_local,ntohs(eth->local_addrd.sin_port));
|
||||
}
|
||||
for (int i=0;i<eth->num_fd;i++)
|
||||
if (bind(eth->sockfdd[i],(struct sockaddr *)ð->local_addrd,eth->addr_len)<0) {
|
||||
printf("ETHERNET: Cannot bind to socket (user %d)",i);
|
||||
exit(0);
|
||||
} else {
|
||||
printf("[%s] binding to %s:%d (user %d)\n",str[hostind],str_local,ntohs(eth->local_addrd.sin_port),i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -180,7 +210,7 @@ int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestam
|
||||
|
||||
while(bytes_received == -1) {
|
||||
again:
|
||||
bytes_received = recvfrom(eth->sockfdd,
|
||||
bytes_received = recvfrom(eth->sockfdd[0/*cc%eth->num_fd*/],
|
||||
buff[0],
|
||||
packet_size,
|
||||
0,
|
||||
@@ -211,7 +241,6 @@ int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestam
|
||||
eth->rx_count++;
|
||||
}
|
||||
}
|
||||
|
||||
eth->rx_nsamps = nsamps;
|
||||
return(bytes_received);
|
||||
}
|
||||
@@ -246,7 +275,7 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam
|
||||
|
||||
eth->tx_nsamps = nblocks;
|
||||
|
||||
bytes_sent = sendto(eth->sockfdd,
|
||||
bytes_sent = sendto(eth->sockfdd[0/*cc%eth->num_fd*/],
|
||||
buff[0],
|
||||
packet_size,
|
||||
0,
|
||||
@@ -264,233 +293,234 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam
|
||||
return (bytes_sent);
|
||||
}
|
||||
|
||||
int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int cc, int flags) {
|
||||
|
||||
|
||||
|
||||
void *trx_eth_write_udp_cmd(udpTXelem_t *udpTXelem) {
|
||||
|
||||
openair0_device *device=udpTXelem->device;
|
||||
openair0_timestamp timestamp = udpTXelem->timestamp;
|
||||
void **buff = udpTXelem->buff;
|
||||
int nsamps = udpTXelem->nsamps;
|
||||
int nant = udpTXelem->nant;
|
||||
int bytes_sent=0;
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
int sendto_flag =0;
|
||||
fhstate_t *fhstate = &device->fhstate;
|
||||
|
||||
//sendto_flag|=flags;
|
||||
eth->tx_nsamps=nsamps;
|
||||
|
||||
|
||||
uint64_t last_rxTS = fhstate->TS[0]-fhstate->TS0;
|
||||
uint64_t TS_advance=0;
|
||||
if (timestamp > last_rxTS) TS_advance = timestamp - last_rxTS;
|
||||
|
||||
|
||||
int nsamps2; // aligned to upper 32 or 16 byte boundary
|
||||
|
||||
if (TS_advance < (nsamps/2)) LOG_W(PHY,"Starting TX FH for TS %llu absslot %llu(%llu) last_rxTS %llu TS_advance %llu samples\n",(unsigned long long)timestamp,(unsigned long long)timestamp/nsamps,((unsigned long long)timestamp/nsamps)%20,(unsigned long long)last_rxTS,(unsigned long long)TS_advance);
|
||||
void *buff2;
|
||||
#if defined(__x86_64) || defined(__i386__)
|
||||
#ifdef __AVX2__
|
||||
nsamps2 = (nsamps+7)>>3;
|
||||
int nsamps2 = 256>>3;
|
||||
__m256i buff_tx[nsamps2+1];
|
||||
__m256i *buff_tx2=buff_tx+1;
|
||||
buff2=(void*)&buff_tx[1] - APP_HEADER_SIZE_BYTES;
|
||||
#else
|
||||
nsamps2 = (nsamps+3)>>2;
|
||||
int nsamps2 = 256>>2;
|
||||
__m128i buff_tx[nsamps2+2];
|
||||
__m128i *buff_tx2=buff_tx+2;
|
||||
buff2=(void*)&buff_tx[2] - APP_HEADER_SIZE_BYTES;
|
||||
#endif
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
nsamps2 = (nsamps+3)>>2;
|
||||
int nsamps2 = 256>>2;
|
||||
int16x8_t buff_tx[nsamps2+2];
|
||||
int16x8_t *buff_tx2=buff_tx+2;
|
||||
buff2=(void*)&buff_tx[2] - APP_HEADER_SIZE_BYTES;
|
||||
#else
|
||||
#error Unsupported CPU architecture, ethernet device cannot be built
|
||||
#endif
|
||||
|
||||
|
||||
// bring TX data into 12 LSBs for softmodem RX
|
||||
for (int j=0; j<nsamps2; j++) {
|
||||
/* construct application header */
|
||||
// ECPRI Protocol revision + reserved bits (1 byte)
|
||||
*(uint8_t *)buff2 = ECPRIREV;
|
||||
// ECPRI Message type (1 byte)
|
||||
*(uint8_t *)(buff2 + 1) = 64;
|
||||
|
||||
openair0_timestamp TS = timestamp + fhstate->TS0;
|
||||
TS = (6*device->sampling_rate_ratio_d*TS)/device->sampling_rate_ratio_n;
|
||||
TS -= device->txrx_offset;
|
||||
int TSinc = (6*256*device->sampling_rate_ratio_d)/device->sampling_rate_ratio_n;
|
||||
int len=256;
|
||||
LOG_D(PHY,"TS %llu (%llu),txrx_offset %d,d %d, n %d, buff[0] %p buff[1] %p\n",
|
||||
(unsigned long long)TS,(unsigned long long)timestamp,device->txrx_offset,device->sampling_rate_ratio_d,device->sampling_rate_ratio_n,
|
||||
buff[0],buff[1]);
|
||||
for (int offset=0;offset<nsamps;offset+=256,TS+=TSinc) {
|
||||
// OAI modified SEQ_ID (4 bytes)
|
||||
*(uint64_t *)(buff2 + 6) = TS;
|
||||
if ((offset + 256) <= nsamps) len=1024;
|
||||
else len = (nsamps-offset)<<2;
|
||||
// ECPRI Payload Size (2 bytes)
|
||||
*(uint8_t *)(buff2 + 2) = len>>8;
|
||||
*(uint8_t *)(buff2 + 3) = len&0xff;
|
||||
for (int aid = 0; aid<nant; aid++) {
|
||||
LOG_D(PHY,"TS %llu (TS0 %llu) aa %d : offset %d, len %d\n",(unsigned long long)TS,(unsigned long long)fhstate->TS0,aid,offset,len);
|
||||
// ECPRI PC_ID (2 bytes)
|
||||
*(uint16_t *)(buff2 + 4) = aid;
|
||||
// bring TX data into 12 MSBs
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
#ifdef __AVX2__
|
||||
buff_tx2[j] = _mm256_slli_epi16(((__m256i *)buff)[j],4);
|
||||
__m256i *buff256 = (__m256i *)&(((int32_t*)buff[aid])[offset]);
|
||||
for (int j=0; j<32; j+=8) {
|
||||
buff_tx[1+j] = _mm256_slli_epi16(buff256[j],4);
|
||||
buff_tx[2+j] = _mm256_slli_epi16(buff256[j+1],4);
|
||||
buff_tx[3+j] = _mm256_slli_epi16(buff256[j+2],4);
|
||||
buff_tx[4+j] = _mm256_slli_epi16(buff256[j+3],4);
|
||||
buff_tx[5+j] = _mm256_slli_epi16(buff256[j+4],4);
|
||||
buff_tx[6+j] = _mm256_slli_epi16(buff256[j+5],4);
|
||||
buff_tx[7+j] = _mm256_slli_epi16(buff256[j+6],4);
|
||||
buff_tx[8+j] = _mm256_slli_epi16(buff256[j+7],4);
|
||||
}
|
||||
#else
|
||||
buff_tx2[j] = _mm_slli_epi16(((__m128i *)buff)[j],4);
|
||||
__m128i *buff128 = (__m128i *)&buff[aid][offset];
|
||||
for (int j=0; j<64; j++) buff_tx[2+j] = _mm_slli_epi16(buff128[j],4);
|
||||
#endif
|
||||
#elif defined(__arm__)
|
||||
buff_tx2[j] = vshlq_n_s16(((int16x8_t *)buff)[j],4);
|
||||
int16x8_t *buff128 = (__int16x8_t*)&buff[aid][offset];
|
||||
for (int j=0; j<64; j++) buff_tx[2+j] = vshlq_n_s16(((int16x8_t *)buff128)[j],4);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* buff[i] points to the position in tx buffer where the payload to be sent is
|
||||
buff2 points to the position in tx buffer where the packet header will be placed */
|
||||
void *buff2 = ((void*)buff_tx2)- APP_HEADER_SIZE_BYTES;
|
||||
|
||||
|
||||
|
||||
bytes_sent = 0;
|
||||
|
||||
/* constract application header */
|
||||
// ECPRI Protocol revision + reserved bits (1 byte)
|
||||
*(uint8_t *)buff2 = ECPRIREV;
|
||||
// ECPRI Message type (1 byte)
|
||||
*(uint8_t *)(buff2 + 1) = 64;
|
||||
// ECPRI Payload Size (2 bytes)
|
||||
AssertFatal(nsamps<16381,"nsamps > 16381\n");
|
||||
*(uint8_t *)(buff2 + 2) = (nsamps<<2)>>8;
|
||||
*(uint8_t *)(buff2 + 3) = (nsamps<<2)&0xff;
|
||||
// ECPRI PC_ID (2 bytes)
|
||||
*(uint16_t *)(buff2 + 4) = cc;
|
||||
// OAI modified SEQ_ID (4 bytes)
|
||||
*(uint64_t *)(buff2 + 6) = ((uint64_t )timestamp)*6;
|
||||
|
||||
/*
|
||||
printf("ECPRI TX (REV %x, MessType %d, Payload size %d, PC_ID %d, TS %llu\n",
|
||||
*(uint8_t *)buff2,
|
||||
*(uint8_t *)(buff2+1),
|
||||
*(uint16_t *)(buff2+2),
|
||||
*(uint16_t *)(buff2+4),
|
||||
*(uint64_t *)(buff2+6));
|
||||
*/
|
||||
|
||||
int sent_byte;
|
||||
if (eth->compression == ALAW_COMPRESS) {
|
||||
sent_byte = UDP_PACKET_SIZE_BYTES_ALAW(nsamps);
|
||||
} else {
|
||||
sent_byte = UDP_PACKET_SIZE_BYTES(nsamps);
|
||||
}
|
||||
|
||||
//while(bytes_sent < sent_byte) {
|
||||
//printf("eth->pck_seq_num: %d\n", eth->pck_seq_num);
|
||||
#if DEBUG
|
||||
printf("------- TX ------: buff2 current position=%d remaining_bytes=%d bytes_sent=%d \n",
|
||||
(void *)(buff2+bytes_sent),
|
||||
sent_byte - bytes_sent,
|
||||
bytes_sent);
|
||||
#endif
|
||||
/* Send packet */
|
||||
bytes_sent = sendto(eth->sockfdd,
|
||||
buff2,
|
||||
sent_byte,
|
||||
sendto_flag,
|
||||
(struct sockaddr*)ð->dest_addrd,
|
||||
eth->addr_len);
|
||||
|
||||
/* Send packet */
|
||||
bytes_sent = sendto(eth->sockfdd[0],
|
||||
buff2,
|
||||
UDP_PACKET_SIZE_BYTES(len>>2),
|
||||
sendto_flag,
|
||||
(struct sockaddr*)ð->dest_addrd,
|
||||
eth->addr_len);
|
||||
if ( bytes_sent == -1) {
|
||||
eth->num_tx_errors++;
|
||||
eth->num_tx_errors++;
|
||||
perror("ETHERNET WRITE: ");
|
||||
exit(-1);
|
||||
} else {
|
||||
#if DEBUG
|
||||
printf("------- TX ------: nu=%d an_id=%d ts%d bytes_send=%d\n",
|
||||
*(int16_t *)buff2,
|
||||
*(int16_t *)(buff2 + sizeof(int16_t)),
|
||||
*(openair0_timestamp *)(buff2 + sizeof(int32_t)),
|
||||
bytes_sent);
|
||||
|
||||
dump_packet((device->host_type == RAU_HOST)? "RAU":"RAU", buff2, UDP_PACKET_SIZE_BYTES(nsamps), TX_FLAG);
|
||||
#endif
|
||||
eth->tx_actual_nsamps=bytes_sent>>2;
|
||||
eth->tx_count++;
|
||||
eth->pck_seq_num++;
|
||||
if ( eth->pck_seq_num > MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame) ) eth->pck_seq_num = 1;
|
||||
eth->tx_actual_nsamps=bytes_sent>>2;
|
||||
eth->tx_count++;
|
||||
}
|
||||
//}
|
||||
|
||||
return (bytes_sent-APP_HEADER_SIZE_BYTES)>>2;
|
||||
} // aid
|
||||
} // offset
|
||||
free(buff);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
#define NOSHIFT 1
|
||||
int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int fd_ind, int nsamps, int flags, int nant) {
|
||||
|
||||
int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void *buff, int nsamps, int *cc) {
|
||||
|
||||
int bytes_received=0;
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
// openair0_timestamp prev_timestamp = -1;
|
||||
int rcvfrom_flag =0;
|
||||
int block_cnt=0;
|
||||
int again_cnt=0;
|
||||
static int packet_cnt=0;
|
||||
int payload_size = UDP_PACKET_SIZE_BYTES(nsamps);
|
||||
union udpTXReqUnion id = {.s={(uint64_t)timestamp,nsamps,0}};
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(udpTXelem_t), id.p, device->utx[fd_ind]->resp,NULL);
|
||||
udpTXelem_t * udptxelem=(udpTXelem_t *) NotifiedFifoData(req);
|
||||
udptxelem->device = device;
|
||||
udptxelem->timestamp = timestamp;
|
||||
udptxelem->buff = calloc(nant,sizeof(void*));
|
||||
memcpy(udptxelem->buff,buff,nant*sizeof(void*));
|
||||
udptxelem->fd_ind = fd_ind;
|
||||
udptxelem->nsamps = nsamps;
|
||||
udptxelem->flags = flags;
|
||||
udptxelem->nant = nant;
|
||||
pushNotifiedFIFO(device->utx[fd_ind]->resp, req);
|
||||
LOG_D(PHY,"Pushed to TX FH FIFO, TS %llu, nsamps %d, nant %d buffs[0] %p buffs[1] %p\n",
|
||||
(unsigned long long)timestamp,nsamps,nant,udptxelem->buff[0],udptxelem->buff[1]);
|
||||
return(0);
|
||||
}
|
||||
extern int oai_exit;
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
#ifdef __AVX2__
|
||||
int nsamps2 = (payload_size>>5)+1;
|
||||
__m256i temp_rx[nsamps2];
|
||||
char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES;
|
||||
#else
|
||||
int nsamps2 = (payload_size>>4)+1;
|
||||
__m128i temp_rx[nsamps2];
|
||||
char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES;
|
||||
#endif
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
int nsamps2 = (payload_size>>4)+1;
|
||||
int16x8_t temp_rx[nsamps2];
|
||||
char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES;
|
||||
#else
|
||||
#error Unsupported CPU architecture device cannot be built
|
||||
int nsamps2 = (payload_size>>2)+1;
|
||||
int32_t temp_rx[payload_size>>2];
|
||||
char* *temp_rx0 = ((char *)&temp_rx[1]) - APP_HEADER_SIZE_BYTES;
|
||||
#endif
|
||||
|
||||
eth->rx_nsamps=nsamps;
|
||||
void *udp_write_thread(void *arg) {
|
||||
|
||||
bytes_received=0;
|
||||
block_cnt=0;
|
||||
AssertFatal(eth->compression == NO_COMPRESS, "IF5 compression not supported for now\n");
|
||||
|
||||
while(bytes_received < payload_size) {
|
||||
again:
|
||||
bytes_received +=recvfrom(eth->sockfdd,
|
||||
temp_rx0,
|
||||
payload_size,
|
||||
rcvfrom_flag,
|
||||
(struct sockaddr *)ð->dest_addrd,
|
||||
(socklen_t *)ð->addr_len);
|
||||
packet_cnt++;
|
||||
if (bytes_received ==-1) {
|
||||
eth->num_rx_errors++;
|
||||
if (errno == EAGAIN) {
|
||||
again_cnt++;
|
||||
usleep(10);
|
||||
if (again_cnt == 1000) {
|
||||
perror("ETHERNET READ: ");
|
||||
exit(-1);
|
||||
} else {
|
||||
bytes_received=0;
|
||||
goto again;
|
||||
}
|
||||
} else if (errno == EWOULDBLOCK) {
|
||||
block_cnt++;
|
||||
usleep(10);
|
||||
if (block_cnt == 1000) {
|
||||
perror("ETHERNET READ: ");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n");
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
udp_ctx_t *utx = (udp_ctx_t *)arg;
|
||||
utx->resp = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_elt_t));
|
||||
initNotifiedFIFO(utx->resp);
|
||||
LOG_D(PHY,"UDP write thread started on core %d\n",sched_getcpu());
|
||||
reset_meas(&utx->device->tx_fhaul);
|
||||
while (oai_exit == 0) {
|
||||
notifiedFIFO_elt_t *res = pullNotifiedFIFO(utx->resp);
|
||||
udpTXelem_t *udptxelem = (udpTXelem_t *)NotifiedFifoData(res);
|
||||
LOG_D(PHY,"Pulled from TX FH FIFO, TS %llu, nsamps %d, nant %d\n",(unsigned long long)udptxelem->timestamp,udptxelem->nsamps,udptxelem->nant);
|
||||
start_meas(&utx->device->tx_fhaul);
|
||||
trx_eth_write_udp_cmd(udptxelem);
|
||||
stop_meas(&utx->device->tx_fhaul);
|
||||
// send data to RU
|
||||
delNotifiedFIFO_elt(res);
|
||||
}
|
||||
free(utx->resp);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void *udp_read_thread(void *arg) {
|
||||
openair0_timestamp TS;
|
||||
|
||||
int aid;
|
||||
udp_ctx_t *u = (udp_ctx_t *)arg;
|
||||
openair0_device *device=u->device;
|
||||
fhstate_t *fhstate = &device->fhstate;
|
||||
char buffer[UDP_PACKET_SIZE_BYTES(256)];
|
||||
int first_read=0;
|
||||
while (oai_exit == 0) {
|
||||
LOG_I(PHY,"UDP read thread %d, waiting for start sampling_rate_d %d, sampling_rate_n %d\n",u->thread_id,device->sampling_rate_ratio_n,device->sampling_rate_ratio_d);
|
||||
while (fhstate->active > 0) {
|
||||
size_t count = recvfrom(((eth_state_t*)device->priv)->sockfdd[0],
|
||||
buffer,sizeof(buffer),0,
|
||||
(struct sockaddr *)&((eth_state_t*)device->priv)->dest_addrd,
|
||||
(socklen_t *)&((eth_state_t*)device->priv)->addr_len);
|
||||
aid = *(uint16_t*)(&buffer[ECPRICOMMON_BYTES]);
|
||||
TS = *(openair0_timestamp *)(&buffer[ECPRICOMMON_BYTES+ECPRIPCID_BYTES]);
|
||||
// convert TS to samples, /6 for AW2S @ 30.72 Ms/s, this is converted for other sample rates in OAI application
|
||||
TS = (device->sampling_rate_ratio_n*TS)/(device->sampling_rate_ratio_d*6);
|
||||
if ((int)count <= 0) continue;
|
||||
AssertFatal(aid < 8,"Cannot handle more than 8 antennas, got aid %d\n",aid);
|
||||
fhstate->r[aid]=1;
|
||||
if (aid==0 && first_read == 0) fhstate->TS0 = TS;
|
||||
first_read = 1;
|
||||
/* store the timestamp value from packet's header */
|
||||
*timestamp = *(openair0_timestamp *)(temp_rx0 + ECPRICOMMON_BYTES+ECPRIPCID_BYTES);
|
||||
// convert TS to samples, /3 for 30.72 Ms/s, /6 for 15.36 Ms/s, /12 for 7.68 Ms/s, etc.
|
||||
*timestamp = *timestamp/6;
|
||||
// handle 1.4,3,5,10,15 MHz cases
|
||||
*cc = *(uint16_t*)(temp_rx0 + ECPRICOMMON_BYTES);
|
||||
}
|
||||
eth->rx_actual_nsamps=payload_size>>2;
|
||||
eth->rx_count++;
|
||||
}
|
||||
fhstate->TS[aid] = TS;
|
||||
int64_t offset = TS - fhstate->TS0;
|
||||
if (offset > 0) offset = offset % device->openair0_cfg->rxsize;
|
||||
else offset = TS % device->openair0_cfg->rxsize + ((((uint64_t)1)<<63)-(fhstate->TS0-1)) % device->openair0_cfg->rxsize;
|
||||
// need to do memcpy since there is no guarantee that aid is the same each time, otherwise we could have used
|
||||
// zero-copy and corrected the header component.
|
||||
|
||||
#ifdef NOSHIFT
|
||||
memcpy(buff,(void*)(temp_rx+1),payload_size);
|
||||
#else
|
||||
// populate receive buffer in lower 12-bits from 16-bit representation
|
||||
for (int j=1; j<nsamps2; j++) {
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
#ifdef __AVX2__
|
||||
((__m256i *)buff)[j-1] = _mm256_srai_epi16(temp_rx[j],2);
|
||||
#else
|
||||
((__m128i *)buff)[j-1] = _mm_srai_epi16(temp_rx[j],2);
|
||||
#endif
|
||||
#elif defined(__arm__)
|
||||
((int16x8_t *)buff)[j] = vshrq_n_s16(temp_rx[i][j],2);
|
||||
#endif
|
||||
memcpy((void*)(device->openair0_cfg->rxbase[aid]+offset),
|
||||
(void*)&buffer[APP_HEADER_SIZE_BYTES],
|
||||
count-APP_HEADER_SIZE_BYTES);
|
||||
LOG_D(PHY,"UDP read thread_id %d (%d), aid %d, TS %llu, TS0 %llu, offset %ld\n",(int)u->thread_id,(int)sched_getcpu(),aid,(unsigned long long)TS,(unsigned long long)fhstate->TS0,offset);
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, uint32_t **buff, int nsamps) {
|
||||
|
||||
return (payload_size>>2);
|
||||
fhstate_t *fhstate = &device->fhstate;
|
||||
openair0_timestamp prev_read_TS= fhstate->TS_read, min_TS;
|
||||
// block until FH is ready
|
||||
while (fhstate->r[0] == 0 || fhstate->r[1] == 0 || fhstate->r[2] == 0 || fhstate->r[3] == 0 ||
|
||||
fhstate->r[4] == 0 || fhstate->r[5] == 0 || fhstate->r[6] == 0 || fhstate->r[7] == 0) usleep(100);
|
||||
|
||||
// get minimum TS over all antennas
|
||||
min_TS = fhstate->TS[0];
|
||||
for (int i=1;i<device->openair0_cfg->rx_num_channels;i++) min_TS = min(min_TS,fhstate->TS[i]);
|
||||
// poll/sleep until we accumulated enough samples on each antenna port
|
||||
int count=0;
|
||||
while (fhstate->first_read == 1 && min_TS < (fhstate->TS0+prev_read_TS + nsamps)) {
|
||||
usleep(50);
|
||||
min_TS = fhstate->TS[0];
|
||||
for (int i=1;i<device->openair0_cfg->rx_num_channels;i++) min_TS = min(min_TS,fhstate->TS[i]);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (fhstate->first_read == 0) {
|
||||
*timestamp = 0;
|
||||
fhstate->TS_read = *timestamp+nsamps;
|
||||
LOG_D(PHY,"first read : TS_read %llu, TS %llu state (%d,%d,%d,%d,%d,%d,%d,%d)\n",(unsigned long long)fhstate->TS_read,(unsigned long long)*timestamp,
|
||||
fhstate->r[0],fhstate->r[1],fhstate->r[2],fhstate->r[3],fhstate->r[4],fhstate->r[5],fhstate->r[6],fhstate->r[7]);
|
||||
}
|
||||
else {
|
||||
*timestamp = fhstate->TS_read;
|
||||
fhstate->TS_read = prev_read_TS + nsamps;
|
||||
LOG_D(PHY,"TS_read %llu (%llu, %llu), min_TS %llu, prev_read_TS %llu, nsamps %d, fhstate->TS0+prev_TS+nsamps %llu, wait count %d x 100us\n",(unsigned long long)fhstate->TS_read,(unsigned long long)*timestamp/nsamps,((unsigned long long)*timestamp/nsamps)%20,(unsigned long long)min_TS,(unsigned long long)prev_read_TS,nsamps,(unsigned long long)(fhstate->TS0+prev_read_TS+nsamps),count);
|
||||
}
|
||||
fhstate->first_read = 1;
|
||||
return (nsamps);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# Ethernet drivers
|
||||
|
||||
This directory contains ethernet-based drivers for fronthaul. The only functional versions today are ECPRI time-domain (split 8) over UDP for AW2S and IF4.5 (split 7) for OAI RU over UDP. The RAW ethernet implementation is currently not tested and quite possibly obsolete.
|
||||
|
||||
|
||||
## license
|
||||
Author:
|
||||
Raymond Knopp, EURECOM
|
||||
OAI License V1.1
|
||||
# Top-level
|
||||
|
||||
The files implement the OAI IF device interface which provides the transmit/receive (trx) functions for generic ethernet-based devices. Some minimal control-plane socket handling for IF4p5 is also provided. It comprises the following top-level functions (ethernet_lib.c) which are mapped to the OAI device structure:
|
||||
|
||||
* trx_eth_start : create sockets and threads to handle I/O
|
||||
* trx_eth_end : close sockets
|
||||
* trx_eth_stop : stops 3rd party (AW2S) device
|
||||
* trx_eth_set_freq : empty
|
||||
* trx_eth_set_gains : empty
|
||||
* trx_eth_get_stats : empty
|
||||
* trx_eth_reset_stats : empty
|
||||
* trx_eth_write_init : empty
|
||||
* ethernet_tune : write certain performance-related parameters to ethernet device
|
||||
* transport_init : entry routine to fill device data structure with function pointers
|
||||
|
||||
|
||||
# IF4p5 U-plane implementation
|
||||
|
||||
It is contained in the eth_udp.c and eth_raw.c files. The two basic routines are
|
||||
|
||||
* trx_eth_read_udp_IF4p5() : implements a blocking read for three particular IF4p5 packets, IF4p5_PULFFT (for OAI RCC/DU), IF4p5_PRACH and IF4p5_PDLFFT (for OAI RU). The packets are parsed and mapped to the appropriate physical channels by the OAI physical layer
|
||||
* trx_eth_write_udp_IF4p5 : implements a write for the three IF4p5 packets.
|
||||
|
||||
* trx_eth_ctlsend_udp : implements the sending component for the control socket
|
||||
|
||||
* trx_eth_ctlrecv_udp : implements the receive component for the control socket (blocking read)
|
||||
|
||||
# ECPRI U-plane implementation
|
||||
|
||||
It is contained in the eth_udp.c file and only implements ECPRI/UDP. The implementation has 2 top-level functions:
|
||||
|
||||
* trx_eth_write_udp : This sends a stream of packets containing 16-bit I/ 16-bit Q samples to the ECPRI RU. It uses the proprietary AW2S format (user-defined). Each packet carries 256 samples and some header information (timestamp, antenna index) and fits inslightly more than 1024 bytes. Each packet with Ethernet, IP and UDP headers fits into a regular Ethernet frame. The transmit function does not block and pushes the data to a worker thread (udp_write_thread) which runs in the background. The worker thread scales the IQ samples to fit in 16-bit units and forms the ECPRI packets for each antenna. The signals are split into 256-sample chunks and antennas are handled in sequence for each chunk. This ensures that all antennas receive their signals more or less at the same time.
|
||||
|
||||
* trx_eth_read_udp : This is a blocking read which waits for a worker thread (udp_read_thread) listening on the U-plane socket to have acquired enough samples satisfying the request (nsamps). The requests are usually a slot (NR) or subframe (LTE) worth of samples. The worker thread identifies the antenna index (aid) and timestamp of each packet and copies the received chunk into the destination memory location according to the timestamp modulo the length of the receive buffer. The memory location for read is identifited during initialization of the interface and is written circularly. Typically the buffer would contain a frame's worth of samples, but this is not a requirement. There is only one memcpy in the driver and the end OAI application can use the data in its normal local buffer (RU.common.rxdata[aid]). The memcpy is needed since the destination address depends on the antenna index which is carried in the received packet itself. Kernel filtering and redirection (C/EBPF,XDP) doesn't seem to be possible with the AW2S packet format.
|
||||
|
||||
The two threads should be pinned to isolated CPUs to maximize performance. Their CPU id's can be passed to the driver from the OAI application. tx_fh_core and rx_fh_core in the RU section of the OAI .conf file.
|
||||
|
||||
# Obsolete code
|
||||
|
||||
Non ECPRI split 8 and IF4p5 with RAW sockets is not functional anymore (eth_raw.c). split-8 will be resusitated if an RU implementing ECPRI is integrated with OAI. IF4p5 with raw sockets is replaced with the FHI Split 7.2 interface.
|
||||
|
||||
|
||||
@@ -64,8 +64,78 @@ int trx_eth_start(openair0_device *device)
|
||||
AssertFatal(device->thirdparty_init != NULL, "device->thirdparty_init is null\n");
|
||||
AssertFatal(device->thirdparty_init(device) == 0, "third-party init failed\n");
|
||||
device->openair0_cfg->samples_per_packet = 256;
|
||||
}
|
||||
/* initialize socket */
|
||||
eth->num_fd = 1; //max(device->openair0_cfg->rx_num_channels,device->openair0_cfg->tx_num_channels);
|
||||
udp_ctx_t *u[1+eth->num_fd];
|
||||
device->utx = (udp_ctx_t**)malloc(sizeof(device->utx));
|
||||
for (int i=0;i<eth->num_fd;i++) {
|
||||
u[i] = malloc(sizeof(udp_ctx_t));
|
||||
u[i]->thread_id=i;
|
||||
u[i]->device = device;
|
||||
printf("UDP Read Thread %d on core %d\n",i,device->openair0_cfg->rxfh_cores[i]);
|
||||
threadCreate(&u[i]->pthread,udp_read_thread,u[i],"udp read thread",device->openair0_cfg->rxfh_cores[i],OAI_PRIORITY_RT_MAX);
|
||||
device->utx[i] = malloc(sizeof(udp_ctx_t));
|
||||
device->utx[i]->thread_id=i;
|
||||
device->utx[i]->device = device;
|
||||
printf("UDP Write Thread %d on core %d\n",i,device->openair0_cfg->txfh_cores[i]);
|
||||
threadCreate(&device->utx[i]->pthread,udp_write_thread,device->utx[i],"udp write thread",device->openair0_cfg->txfh_cores[i],OAI_PRIORITY_RT_MAX);
|
||||
}
|
||||
device->sampling_rate_ratio_n=1;
|
||||
device->sampling_rate_ratio_d=1;
|
||||
if (device->openair0_cfg->nr_flag==1) { // This check if RRU knows about NR numerologies
|
||||
if (device->openair0_cfg->num_rb_dl <= 162 && device->openair0_cfg->num_rb_dl > 106) {
|
||||
device->sampling_rate_ratio_n = 2;
|
||||
device->txrx_offset=5500;
|
||||
}
|
||||
else if (device->openair0_cfg->num_rb_dl <= 106 && device->openair0_cfg->num_rb_dl > 51) {
|
||||
device->sampling_rate_ratio_d=3;
|
||||
device->sampling_rate_ratio_n=4;
|
||||
device->txrx_offset=3750;
|
||||
}
|
||||
else if (device->openair0_cfg->num_rb_dl == 51) {
|
||||
device->sampling_rate_ratio_n=1;
|
||||
device->sampling_rate_ratio_d=1;
|
||||
device->txrx_offset=7500;
|
||||
}
|
||||
else AssertFatal(1==0,"num_rb_dl %d not ok with ECPRI\n",device->openair0_cfg->num_rb_dl);
|
||||
}
|
||||
else {
|
||||
if (device->openair0_cfg->num_rb_dl == 100 || device->openair0_cfg->num_rb_dl == 51) {
|
||||
device->sampling_rate_ratio_d = 1;
|
||||
device->txrx_offset=7500;
|
||||
}
|
||||
else if (device->openair0_cfg->num_rb_dl == 75) {
|
||||
device->sampling_rate_ratio_d = 4;
|
||||
device->sampling_rate_ratio_n=3;
|
||||
device->txrx_offset=7500;
|
||||
}
|
||||
else if (device->openair0_cfg->num_rb_dl == 50) {
|
||||
device->sampling_rate_ratio_d = 2;
|
||||
device->txrx_offset=7500;
|
||||
}
|
||||
else if (device->openair0_cfg->num_rb_dl == 25) {
|
||||
device->sampling_rate_ratio_d = 4;
|
||||
device->txrx_offset=7500;
|
||||
}
|
||||
else AssertFatal(1==0,"num_rb_dl %d not ok with ECPRI\n",device->openair0_cfg->num_rb_dl);
|
||||
}
|
||||
#ifdef USE_TX_TPOOL
|
||||
int threadCnt = device->openair0_cfg->tx_num_channels;
|
||||
if (threadCnt < 2) LOG_E(PHY,"Number of threads for gNB should be more than 1. Allocated only %d\n",threadCnt);
|
||||
char pool[80];
|
||||
sprintf(pool,"-1");
|
||||
int s_offset = 0;
|
||||
for (int icpu=1; icpu<threadCnt; icpu++) {
|
||||
sprintf(pool+2+s_offset,",-1");
|
||||
s_offset += 3;
|
||||
}
|
||||
device->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
|
||||
initTpool(pool, device->threadPool, cpumeas(CPUMEAS_GETSTATE));
|
||||
// ULSCH decoder result FIFO
|
||||
device->respudpTX = (notifiedFIFO_elt_t*) malloc(sizeof(notifiedFIFO_elt_t));
|
||||
initNotifiedFIFO(device->respudpTX);
|
||||
#endif
|
||||
}
|
||||
/* initialize socket */
|
||||
if (eth->flags == ETH_RAW_MODE) {
|
||||
printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n");
|
||||
if (eth_socket_init_raw(device)!=0) return -1;
|
||||
@@ -145,10 +215,11 @@ int trx_eth_start(openair0_device *device)
|
||||
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
|
||||
}
|
||||
/* apply additional configuration */
|
||||
if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0) return -1;
|
||||
if(ethernet_tune (device, RCV_BUF_SIZE,2000000000)!=0) return -1;
|
||||
if(ethernet_tune (device, KERNEL_SND_BUF_MAX_SIZE, 200000000)!=0) return -1;
|
||||
if(ethernet_tune (device, KERNEL_RCV_BUF_MAX_SIZE, 200000000)!=0) return -1;
|
||||
if(ethernet_tune (device, SND_BUF_SIZE,67108864)!=0) return -1;
|
||||
if(ethernet_tune (device, RCV_BUF_SIZE,67108864)!=0) return -1;
|
||||
if(ethernet_tune (device, KERNEL_SND_BUF_MAX_SIZE, 67108864)!=0) return -1;
|
||||
if(ethernet_tune (device, KERNEL_RCV_BUF_MAX_SIZE, 67108864)!=0) return -1;
|
||||
if(ethernet_tune (device, TX_Q_LEN, 10000)!=0) return -1;
|
||||
|
||||
|
||||
return 0;
|
||||
@@ -159,12 +230,13 @@ void trx_eth_end(openair0_device *device)
|
||||
{
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
/* destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */
|
||||
if ( close(eth->sockfdd) <0 ) {
|
||||
perror("ETHERNET: Failed to close socket");
|
||||
exit(0);
|
||||
} else {
|
||||
printf("[%s] socket has been successfully closed.\n",(device->host_type == RAU_HOST)? "RAU":"RRU");
|
||||
}
|
||||
for (int i=0;i<eth->num_fd;i++)
|
||||
if ( close(eth->sockfdd[i]) <0 ) {
|
||||
perror("ETHERNET: Failed to close socket");
|
||||
exit(0);
|
||||
} else {
|
||||
printf("[%s] socket has been successfully closed.\n",(device->host_type == RAU_HOST)? "RAU":"RRU");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -224,7 +296,8 @@ int ethernet_tune(openair0_device *device,
|
||||
/****************** socket level options ************************/
|
||||
switch(option) {
|
||||
case SND_BUF_SIZE: /* transmit socket buffer size */
|
||||
if (setsockopt(eth->sockfdd,
|
||||
for (int i=0;i<eth->num_fd;i++)
|
||||
if (setsockopt(eth->sockfdd[i],
|
||||
SOL_SOCKET,
|
||||
SO_SNDBUF,
|
||||
&value,sizeof(value))) {
|
||||
@@ -232,10 +305,11 @@ int ethernet_tune(openair0_device *device,
|
||||
} else {
|
||||
printf("send buffer size= %d bytes\n",value);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case RCV_BUF_SIZE: /* receive socket buffer size */
|
||||
if (setsockopt(eth->sockfdd,
|
||||
for (int i=0;i<eth->num_fd;i++) {
|
||||
if (setsockopt(eth->sockfdd[i],
|
||||
SOL_SOCKET,
|
||||
SO_RCVBUF,
|
||||
&value,sizeof(value))) {
|
||||
@@ -243,26 +317,29 @@ int ethernet_tune(openair0_device *device,
|
||||
} else {
|
||||
printf("receive bufffer size= %d bytes\n",value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RCV_TIMEOUT:
|
||||
timeout.tv_sec = value/1000000;
|
||||
timeout.tv_usec = value%1000000;//less than rt_period?
|
||||
if (setsockopt(eth->sockfdc,
|
||||
SOL_SOCKET,
|
||||
SO_RCVTIMEO,
|
||||
(char *)&timeout,sizeof(timeout))) {
|
||||
perror("[ETHERNET] setsockopt()");
|
||||
SOL_SOCKET,
|
||||
SO_RCVTIMEO,
|
||||
(char *)&timeout,sizeof(timeout))) {
|
||||
perror("[ETHERNET] setsockopt()");
|
||||
} else {
|
||||
printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec);
|
||||
printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec);
|
||||
}
|
||||
if (setsockopt(eth->sockfdd,
|
||||
SOL_SOCKET,
|
||||
SO_RCVTIMEO,
|
||||
(char *)&timeout,sizeof(timeout))) {
|
||||
perror("[ETHERNET] setsockopt()");
|
||||
} else {
|
||||
printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec);
|
||||
for (int i=0;i<eth->num_fd;i++) {
|
||||
if (setsockopt(eth->sockfdd[i],
|
||||
SOL_SOCKET,
|
||||
SO_RCVTIMEO,
|
||||
(char *)&timeout,sizeof(timeout))) {
|
||||
perror("[ETHERNET] setsockopt()");
|
||||
} else {
|
||||
printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -277,13 +354,15 @@ int ethernet_tune(openair0_device *device,
|
||||
} else {
|
||||
printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec);
|
||||
}
|
||||
if (setsockopt(eth->sockfdd,
|
||||
SOL_SOCKET,
|
||||
SO_SNDTIMEO,
|
||||
(char *)&timeout,sizeof(timeout))) {
|
||||
perror("[ETHERNET] setsockopt()");
|
||||
} else {
|
||||
printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec);
|
||||
for (int i=0;i<eth->num_fd;i++) {
|
||||
if (setsockopt(eth->sockfdd[i],
|
||||
SOL_SOCKET,
|
||||
SO_SNDTIMEO,
|
||||
(char *)&timeout,sizeof(timeout))) {
|
||||
perror("[ETHERNET] setsockopt()");
|
||||
} else {
|
||||
printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -293,20 +372,24 @@ int ethernet_tune(openair0_device *device,
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)-1);
|
||||
ifr.ifr_mtu =value;
|
||||
if (ioctl(eth->sockfdd,SIOCSIFMTU,(caddr_t)&ifr) < 0 )
|
||||
perror ("[ETHERNET] Can't set the MTU");
|
||||
else
|
||||
printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name,ifr.ifr_mtu);
|
||||
for (int i=0;i<eth->num_fd;i++) {
|
||||
if (ioctl(eth->sockfdd[i],SIOCSIFMTU,(caddr_t)&ifr) < 0 )
|
||||
perror ("[ETHERNET] Can't set the MTU");
|
||||
else
|
||||
printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name,ifr.ifr_mtu);
|
||||
}
|
||||
break;
|
||||
|
||||
case TX_Q_LEN: /* change TX queue length of eth interface */
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)-1);
|
||||
ifr.ifr_qlen =value;
|
||||
if (ioctl(eth->sockfdd,SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 )
|
||||
perror ("[ETHERNET] Can't set the txqueuelen");
|
||||
else
|
||||
printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name,ifr.ifr_qlen);
|
||||
for (int i=0;i<eth->num_fd;i++) {
|
||||
if (ioctl(eth->sockfdd[i],SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 )
|
||||
perror ("[ETHERNET] Can't set the txqueuelen");
|
||||
else
|
||||
printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name,ifr.ifr_qlen);
|
||||
}
|
||||
break;
|
||||
|
||||
/******************* device level options *************************/
|
||||
@@ -357,7 +440,7 @@ int ethernet_tune(openair0_device *device,
|
||||
}
|
||||
break;
|
||||
case KERNEL_RCV_BUF_MAX_SIZE:
|
||||
ret=snprintf(system_cmd,sizeof(system_cmd),"sysctl -w net.core.rmem_max=%d",value);
|
||||
ret=snprintf(system_cmd,sizeof(system_cmd),"sysctl -w net.core.rmem_max=%d;sysctl -w net.core.rmem_default=%d",value,value);
|
||||
if (ret > 0) {
|
||||
ret=system(system_cmd);
|
||||
if (ret == -1) {
|
||||
@@ -371,7 +454,7 @@ int ethernet_tune(openair0_device *device,
|
||||
}
|
||||
break;
|
||||
case KERNEL_SND_BUF_MAX_SIZE:
|
||||
ret=snprintf(system_cmd,sizeof(system_cmd),"sysctl -w net.core.wmem_max=%d",value);
|
||||
ret=snprintf(system_cmd,sizeof(system_cmd),"sysctl -w net.core.wmem_max=%d;sysctl -w net.core.wmem_default=%d;sysctl -w net.core.netdev_max_backlog=5000;sysctl -w net.core.optmem_max=524288;",value,value);
|
||||
if (ret > 0) {
|
||||
ret=system(system_cmd);
|
||||
if (ret == -1) {
|
||||
@@ -413,7 +496,10 @@ int transport_init(openair0_device *device,
|
||||
eth->compression = ALAW_COMPRESS;
|
||||
}
|
||||
|
||||
eth->num_fd = 1;
|
||||
|
||||
printf("[ETHERNET]: Initializing openair0_device for %s ...\n", ((device->host_type == RAU_HOST) ? "RAU": "RRU"));
|
||||
printf("[ETHERNET]: num_fd %d\n",eth->num_fd);
|
||||
device->Mod_id = 0;//num_devices_eth++;
|
||||
device->transp_type = ETHERNET_TP;
|
||||
device->trx_start_func = trx_eth_start;
|
||||
@@ -438,6 +524,9 @@ int transport_init(openair0_device *device,
|
||||
device->trx_read_func2 = trx_eth_read_udp;
|
||||
device->trx_ctlsend_func = trx_eth_ctlsend_udp;
|
||||
device->trx_ctlrecv_func = trx_eth_ctlrecv_udp;
|
||||
memset((void*)&device->fhstate,0,sizeof(device->fhstate));
|
||||
printf("Setting %d RX channels to waiting\n",openair0_cfg->rx_num_channels);
|
||||
for (int i=openair0_cfg->rx_num_channels;i<8;i++) device->fhstate.r[i] = 1;
|
||||
} else if (eth->flags == ETH_RAW_IF4p5_MODE) {
|
||||
device->trx_write_func = trx_eth_write_raw_IF4p5;
|
||||
device->trx_read_func = trx_eth_read_raw_IF4p5;
|
||||
@@ -454,6 +543,7 @@ int transport_init(openair0_device *device,
|
||||
eth->if_name = eth_params->local_if_name;
|
||||
device->priv = eth;
|
||||
|
||||
|
||||
/* device specific */
|
||||
// openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
|
||||
// openair0_cfg[0].iq_txshift = eth_params->iq_txshift;// shift
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <common/utils/threadPool/thread-pool.h>
|
||||
|
||||
#define MAX_INST 4
|
||||
#define DEFAULT_IF "lo"
|
||||
@@ -59,12 +60,16 @@ typedef struct {
|
||||
|
||||
/*!\brief socket file desc (control)*/
|
||||
int sockfdc;
|
||||
/*!\brief number of sockets for user-plane*/
|
||||
int num_fd;
|
||||
/*!\brief socket file desc (user)*/
|
||||
int sockfdd;
|
||||
int sockfdd[8];
|
||||
/*!\brief interface name */
|
||||
char *if_name;
|
||||
/*!\brief buffer size */
|
||||
unsigned int buffer_size;
|
||||
/*!\brief Fronthaul state */
|
||||
fhstate_t *fhstate;
|
||||
/*!\brief destination address (control) for UDP socket*/
|
||||
struct sockaddr_in dest_addrc;
|
||||
/*!\brief local address (control) for UDP socket*/
|
||||
@@ -205,6 +210,28 @@ typedef struct {
|
||||
short q;
|
||||
} iqoai_t ;
|
||||
|
||||
typedef struct udpTXelem_s {
|
||||
openair0_device *device;
|
||||
openair0_timestamp timestamp;
|
||||
void **buff;
|
||||
int fd_ind;
|
||||
int nant;
|
||||
int nsamps;
|
||||
int flags;
|
||||
} udpTXelem_t;
|
||||
|
||||
struct udpTXReqId {
|
||||
uint64_t TS;
|
||||
int aid;
|
||||
int length;
|
||||
uint16_t spare;
|
||||
} __attribute__((packed));
|
||||
|
||||
union udpTXReqUnion {
|
||||
struct udpTXReqId s;
|
||||
uint64_t p;
|
||||
};
|
||||
|
||||
void dump_packet(char *title, unsigned char* pkt, int bytes, unsigned int tx_rx_flag);
|
||||
unsigned short calc_csum (unsigned short *buf, int nwords);
|
||||
void dump_dev(openair0_device *device);
|
||||
@@ -214,7 +241,8 @@ void inline dump_txcounters(openair0_device *device);
|
||||
*/
|
||||
void dump_iqs(char * buff, int iq_cnt);
|
||||
|
||||
|
||||
void *udp_read_thread(void *arg);
|
||||
void *udp_write_thread(void *arg);
|
||||
|
||||
/*! \fn int ethernet_tune (openair0_device *device, unsigned int option, int value);
|
||||
* \brief this function allows you to configure certain ethernet parameters in socket or device level
|
||||
@@ -237,8 +265,8 @@ int ethernet_tune(openair0_device *device, unsigned int option, int value);
|
||||
* @ingroup _oai
|
||||
*/
|
||||
int eth_socket_init_udp(openair0_device *device);
|
||||
int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int cc, int flags);
|
||||
int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void *buff, int nsamps, int *cc);
|
||||
int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buf, int fd_ind, int nsamps, int flags,int nant);
|
||||
int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, uint32_t **buff, int nsamps);
|
||||
|
||||
|
||||
int eth_socket_init_raw(openair0_device *device);
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
|
||||
#ifndef LITE_COMPILATION
|
||||
#include "PHY/LTE_TRANSPORT/if4_tools.h"
|
||||
#include "PHY/LTE_TRANSPORT/if5_tools.h"
|
||||
#endif
|
||||
|
||||
// ETH transport preference modes
|
||||
|
||||
@@ -7,7 +7,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_CU_ID = 0xe00;
|
||||
gNB_ID = 0xe00;
|
||||
|
||||
# cell_type = "CELL_MACRO_GNB";
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ gNBs = (
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 0;
|
||||
do_SRS = 1;
|
||||
ul_prbblacklist = "135,136,137,138"
|
||||
|
||||
pdcch_ConfigSIB1 = ({
|
||||
|
||||
@@ -17,7 +17,7 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
pdsch_AntennaPorts_N1 = 2;
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 1;
|
||||
@@ -254,7 +254,6 @@ MACRLCs = (
|
||||
tr_n_preference = "local_RRC";
|
||||
#pusch_TargetSNRx10 = 150;
|
||||
#pucch_TargetSNRx10 = 200;
|
||||
ul_prbblack_SNR_threshold = 10;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -251,7 +251,6 @@ MACRLCs = (
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 150;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
ul_prbblack_SNR_threshold = 10;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
}
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user